diff --git a/.changeset/itchy-baths-cross.md b/.changeset/itchy-baths-cross.md new file mode 100644 index 0000000..8a4186d --- /dev/null +++ b/.changeset/itchy-baths-cross.md @@ -0,0 +1,5 @@ +--- +'@epilot/pricing': patch +--- + +Handle correct precision on net unit amount values diff --git a/src/variables/utils.test.ts b/src/variables/utils.test.ts index d363c2e..c37c839 100644 --- a/src/variables/utils.test.ts +++ b/src/variables/utils.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { fixedDiscountCoupon } from '../coupons/__tests__/coupon.fixtures'; import type { I18n } from '../shared/types'; import type { PriceItemWithParent } from './types'; -import { getUnitAmount } from './utils'; +import { getDecimalPrecision, getUnitAmount } from './utils'; const mockI18n = { t: (key: string, fallback: string) => key || fallback, @@ -48,3 +48,29 @@ describe('getUnitAmount', () => { expect(grossAmount).toBe('789,46\xa0€'); }); }); + +describe('getDecimalPrecision', () => { + it('returns 2 when input is undefined', () => { + expect(getDecimalPrecision(undefined)).toBe(2); + }); + + it('returns 2 when input has no decimal point', () => { + expect(getDecimalPrecision('12')).toBe(2); + }); + + it('returns 2 for a two-decimal string', () => { + expect(getDecimalPrecision('12.00')).toBe(2); + }); + + it('returns 1 for a one-decimal string', () => { + expect(getDecimalPrecision('12.5')).toBe(1); + }); + + it('returns the full precision for a high-precision string', () => { + expect(getDecimalPrecision('0.12345')).toBe(5); + }); + + it('returns the full precision for a high-precision string', () => { + expect(getDecimalPrecision('10.12345')).toBe(5); + }); +}); diff --git a/src/variables/utils.ts b/src/variables/utils.ts index d9e8aad..533b8d9 100644 --- a/src/variables/utils.ts +++ b/src/variables/utils.ts @@ -207,6 +207,11 @@ export const getUnitAmount = ( }); }; +export const getDecimalPrecision = (unitAmountDecimal?: string): number => { + const dotIndex = unitAmountDecimal?.indexOf('.'); + return unitAmountDecimal && dotIndex !== undefined && dotIndex !== -1 ? unitAmountDecimal.length - dotIndex - 1 : 2; +}; + const getTieredUnitAmount = ( item: PriceItemWithParent, i18n: I18n, @@ -248,6 +253,8 @@ const getTieredUnitAmount = ( item._price.pricing_model as PricingModel, ); + const netPrecision = useUnitAmountNet ? getDecimalPrecision(displayableTier?.unit_amount_decimal) : undefined; + const descriptionUnit = ''; const descriptionCurrency = item.currency as Currency; const descriptionTranslationFactory = (key: string) => i18n.t(`table_order.${key}`); @@ -265,7 +272,7 @@ const getTieredUnitAmount = ( language, descriptionCurrency, descriptionTranslationFactory, - { showStartsAt: false, enableSubunitDisplay: true }, + { showStartsAt: false, enableSubunitDisplay: true, precision: netPrecision }, tax, )?.split('/')[0]; // remove the unit part as it is not needed } @@ -278,7 +285,12 @@ const getTieredUnitAmount = ( language, descriptionCurrency, descriptionTranslationFactory, - { showStartsAt: false, showOnRequest: !isUnitAmountApproved, enableSubunitDisplay: true }, + { + showStartsAt: false, + showOnRequest: !isUnitAmountApproved, + enableSubunitDisplay: true, + precision: netPrecision, + }, tax, )?.split('/')[0]; // remove the unit part as it is not needed } @@ -291,7 +303,7 @@ const getTieredUnitAmount = ( language, descriptionCurrency, descriptionTranslationFactory, - { showStartsAt: false, enableSubunitDisplay: true }, + { showStartsAt: false, enableSubunitDisplay: true, precision: netPrecision }, tax, )?.split('/')[0]; // remove the unit part as it is not needed }