feat: enhance sales module with decimal formatting and input improvements
- Updated various components to utilize `FieldCurrencyInput` for quantity inputs, improving user experience in financial data entry. - Introduced `formatDecimal` utility for consistent decimal formatting across the application, ensuring accurate display of numeric values. - Refactored quantity handling in forms and tables to support decimal values, enhancing data integrity and usability. - Added unit tests for new decimal formatting functionality to ensure reliability and correctness. These changes improve the sales module's handling of numeric inputs and displays, providing a more user-friendly experience for managing financial data.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export * from './field-value';
|
||||
export * from './render-date';
|
||||
export * from './render-currency';
|
||||
export * from './render-decimal';
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { RenderDecimal } from './render-decimal';
|
||||
|
||||
describe('RenderDecimal', () => {
|
||||
it('renders two display decimals without a currency prefix', () => {
|
||||
render(<RenderDecimal value="2.0000" />);
|
||||
expect(screen.getByText('2,00')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the fallback when empty', () => {
|
||||
render(<RenderDecimal value={null} />);
|
||||
expect(screen.getByText('-')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { formatDecimal } from '@repo/utils';
|
||||
|
||||
export interface RenderDecimalProps {
|
||||
value?: string | number | null;
|
||||
fallback?: string;
|
||||
}
|
||||
|
||||
export function RenderDecimal({ value, fallback = '-' }: RenderDecimalProps) {
|
||||
const formatted = formatDecimal(value);
|
||||
return <>{formatted || fallback}</>;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||
import { CurrencyUtils, formatRupiah, toCurrencyNumber } from './currency.utils';
|
||||
import { CurrencyUtils, formatDecimal, formatRupiah, toCurrencyNumber } from './currency.utils';
|
||||
|
||||
describe('CurrencyUtils', () => {
|
||||
let currency: CurrencyUtils;
|
||||
@@ -140,6 +140,15 @@ describe('CurrencyUtils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatDecimal', () => {
|
||||
it('should format with two display decimals and no currency prefix', () => {
|
||||
const stored = '2.0000';
|
||||
expect(formatDecimal(stored)).toBe('2,00');
|
||||
expect(formatDecimal('1234.5678')).toBe('1.234,57');
|
||||
expect(stored).toBe('2.0000');
|
||||
});
|
||||
});
|
||||
|
||||
describe('toCurrencyNumber', () => {
|
||||
it('should keep numeric values as numbers', () => {
|
||||
expect(toCurrencyNumber(12500.12345)).toBe(12500.12345);
|
||||
|
||||
@@ -192,6 +192,13 @@ export function formatRupiah(value: CurrencyInput): string {
|
||||
return displayCurrency.format(value);
|
||||
}
|
||||
|
||||
const displayDecimal = new CurrencyUtils({ prefix: '', decimalScale: CURRENCY_DISPLAY_SCALE });
|
||||
|
||||
/** Format a numeric value with two display decimals and no currency prefix. */
|
||||
export function formatDecimal(value: CurrencyInput): string {
|
||||
return displayDecimal.format(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce a stored price (number or decimal string) into a NumberInput value.
|
||||
* Empty / invalid inputs stay as '' so the form field can remain blank.
|
||||
|
||||
Reference in New Issue
Block a user