merge release/calc-18_season-graphs
This commit is contained in:
parent
bfd6f1d1f9
commit
ed80a94791
@ -96,7 +96,7 @@ const sections: ISection[] = [
|
||||
'radioGraphType',
|
||||
'selectSeasonType',
|
||||
'tbxParmentsDecreasePercent',
|
||||
// 'selectHighSeasonStart',
|
||||
'selectHighSeasonStart',
|
||||
],
|
||||
layout: {
|
||||
newLine: true,
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import elementsTitles, { tablesTitles } from 'client/Containers/Calculation/lib/elements/titles';
|
||||
import { TableNames } from 'core/types/Calculation/Store/tables';
|
||||
import elementsTitles, {
|
||||
tablesTitles,
|
||||
} from 'client/Containers/Calculation/lib/elements/titles';
|
||||
import CalculationStore from 'client/stores/CalculationStore';
|
||||
import { toJS } from 'mobx';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
export default () => {
|
||||
let invalidElements: string[] = [];
|
||||
@ -14,9 +18,11 @@ export default () => {
|
||||
|
||||
let invalidTables: string[] = [];
|
||||
const { tables: storeTables } = CalculationStore;
|
||||
const tables = toJS(storeTables);
|
||||
const tables = omit(toJS(storeTables), tablesExclusion);
|
||||
Object.keys(tables).forEach(tableName => {
|
||||
if (
|
||||
!tables[tableName].rows ||
|
||||
tables[tableName].rows.length === 0 ||
|
||||
tables[tableName].rows.some(row =>
|
||||
Object.keys(row).some(propName => row[propName].validation === false),
|
||||
)
|
||||
@ -27,3 +33,5 @@ export default () => {
|
||||
|
||||
return { invalidElements, invalidTables };
|
||||
};
|
||||
|
||||
const tablesExclusion: TableNames[] = ['tableResults'];
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
import { elementsValues } from 'client/Containers/Calculation/lib/elements/values';
|
||||
import { shiftRight } from 'core/tools/array';
|
||||
import { TElements } from 'core/types/Calculation/Store/elements';
|
||||
import { isEqual } from 'lodash';
|
||||
import CalculationStore from '../../..';
|
||||
import valuesConstants from 'core/constants/values';
|
||||
const { PERIODS_NUMBER } = valuesConstants;
|
||||
|
||||
const VALIDATIONS = {
|
||||
IS_NULL: valueName =>
|
||||
@ -27,6 +31,12 @@ const elementsValidations: TElements<any> = {
|
||||
selectRegistration: VALIDATIONS.IS_NULL,
|
||||
selectLeaseObjectCategory: VALIDATIONS.IS_NULL,
|
||||
tbxLeasingPeriod: valueName => CalculationStore.getValue(valueName) < 7,
|
||||
selectSeasonType: valueName =>
|
||||
CalculationStore.getValue('graphType') === 100000003 &&
|
||||
VALIDATIONS.IS_NULL(valueName),
|
||||
selectHighSeasonStart: valueName =>
|
||||
CalculationStore.getValue('graphType') === 100000003 &&
|
||||
VALIDATIONS.IS_NULL(valueName),
|
||||
tbxLeaseObjectPrice: VALIDATIONS.LESS_OR_EQUALS_ZERO,
|
||||
tbxLastPaymentPerc: VALIDATIONS.IS_NULL,
|
||||
tbxLastPaymentRub: VALIDATIONS.IS_NULL,
|
||||
@ -35,7 +45,7 @@ const elementsValidations: TElements<any> = {
|
||||
tbxLeaseObjectCount: VALIDATIONS.LESS_OR_EQUALS_ZERO,
|
||||
selectQuote: valueName =>
|
||||
CalculationStore.getValue('recalcWithRevision') === true &&
|
||||
!CalculationStore.getValue(valueName),
|
||||
VALIDATIONS.IS_NULL(valueName),
|
||||
};
|
||||
|
||||
const validateElement = (elementName, condition) => {
|
||||
@ -91,16 +101,15 @@ const validateInsuranceTable = () => {
|
||||
|
||||
const validatePaymentsTable = () => {
|
||||
const { graphType } = CalculationStore.values;
|
||||
const payments = CalculationStore.tables.tablePayments.rows;
|
||||
const payments = CalculationStore.tables.tablePayments.rows.map(
|
||||
x => x.paymentRelation?.value,
|
||||
);
|
||||
|
||||
switch (graphType) {
|
||||
case 100000001: {
|
||||
{
|
||||
const areMiddleRowsEqual =
|
||||
new Set(
|
||||
payments
|
||||
.slice(1, payments.length - 1)
|
||||
.map(x => x.paymentRelation?.value),
|
||||
).size === 1;
|
||||
new Set(payments.slice(1, payments.length - 1)).size === 1;
|
||||
|
||||
CalculationStore.setTableRows(
|
||||
'tablePayments',
|
||||
@ -119,9 +128,7 @@ const validatePaymentsTable = () => {
|
||||
x => x.paymentRelation?.validation === false,
|
||||
)
|
||||
) {
|
||||
const target_payments = payments
|
||||
.slice(1, 4)
|
||||
.map(x => x.paymentRelation?.value);
|
||||
const target_payments = payments.slice(1, 4);
|
||||
const min = Math.min.apply(Math, target_payments);
|
||||
const max = Math.max.apply(Math, target_payments);
|
||||
const areInvalidRows = max - min > 10;
|
||||
@ -143,9 +150,7 @@ const validatePaymentsTable = () => {
|
||||
x => x.paymentRelation?.validation === false,
|
||||
)
|
||||
) {
|
||||
const target_payments = payments
|
||||
.slice(1, payments.length - 1)
|
||||
.map(x => x.paymentRelation?.value);
|
||||
const target_payments = payments.slice(1, payments.length - 1);
|
||||
let pairs_number = 0;
|
||||
new Set(target_payments).forEach(set_v => {
|
||||
let setValueCount = 0;
|
||||
@ -173,10 +178,57 @@ const validatePaymentsTable = () => {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 100000003: {
|
||||
const { highSeasonStart: highSeasonStartId } = CalculationStore.values;
|
||||
if (!highSeasonStartId) {
|
||||
return;
|
||||
}
|
||||
const highSeasonStart = parseInt(
|
||||
CalculationStore.options.selectHighSeasonStart?.find(
|
||||
x => x.value === highSeasonStartId,
|
||||
)?.name || '2',
|
||||
);
|
||||
const shiftNumber = highSeasonStart - 2;
|
||||
const middleRows = payments.slice(1, PERIODS_NUMBER + 1);
|
||||
const unshiftedMiddleRows = shiftRight(middleRows, shiftNumber);
|
||||
|
||||
const { seasonType } = CalculationStore.values;
|
||||
if (!seasonType) {
|
||||
return;
|
||||
}
|
||||
const seasonTypeOptions = CalculationStore.options.selectSeasonType?.find(
|
||||
x => x.value === seasonType,
|
||||
);
|
||||
const startPositions =
|
||||
seasonTypeOptions && seasonTypeOptions.startPositions;
|
||||
|
||||
let stepsValues = [];
|
||||
for (let i = 0; i < startPositions.length; i++) {
|
||||
const targetIndex = startPositions[i];
|
||||
//@ts-ignore
|
||||
stepsValues.push(unshiftedMiddleRows[targetIndex]);
|
||||
}
|
||||
|
||||
const areCorrectSeasonPayments = isEqual(
|
||||
stepsValues,
|
||||
[...stepsValues].sort((a, b) => b - a),
|
||||
);
|
||||
CalculationStore.setTableRows(
|
||||
'tablePayments',
|
||||
1,
|
||||
)(
|
||||
Array.from({ length: PERIODS_NUMBER }, () => ({
|
||||
paymentRelation: {
|
||||
validation: areCorrectSeasonPayments,
|
||||
},
|
||||
})),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case 100000004: {
|
||||
const areMiddleRowsEqual =
|
||||
new Set(payments.slice(1, 4).map(x => x.paymentRelation?.value))
|
||||
.size === 1;
|
||||
const areMiddleRowsEqual = new Set(payments.slice(1, 4)).size === 1;
|
||||
|
||||
CalculationStore.setTableRows(
|
||||
'tablePayments',
|
||||
|
||||
@ -735,6 +735,8 @@ const reactionEffects: IReactionEffect[] = [
|
||||
effect: graphType => {
|
||||
if (graphType) {
|
||||
calculationStore.setValue('seasonType', null);
|
||||
calculationStore.setValue('highSeasonStart', null);
|
||||
calculationStore.setValue('parmentsDecreasePercent', 50);
|
||||
switch (graphType) {
|
||||
case 100000001: {
|
||||
calculationStore.setStatus(
|
||||
|
||||
@ -5,6 +5,8 @@ import { Process } from 'core/types/Calculation/Store/process';
|
||||
import { ITableCell, TableProps } from 'core/types/Calculation/Store/tables';
|
||||
import { ElementStatus } from 'core/types/statuses';
|
||||
import { toJS } from 'mobx';
|
||||
import valuesConstants from 'core/constants/values';
|
||||
const { PERIODS_NUMBER } = valuesConstants;
|
||||
|
||||
export default [
|
||||
(calculationStore, calculationProcess) => ({
|
||||
@ -516,19 +518,20 @@ export default [
|
||||
const targetSeasonType = calculationStore.options?.selectSeasonType?.find(
|
||||
x => x?.value === seasonType,
|
||||
);
|
||||
const steps: number[] = targetSeasonType && targetSeasonType.steps;
|
||||
const stepsValues: number[] =
|
||||
targetSeasonType && targetSeasonType.stepsValues;
|
||||
|
||||
const middleRows = Array.from(
|
||||
{ length: leasingPeriod - 2 },
|
||||
(_v, i) => {
|
||||
let value = steps[2];
|
||||
let value = stepsValues[2];
|
||||
|
||||
if (i <= paymentsInStep * 2 - 1) {
|
||||
value = steps[1];
|
||||
value = stepsValues[1];
|
||||
}
|
||||
|
||||
if (i <= paymentsInStep - 1) {
|
||||
value = steps[0];
|
||||
value = stepsValues[0];
|
||||
}
|
||||
|
||||
return {
|
||||
@ -540,7 +543,6 @@ export default [
|
||||
},
|
||||
);
|
||||
payments = [...payments, ...middleRows];
|
||||
|
||||
} else {
|
||||
const middleRows = Array.from(
|
||||
{ length: leasingPeriod - 3 },
|
||||
@ -602,59 +604,56 @@ export default [
|
||||
}
|
||||
|
||||
case 100000003: {
|
||||
let HIGH = 100,
|
||||
MIDDLE = 75,
|
||||
LOW = 50;
|
||||
if (!seasonType) {
|
||||
return;
|
||||
}
|
||||
|
||||
const next_seasonType_option = calculationStore.options.selectSeasonType?.find(
|
||||
x => x.value === seasonType,
|
||||
);
|
||||
|
||||
const {
|
||||
//@ts-ignore
|
||||
startPositions: nextStartPositions,
|
||||
//@ts-ignore
|
||||
paymentsInStep: nextPaymentsInStep,
|
||||
//@ts-ignore
|
||||
stepsValues: nextStepsValues,
|
||||
} = next_seasonType_option;
|
||||
|
||||
let stepsValues: number[] = nextStepsValues;
|
||||
|
||||
const {
|
||||
seasonType: prevSeasonType,
|
||||
highSeasonStart: prevHighSeasonStart,
|
||||
} = prevParams;
|
||||
if (
|
||||
prevParams.graphType === nextParams.graphType
|
||||
// && nextParams.graphType === 100000003
|
||||
prevParams.graphType === nextParams.graphType &&
|
||||
prevSeasonType === seasonType &&
|
||||
prevHighSeasonStart !== highSeasonStart
|
||||
) {
|
||||
/**
|
||||
* FIND PREV HIGH, MIDDLE, LOW
|
||||
*/
|
||||
const {
|
||||
leasingPeriod: prevLeasingPeriod,
|
||||
seasonType: prevSeasonType,
|
||||
highSeasonStart: prevHighSeasonStart,
|
||||
} = prevParams;
|
||||
|
||||
const prevPeriodsNumber =
|
||||
prevLeasingPeriod <= 14 ? prevLeasingPeriod - 2 : 12;
|
||||
//TODO: change 2 to variable from options selectHighSeasonStart
|
||||
const prevShiftNumber = prevHighSeasonStart - 2;
|
||||
|
||||
let middleRows = prevValues.slice(1, prevPeriodsNumber + 1);
|
||||
if (middleRows.length < 12) {
|
||||
middleRows = [
|
||||
...middleRows,
|
||||
...Array.from({ length: 12 - middleRows.length }, v => 0),
|
||||
];
|
||||
}
|
||||
let middleRows = prevValues.slice(1, PERIODS_NUMBER + 1);
|
||||
|
||||
// prevent unnecessary running shiftRight
|
||||
if (prevShiftNumber > 0)
|
||||
middleRows = shiftRight(middleRows, prevShiftNumber);
|
||||
|
||||
switch (prevSeasonType) {
|
||||
// 6/6
|
||||
case 100000000: {
|
||||
HIGH = middleRows[0];
|
||||
LOW = middleRows[6];
|
||||
break;
|
||||
}
|
||||
// 8/4
|
||||
case 100000001: {
|
||||
HIGH = middleRows[0];
|
||||
LOW = middleRows[8];
|
||||
const prev_seasonType_option = calculationStore.options.selectSeasonType?.find(
|
||||
x => x.value === prevSeasonType,
|
||||
);
|
||||
const prevStartPositions =
|
||||
prev_seasonType_option && prev_seasonType_option.startPositions;
|
||||
|
||||
break;
|
||||
}
|
||||
// 4/4/4
|
||||
case 100000002: {
|
||||
HIGH = middleRows[0];
|
||||
MIDDLE = middleRows[4];
|
||||
LOW = middleRows[8];
|
||||
break;
|
||||
}
|
||||
}
|
||||
stepsValues = prevStartPositions.map(
|
||||
startPosition => middleRows[startPosition],
|
||||
);
|
||||
/** */
|
||||
}
|
||||
|
||||
@ -662,58 +661,36 @@ export default [
|
||||
* GENERATE PERIODS
|
||||
*/
|
||||
|
||||
const {
|
||||
leasingPeriod: nextLeasingPeriod,
|
||||
seasonType: nextSeasonType,
|
||||
highSeasonStart: nextHighSeasonStart,
|
||||
} = nextParams;
|
||||
|
||||
const nextPeriodsNumber =
|
||||
nextLeasingPeriod <= 14 ? nextLeasingPeriod - 2 : 12;
|
||||
const nextShiftNumber = nextHighSeasonStart - 2;
|
||||
const nextShiftNumber = highSeasonStart - 2;
|
||||
|
||||
let nextPeriods: number[] = [];
|
||||
|
||||
switch (nextSeasonType) {
|
||||
// 6/6
|
||||
case 100000000: {
|
||||
nextPeriods = Array.from({ length: 12 }, (v, i) =>
|
||||
i < 6 ? HIGH : LOW,
|
||||
);
|
||||
break;
|
||||
nextStartPositions.forEach((startPosition, i) => {
|
||||
for (
|
||||
let j = startPosition;
|
||||
j < startPosition + nextPaymentsInStep[i];
|
||||
j++
|
||||
) {
|
||||
nextPeriods[j] = stepsValues[i];
|
||||
}
|
||||
// 8/4
|
||||
case 100000001: {
|
||||
nextPeriods = Array.from({ length: 12 }, (v, i) =>
|
||||
i < 8 ? HIGH : LOW,
|
||||
);
|
||||
break;
|
||||
}
|
||||
// 4/4/4
|
||||
case 100000002: {
|
||||
nextPeriods = Array.from(
|
||||
{ length: 12 },
|
||||
(v, i) => (i < 4 && HIGH) || (i < 8 && MIDDLE) || LOW,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (nextShiftNumber > 0) {
|
||||
nextPeriods = shift(nextPeriods, nextShiftNumber);
|
||||
}
|
||||
nextPeriods.length = nextPeriodsNumber;
|
||||
nextPeriods.length = PERIODS_NUMBER;
|
||||
|
||||
const middleRows = Array.from(
|
||||
{ length: nextLeasingPeriod - 2 },
|
||||
{ length: leasingPeriod - 2 },
|
||||
(v, i) => {
|
||||
return {
|
||||
paymentRelation: {
|
||||
value:
|
||||
nextPeriods[
|
||||
i - nextPeriodsNumber * Math.floor(i / nextPeriodsNumber)
|
||||
],
|
||||
i < PERIODS_NUMBER &&
|
||||
// i - PERIODS_NUMBER * Math.floor(i / PERIODS_NUMBER)
|
||||
nextPeriods[i],
|
||||
status:
|
||||
i < nextPeriodsNumber
|
||||
i < PERIODS_NUMBER
|
||||
? ElementStatus.Default
|
||||
: ElementStatus.Disabled,
|
||||
},
|
||||
@ -767,6 +744,7 @@ export default [
|
||||
calculationStore.setTableRows(
|
||||
'tablePayments',
|
||||
0,
|
||||
true,
|
||||
)([
|
||||
...payments,
|
||||
{
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import { TElementFilter } from 'core/types/Calculation/Store/filters';
|
||||
import { TElements } from 'core/types/Calculation/Store/elements';
|
||||
|
||||
const initialFilters: TElements<TElementFilter> = {
|
||||
radioGraphType: options => options.filter(x => x.value !== 100000003),
|
||||
};
|
||||
const initialFilters: TElements<TElementFilter> = {};
|
||||
|
||||
export default initialFilters;
|
||||
|
||||
@ -85,34 +85,43 @@ const initialOptions: TElements<IBaseOption[]> = {
|
||||
{
|
||||
name: '6/6',
|
||||
value: 100000000,
|
||||
startPositions: [0, 6],
|
||||
paymentsInStep: [6, 6],
|
||||
stepsValues: [100, 50],
|
||||
},
|
||||
{
|
||||
name: '8/4',
|
||||
value: 100000001,
|
||||
startPositions: [0, 8],
|
||||
paymentsInStep: [8, 4],
|
||||
stepsValues: [100, 50],
|
||||
},
|
||||
{
|
||||
name: '4/4/4',
|
||||
value: 100000002,
|
||||
startPositions: [0, 4, 8],
|
||||
paymentsInStep: [4, 4, 4],
|
||||
stepsValues: [100, 75, 50],
|
||||
},
|
||||
{
|
||||
name: '100.50.25',
|
||||
value: 100000003,
|
||||
steps: [100, 50, 25],
|
||||
stepsValues: [100, 50, 25],
|
||||
},
|
||||
{
|
||||
name: '100.30.10',
|
||||
value: 100000004,
|
||||
steps: [100, 30, 10],
|
||||
stepsValues: [100, 30, 10],
|
||||
},
|
||||
{
|
||||
name: '100.70.40',
|
||||
value: 100000005,
|
||||
steps: [100, 70, 40],
|
||||
stepsValues: [100, 70, 40],
|
||||
},
|
||||
{
|
||||
name: '100.7.3',
|
||||
value: 100000006,
|
||||
steps: [100, 7, 3],
|
||||
stepsValues: [100, 7, 3],
|
||||
},
|
||||
],
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import { rotateArrays } from 'core/tools/array';
|
||||
import { ITable } from 'core/types/Calculation/Store/tables';
|
||||
import { isEqual } from 'lodash';
|
||||
import { inRange, isEqual } from 'lodash';
|
||||
import valuesConstants from 'core/constants/values';
|
||||
const { PERIODS_NUMBER } = valuesConstants;
|
||||
|
||||
const tablePayments: ITable = {
|
||||
rows: [
|
||||
@ -52,17 +55,67 @@ const tablePayments: ITable = {
|
||||
|
||||
if (graphType === 100000003) {
|
||||
const { leasingPeriod } = calculationStore.values;
|
||||
const periodsNumber = leasingPeriod <= 14 ? leasingPeriod - 2 : 12;
|
||||
if (rowIndex >= 1 && rowIndex <= periodsNumber) {
|
||||
for (let i = rowIndex; i < leasingPeriod - 1; i += periodsNumber) {
|
||||
calculationStore.setTableRow(
|
||||
tableName,
|
||||
i,
|
||||
)({
|
||||
paymentRelation: {
|
||||
value,
|
||||
},
|
||||
});
|
||||
if (rowIndex >= 1 && rowIndex <= PERIODS_NUMBER) {
|
||||
const { highSeasonStart } = calculationStore.values;
|
||||
const highSeasonStartValue = parseInt(
|
||||
calculationStore.options.selectHighSeasonStart?.find(
|
||||
x => x.value === highSeasonStart,
|
||||
)?.name || '2',
|
||||
),
|
||||
shiftNumber = highSeasonStartValue - 2;
|
||||
|
||||
const seasonTypeOptions = calculationStore.options.selectSeasonType?.find(
|
||||
x => x.value === seasonType,
|
||||
);
|
||||
const startPositions =
|
||||
seasonTypeOptions && seasonTypeOptions.startPositions,
|
||||
endPositions =
|
||||
seasonTypeOptions &&
|
||||
seasonTypeOptions.paymentsInStep.map(
|
||||
(x, i) => startPositions[i] + x,
|
||||
);
|
||||
|
||||
const allBoundaries = rotateArrays(startPositions, endPositions);
|
||||
|
||||
const withUnshift = n => n - shiftNumber;
|
||||
const withShift = n => n + shiftNumber;
|
||||
const withFirstPayment = n => n + 1;
|
||||
let index;
|
||||
for (let i = 0; i < allBoundaries.length; i++) {
|
||||
const [min, max] = allBoundaries[i].map(x => withFirstPayment(x));
|
||||
let unshiftedRowIndex = withUnshift(rowIndex);
|
||||
if (unshiftedRowIndex <= 0) {
|
||||
unshiftedRowIndex += PERIODS_NUMBER;
|
||||
}
|
||||
|
||||
if (inRange(unshiftedRowIndex, min, max)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const paymentsInStep =
|
||||
seasonTypeOptions && seasonTypeOptions.paymentsInStep;
|
||||
|
||||
for (
|
||||
let i =
|
||||
withFirstPayment(withShift(allBoundaries[index][0])) -
|
||||
PERIODS_NUMBER;
|
||||
i < leasingPeriod - 1;
|
||||
i += PERIODS_NUMBER
|
||||
) {
|
||||
const targetStartPosition = i;
|
||||
for (
|
||||
let j = targetStartPosition;
|
||||
j < paymentsInStep[index] + targetStartPosition;
|
||||
j++
|
||||
) {
|
||||
if (j > 0 && j < leasingPeriod - 1)
|
||||
calculationStore.setTableRow(
|
||||
tableName,
|
||||
j,
|
||||
)({ paymentRelation: { value } });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,4 +7,5 @@ export default {
|
||||
NDFL: 0.13,
|
||||
MAX_VEHICLE_MASS: 3500,
|
||||
MAX_VEHICLE_SEATS: 20,
|
||||
PERIODS_NUMBER: 12,
|
||||
};
|
||||
|
||||
@ -13,3 +13,15 @@ export function shiftRight(arr, n) {
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
export function rotateArrays(...arrs) {
|
||||
let res = [];
|
||||
for (let i = 0; i < arrs[0].length; i++) {
|
||||
let boundaries = [];
|
||||
for (let arr of arrs) {
|
||||
boundaries.push(arr[i]);
|
||||
}
|
||||
res.push(boundaries);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user