From 591abe97c504c84b01e259fe2d883b3c8088c5ca Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Wed, 5 Apr 2023 18:31:46 +0300 Subject: [PATCH] fix formatting numbers --- .../Form/Insurance/InsuranceTable/config.tsx | 6 ++--- .../Calculation/config/elements-props.tsx | 13 ++++++---- apps/web/Components/Output/Results/config.ts | 12 ++++++++- .../web/process/calculate/reactions/common.ts | 7 ++++- apps/web/process/price/reactions/common.ts | 11 +++++--- packages/tools/number.ts | 26 +------------------ packages/ui/elements/InputNumber.tsx | 13 ++++++++++ 7 files changed, 50 insertions(+), 38 deletions(-) diff --git a/apps/web/Components/Calculation/Form/Insurance/InsuranceTable/config.tsx b/apps/web/Components/Calculation/Form/Insurance/InsuranceTable/config.tsx index 8b9d71a..5b6ca90 100644 --- a/apps/web/Components/Calculation/Form/Insurance/InsuranceTable/config.tsx +++ b/apps/web/Components/Calculation/Form/Insurance/InsuranceTable/config.tsx @@ -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 = [ @@ -44,7 +44,7 @@ export const columns: ColumnsType = [ return ( = { tbxLeaseObjectPrice: { @@ -77,7 +80,7 @@ const props: Partial = { max: 50, precision: 4, parser, - formatter: formatterExtra, + formatter: createFormatter({ minimumFractionDigits: 4, maximumFractionDigits: 4 }), addonAfter: '%', }, tbxFirstPaymentRub: { @@ -95,7 +98,7 @@ const props: Partial = { step: 1, precision: 6, parser, - formatter: formatterExtra, + formatter: createFormatter({ minimumFractionDigits: 6, maximumFractionDigits: 6 }), addonAfter: '%', }, tbxLastPaymentRub: { @@ -203,7 +206,7 @@ const props: Partial = { step: 0.5, precision: 4, parser, - formatter: formatterExtra, + formatter: createFormatter({ minimumFractionDigits: 4, maximumFractionDigits: 4 }), addonAfter: 'л', }, tbxMaxMass: { @@ -363,7 +366,7 @@ const props: Partial = { step: 0.0001, precision: 6, parser, - formatter: formatterExtra, + formatter: createFormatter({ minimumFractionDigits: 6, maximumFractionDigits: 6 }), addonAfter: '%', }, linkDownloadKp: { diff --git a/apps/web/Components/Output/Results/config.ts b/apps/web/Components/Output/Results/config.ts index 0a4446b..a0f7848 100644 --- a/apps/web/Components/Output/Results/config.ts +++ b/apps/web/Components/Output/Results/config.ts @@ -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 = { 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, diff --git a/apps/web/process/calculate/reactions/common.ts b/apps/web/process/calculate/reactions/common.ts index 07fcc02..db14853 100644 --- a/apps/web/process/calculate/reactions/common.ts +++ b/apps/web/process/calculate/reactions/common.ts @@ -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) => { diff --git a/apps/web/process/price/reactions/common.ts b/apps/web/process/price/reactions/common.ts index 9e46eb0..40511e7 100644 --- a/apps/web/process/price/reactions/common.ts +++ b/apps/web/process/price/reactions/common.ts @@ -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, diff --git a/packages/tools/number.ts b/packages/tools/number.ts index d6fc194..c3f7c7a 100644 --- a/packages/tools/number.ts +++ b/packages/tools/number.ts @@ -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)); diff --git a/packages/ui/elements/InputNumber.tsx b/packages/ui/elements/InputNumber.tsx index 583f8da..be3a0f9 100644 --- a/packages/ui/elements/InputNumber.tsx +++ b/packages/ui/elements/InputNumber.tsx @@ -38,3 +38,16 @@ function InputNumber({ } export default InputNumber as FC; + +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; +}