2
0
mirror of https://github.com/frappe/books.git synced 2024-11-10 07:40:55 +00:00
books/fyo/utils/format.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

203 lines
4.6 KiB
TypeScript
Raw Normal View History

import { Fyo } from 'fyo';
import { Doc } from 'fyo/model/doc';
2022-04-18 08:01:41 +00:00
import { DateTime } from 'luxon';
import { Field, FieldType, FieldTypeEnum } from 'schemas/types';
import { getIsNullOrUndef, safeParseFloat, titleCase } from 'utils';
import { isPesa } from '.';
2022-04-18 08:01:41 +00:00
import {
DEFAULT_CURRENCY,
DEFAULT_DATE_FORMAT,
DEFAULT_DISPLAY_PRECISION,
DEFAULT_LOCALE,
2022-04-18 08:01:41 +00:00
} from './consts';
export function format(
value: unknown,
df: string | Field | null,
doc: Doc | null,
fyo: Fyo
2022-04-18 08:01:41 +00:00
): string {
if (!df) {
return String(value);
}
const field: Field = getField(df);
if (field.fieldtype === FieldTypeEnum.Float) {
return Number(value).toFixed(fyo.singles.SystemSettings?.displayPrecision);
}
if (field.fieldtype === FieldTypeEnum.Int) {
return Math.trunc(Number(value)).toString();
}
2022-04-18 08:01:41 +00:00
if (field.fieldtype === FieldTypeEnum.Currency) {
return formatCurrency(value, field, doc, fyo);
2022-04-18 08:01:41 +00:00
}
if (field.fieldtype === FieldTypeEnum.Date) {
return formatDate(value, fyo);
2022-04-18 08:01:41 +00:00
}
if (field.fieldtype === FieldTypeEnum.Datetime) {
2022-11-09 18:42:00 +00:00
return formatDatetime(value, fyo);
}
2022-04-18 08:01:41 +00:00
if (field.fieldtype === FieldTypeEnum.Check) {
return titleCase(Boolean(value).toString());
2022-04-18 08:01:41 +00:00
}
if (getIsNullOrUndef(value)) {
return '';
}
return String(value);
}
function toDatetime(value: unknown): DateTime | null {
2022-04-18 08:01:41 +00:00
if (typeof value === 'string') {
2022-11-09 18:42:00 +00:00
return DateTime.fromISO(value);
2022-04-18 08:01:41 +00:00
} else if (value instanceof Date) {
2022-11-09 18:42:00 +00:00
return DateTime.fromJSDate(value);
} else if (typeof value === 'number') {
2022-11-09 18:42:00 +00:00
return DateTime.fromSeconds(value as number);
}
return null;
2022-11-09 18:42:00 +00:00
}
function formatDatetime(value: unknown, fyo: Fyo): string {
if (value == null) {
return '';
}
2022-11-09 18:42:00 +00:00
const dateFormat =
(fyo.singles.SystemSettings?.dateFormat as string) ?? DEFAULT_DATE_FORMAT;
const dateTime = toDatetime(value);
if (!dateTime) {
return '';
}
const formattedDatetime = dateTime.toFormat(`${dateFormat} HH:mm:ss`);
2022-11-09 18:42:00 +00:00
if (value === 'Invalid DateTime') {
return '';
2022-04-18 08:01:41 +00:00
}
2022-11-09 18:42:00 +00:00
return formattedDatetime;
}
function formatDate(value: unknown, fyo: Fyo): string {
if (value == null) {
return '';
}
2022-11-09 18:42:00 +00:00
const dateFormat =
(fyo.singles.SystemSettings?.dateFormat as string) ?? DEFAULT_DATE_FORMAT;
const dateTime = toDatetime(value);
if (!dateTime) {
return '';
}
2022-11-09 18:42:00 +00:00
const formattedDate = dateTime.toFormat(dateFormat);
2022-04-18 08:01:41 +00:00
if (value === 'Invalid DateTime') {
return '';
}
return formattedDate;
}
function formatCurrency(
value: unknown,
field: Field,
doc: Doc | null,
fyo: Fyo
): string {
const currency = getCurrency(field, doc, fyo);
2022-04-18 08:01:41 +00:00
let valueString;
try {
valueString = formatNumber(value, fyo);
2022-04-18 08:01:41 +00:00
} catch (err) {
(err as Error).message += ` value: '${value}', type: ${typeof value}`;
throw err;
}
const currencySymbol = fyo.currencySymbols[currency];
2022-04-18 08:01:41 +00:00
if (currencySymbol !== undefined) {
return currencySymbol + ' ' + valueString;
}
return valueString;
}
function formatNumber(value: unknown, fyo: Fyo): string {
const numberFormatter = getNumberFormatter(fyo);
2022-04-18 08:01:41 +00:00
if (typeof value === 'number') {
2022-05-16 10:10:35 +00:00
value = fyo.pesa(value.toFixed(20));
2022-04-18 08:01:41 +00:00
}
if (isPesa(value)) {
const floatValue = safeParseFloat(value.round());
2022-04-18 08:01:41 +00:00
return numberFormatter.format(floatValue);
}
const floatValue = safeParseFloat(value as string);
2022-04-18 08:01:41 +00:00
const formattedNumber = numberFormatter.format(floatValue);
if (formattedNumber === 'NaN') {
throw Error(
`invalid value passed to formatNumber: '${value}' of type ${typeof value}`
);
}
return formattedNumber;
}
function getNumberFormatter(fyo: Fyo) {
if (fyo.currencyFormatter) {
return fyo.currencyFormatter;
2022-04-18 08:01:41 +00:00
}
const locale =
(fyo.singles.SystemSettings?.locale as string) ?? DEFAULT_LOCALE;
2022-04-18 08:01:41 +00:00
const display =
(fyo.singles.SystemSettings?.displayPrecision as number) ??
2022-04-18 08:01:41 +00:00
DEFAULT_DISPLAY_PRECISION;
return (fyo.currencyFormatter = Intl.NumberFormat(locale, {
2022-04-18 08:01:41 +00:00
style: 'decimal',
minimumFractionDigits: display,
}));
}
function getCurrency(field: Field, doc: Doc | null, fyo: Fyo): string {
2022-09-29 11:04:35 +00:00
const defaultCurrency =
fyo.singles.SystemSettings?.currency ?? DEFAULT_CURRENCY;
let getCurrency = doc?.getCurrencies?.[field.fieldname];
if (getCurrency !== undefined) {
return getCurrency();
2022-04-18 08:01:41 +00:00
}
getCurrency = doc?.parentdoc?.getCurrencies[field.fieldname];
if (getCurrency !== undefined) {
return getCurrency();
2022-04-18 08:01:41 +00:00
}
2022-09-29 11:04:35 +00:00
return defaultCurrency;
2022-04-18 08:01:41 +00:00
}
function getField(df: string | Field): Field {
if (typeof df === 'string') {
return {
label: '',
fieldname: '',
fieldtype: df as FieldType,
} as Field;
2022-04-18 08:01:41 +00:00
}
return df;
}