fix formatting numbers

This commit is contained in:
vchikalkin 2023-04-05 18:31:46 +03:00
parent a747af7333
commit 591abe97c5
7 changed files with 50 additions and 38 deletions

View File

@ -3,8 +3,8 @@ import { buildOptionComponent, buildValueComponent } from './builders';
import type * as Insurance from './types';
import { MAX_INSURANCE } from '@/constants/values';
import type { ColumnsType } from 'antd/lib/table';
import { formatter, parser } from 'tools/number';
import InputNumber from 'ui/elements/InputNumber';
import { parser } from 'tools/number';
import InputNumber, { createFormatter } from 'ui/elements/InputNumber';
import Select from 'ui/elements/Select';
export const columns: ColumnsType<Insurance.RowValues> = [
@ -44,7 +44,7 @@ export const columns: ColumnsType<Insurance.RowValues> = [
return (
<Component
addonAfter="₽"
formatter={formatter}
formatter={createFormatter({ minimumFractionDigits: 2, maximumFractionDigits: 2 })}
max={MAX_INSURANCE}
min={0}
parser={parser}

View File

@ -4,8 +4,11 @@ import CurrencyAddon from '../addons/currency-addon';
import type { ElementsProps } from './elements-components';
import { MAX_FRANCHISE, MAX_LEASING_PERIOD } from '@/constants/values';
import dayjs from 'dayjs';
import { formatter, formatterExtra, parser } from 'tools/number';
import { parser } from 'tools/number';
import { DownloadOutlined, PlusOutlined } from 'ui/elements/icons';
import { createFormatter } from 'ui/elements/InputNumber';
const formatter = createFormatter({ minimumFractionDigits: 2, maximumFractionDigits: 2 });
const props: Partial<ElementsProps> = {
tbxLeaseObjectPrice: {
@ -77,7 +80,7 @@ const props: Partial<ElementsProps> = {
max: 50,
precision: 4,
parser,
formatter: formatterExtra,
formatter: createFormatter({ minimumFractionDigits: 4, maximumFractionDigits: 4 }),
addonAfter: '%',
},
tbxFirstPaymentRub: {
@ -95,7 +98,7 @@ const props: Partial<ElementsProps> = {
step: 1,
precision: 6,
parser,
formatter: formatterExtra,
formatter: createFormatter({ minimumFractionDigits: 6, maximumFractionDigits: 6 }),
addonAfter: '%',
},
tbxLastPaymentRub: {
@ -203,7 +206,7 @@ const props: Partial<ElementsProps> = {
step: 0.5,
precision: 4,
parser,
formatter: formatterExtra,
formatter: createFormatter({ minimumFractionDigits: 4, maximumFractionDigits: 4 }),
addonAfter: 'л',
},
tbxMaxMass: {
@ -363,7 +366,7 @@ const props: Partial<ElementsProps> = {
step: 0.0001,
precision: 6,
parser,
formatter: formatterExtra,
formatter: createFormatter({ minimumFractionDigits: 6, maximumFractionDigits: 6 }),
addonAfter: '%',
},
linkDownloadKp: {

View File

@ -1,5 +1,4 @@
import type { ResultValues } from '@/stores/results/types';
import { moneyFormatter, percentFormatter } from 'tools';
export const id = 'output';
export const title = 'Результаты';
@ -26,6 +25,17 @@ export const titles: Record<keyof ResultValues, string> = {
resultTotalGraphwithNDS: 'Итого по графику, с НДС',
};
const moneyFormatter = Intl.NumberFormat('ru', {
currency: 'RUB',
style: 'currency',
}).format;
const percentFormatter = Intl.NumberFormat('ru', {
maximumFractionDigits: 2,
minimumFractionDigits: 2,
style: 'percent',
}).format;
export const formatters = {
resultAB_FL: moneyFormatter,
resultAB_UL: moneyFormatter,

View File

@ -1,7 +1,10 @@
import helper from '../lib/helper';
import type { ProcessContext } from '@/process/types';
import { reaction } from 'mobx';
import { formatter } from 'tools';
export const formatter = Intl.NumberFormat('ru', {
minimumFractionDigits: 2,
}).format;
export default function reactions({ store, apolloClient }: ProcessContext) {
const { $calculation } = store;
@ -27,7 +30,9 @@ export default function reactions({ store, apolloClient }: ProcessContext) {
fireImmediately: true,
}
);
const { getIrr } = helper({ apolloClient });
reaction(
() => $calculation.$values.getValues(['product', 'tarif', 'bonusCoefficient']),
async (values) => {

View File

@ -40,9 +40,14 @@ export default function reactions({ store, apolloClient }: ProcessContext) {
reaction(
() => $calculation.$values.getValues(['leaseObjectPrice', 'supplierDiscountRub']),
({ leaseObjectPrice, supplierDiscountRub }) => {
$calculation
.element('tbxSupplierDiscountPerc')
.setValue((supplierDiscountRub / leaseObjectPrice) * 100);
// NaN fix
if (leaseObjectPrice === 0) {
$calculation.element('tbxSupplierDiscountPerc').resetValue();
} else {
$calculation
.element('tbxSupplierDiscountPerc')
.setValue((supplierDiscountRub / leaseObjectPrice) * 100);
}
},
{
fireImmediately: true,

View File

@ -1,34 +1,10 @@
/* eslint-disable func-style */
export function parser(value?: string) {
if (!value) return 0;
// eslint-disable-next-line unicorn/prefer-string-replace-all, require-unicode-regexp
const normalized = value.replace(/\s/g, '').replaceAll(',', '.');
const normalized = value.replaceAll(/\s/gu, '').replaceAll(',', '.');
return Number.parseFloat(normalized);
}
export const formatter = (value?: number) =>
Intl.NumberFormat('ru', {
minimumFractionDigits: 2,
}).format(value || 0);
export const formatterExtra = (value?: number) =>
Intl.NumberFormat('ru', {
maximumFractionDigits: 6,
minimumFractionDigits: 2,
}).format(value || 0);
export const moneyFormatter = Intl.NumberFormat('ru', {
currency: 'RUB',
style: 'currency',
}).format;
export const percentFormatter = Intl.NumberFormat('ru', {
maximumFractionDigits: 2,
minimumFractionDigits: 2,
style: 'percent',
}).format;
export function round(value: number, precision: number = 0) {
return Number.parseFloat(value.toFixed(precision));

View File

@ -38,3 +38,16 @@ function InputNumber({
}
export default InputNumber as FC<InputNumberProps>;
export function createFormatter(options: Intl.NumberFormatOptions) {
const format = Intl.NumberFormat('ru', options).format;
return ((value, { userTyping }) => {
if (userTyping) {
// return Intl.NumberFormat('ru').format(value || 0);
return value || 0;
}
return format(value || 0);
}) as NonNullable<InputNumberProps['formatter']>;
}