Skip to content

Commit

Permalink
feat: round number to decimal places
Browse files Browse the repository at this point in the history
  • Loading branch information
ogp-weeloong committed Apr 19, 2024
1 parent 7f1d354 commit 5526af9
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/backend/src/apps/formatter/actions/numbers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { fieldSchema as selectTransformFieldSchema } from '../../common/select-t
import { setUpActionFields } from '../../common/set-up-action-fields'

import { spec as performCalculation } from './transforms/perform-calculation'
import { spec as roundNumberDecimalPlaces } from './transforms/round-number-decimal-places'

const action: IRawAction = {
name: 'Numbers',
key: 'numbers',
description: 'Manipulate numbers in your data',
arguments: setUpActionFields({
commonFields: [],
transforms: [performCalculation],
transforms: [performCalculation, roundNumberDecimalPlaces],
}),

async run($) {
Expand All @@ -20,6 +21,8 @@ const action: IRawAction = {
switch (transformId) {
case performCalculation.id:
return await performCalculation.transformData($)
case roundNumberDecimalPlaces.id:
return await roundNumberDecimalPlaces.transformData($)
default:
throw new Error(`Unknown number transform: '${transformId}'`)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import z from 'zod'

import { numericStringSchema } from '@/apps/formatter/common/numeric-string-schema'
import { type TransformSpec } from '@/apps/formatter/common/transform-spec'
import { ensureZodEnumValue, ensureZodObjectKey } from '@/helpers/zod-utils'

const opTypeEnum = z.enum(['roundDown', 'roundUp', 'roundOff'])

export const fieldSchema = z
.object({
roundNumberValue: numericStringSchema,
roundNumberOp: opTypeEnum,
roundNumberToDecimalPlaces: numericStringSchema.pipe(
z
.number()
.int('Enter whole numbers without decimals')
.nonnegative('Enter a number greater than 0'),
),
})
.transform((params) => ({
value: params.roundNumberValue,
op: params.roundNumberOp,
toDecimalPlaces: params.roundNumberToDecimalPlaces,
}))

export const fields = [
{
label: 'What number do you want to round?',
key: ensureZodObjectKey(fieldSchema.sourceType(), 'roundNumberValue'),
type: 'string' as const,
required: true,
variables: true,
},
{
label: 'What kind of rounding do you want?',
key: ensureZodObjectKey(fieldSchema.sourceType(), 'roundNumberOp'),
type: 'dropdown' as const,
required: true,
variables: false,
showOptionValue: false,
options: [
{
label: 'Round Down',
value: ensureZodEnumValue(opTypeEnum, 'roundDown'),
},
{
label: 'Round Up',
value: ensureZodEnumValue(opTypeEnum, 'roundUp'),
},
{
label: 'Round Off',
value: ensureZodEnumValue(opTypeEnum, 'roundOff'),
},
],
},
{
label: 'How many decimal places do you want to round to?',
key: ensureZodObjectKey(
fieldSchema.sourceType(),
'roundNumberToDecimalPlaces',
),
type: 'string' as const,
required: true,
variables: true,
},
] satisfies TransformSpec['fields']
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { TransformSpec } from '@/apps/formatter/common/transform-spec'

import { fields } from './fields'
import { transformData } from './transform-data'

const id = 'roundNumberDecimalPlaces' satisfies TransformSpec['id']

const dropdownConfig = {
label: 'Round number to decimal places',
description:
'Round down, round up, or round off a number to the decimal places you want',
} satisfies TransformSpec['dropdownConfig']

export const spec = {
id,
dropdownConfig,
fields,
transformData,
} satisfies TransformSpec
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Big from 'big.js'
import { ZodError } from 'zod'

import type { TransformSpec } from '@/apps/formatter/common/transform-spec'
import StepError, { GenericSolution } from '@/errors/step'
import { firstZodParseError } from '@/helpers/zod-utils'

import { fieldSchema } from './fields'

export const transformData: TransformSpec['transformData'] = async ($) => {
try {
const { value, op, toDecimalPlaces } = fieldSchema.parse($.step.parameters)

let result = ''
switch (op) {
case 'roundOff':
result = new Big(value).toFixed(toDecimalPlaces)
break
case 'roundUp':
result = new Big(value).toFixed(toDecimalPlaces, Big.roundUp)
break
case 'roundDown':
result = new Big(value).toFixed(toDecimalPlaces, Big.roundDown)
break
}

$.setActionItem({
raw: {
result,
},
})
} catch (error) {
if (error instanceof ZodError) {
throw new StepError(
`Configuration problem: '${firstZodParseError(error)}'`,
GenericSolution.ReconfigureInvalidField,
$.step.position,
$.app.name,
)
} else {
throw new StepError(
`Error performing rounding: '${error.message}'`,
'Ensure that you have entered valid numbers.',
$.step.position,
$.app.name,
)
}
}
}

0 comments on commit 5526af9

Please sign in to comment.