mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
chore: deprecate numberFormat
This commit is contained in:
parent
021d1d2a39
commit
36f9e47d58
@ -1,17 +1,15 @@
|
|||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const numberFormat = require('../utils/numberFormat');
|
|
||||||
const format = require('../utils/format');
|
const format = require('../utils/format');
|
||||||
const errors = require('./errors');
|
const errors = require('./errors');
|
||||||
const BaseDocument = require('frappejs/model/document');
|
const BaseDocument = require('frappejs/model/document');
|
||||||
const BaseMeta = require('frappejs/model/meta');
|
const BaseMeta = require('frappejs/model/meta');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
initLibs(frappe) {
|
initLibs(frappe) {
|
||||||
Object.assign(frappe, utils);
|
Object.assign(frappe, utils);
|
||||||
Object.assign(frappe, numberFormat);
|
Object.assign(frappe, format);
|
||||||
Object.assign(frappe, format);
|
frappe.errors = errors;
|
||||||
frappe.errors = errors;
|
frappe.BaseDocument = BaseDocument;
|
||||||
frappe.BaseDocument = BaseDocument;
|
frappe.BaseMeta = BaseMeta;
|
||||||
frappe.BaseMeta = BaseMeta;
|
},
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
@ -2,7 +2,6 @@ const frappe = require('frappejs');
|
|||||||
const Observable = require('frappejs/utils/observable');
|
const Observable = require('frappejs/utils/observable');
|
||||||
const naming = require('./naming');
|
const naming = require('./naming');
|
||||||
const { isPesa } = require('../utils/index');
|
const { isPesa } = require('../utils/index');
|
||||||
const { round } = require('frappejs/utils/numberFormat');
|
|
||||||
const { DEFAULT_INTERNAL_PRECISION } = require('../utils/consts');
|
const { DEFAULT_INTERNAL_PRECISION } = require('../utils/consts');
|
||||||
|
|
||||||
module.exports = class BaseDocument extends Observable {
|
module.exports = class BaseDocument extends Observable {
|
||||||
@ -696,7 +695,7 @@ module.exports = class BaseDocument extends Observable {
|
|||||||
}
|
}
|
||||||
const precision =
|
const precision =
|
||||||
frappe.SystemSettings.internalPrecision ?? DEFAULT_INTERNAL_PRECISION;
|
frappe.SystemSettings.internalPrecision ?? DEFAULT_INTERNAL_PRECISION;
|
||||||
return round(value, precision);
|
return frappe.pesa(value).clip(precision).float;
|
||||||
}
|
}
|
||||||
|
|
||||||
isNew() {
|
isNew() {
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
const numberFormat = require('frappejs/utils/numberFormat');
|
|
||||||
const assert = require('assert');
|
|
||||||
|
|
||||||
describe('Number Formatting', () => {
|
|
||||||
it('should format numbers', () => {
|
|
||||||
assert.equal(numberFormat.formatNumber(100), '100.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(1000), '1,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(10000), '10,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(100000), '100,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(1000000), '1,000,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(100.1234), '100.12');
|
|
||||||
assert.equal(numberFormat.formatNumber(1000.1234), '1,000.12');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse numbers', () => {
|
|
||||||
assert.equal(numberFormat.parseNumber('100.00'), 100);
|
|
||||||
assert.equal(numberFormat.parseNumber('1,000.00'), 1000);
|
|
||||||
assert.equal(numberFormat.parseNumber('10,000.00'), 10000);
|
|
||||||
assert.equal(numberFormat.parseNumber('100,000.00'), 100000);
|
|
||||||
assert.equal(numberFormat.parseNumber('1,000,000.00'), 1000000);
|
|
||||||
assert.equal(numberFormat.parseNumber('100.1234'), 100.1234);
|
|
||||||
assert.equal(numberFormat.parseNumber('1,000.1234'), 1000.1234);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should format lakhs and crores', () => {
|
|
||||||
assert.equal(numberFormat.formatNumber(100, '#,##,###.##'), '100.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(1000, '#,##,###.##'), '1,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(10000, '#,##,###.##'), '10,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(100000, '#,##,###.##'), '1,00,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(1000000, '#,##,###.##'), '10,00,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(10000000, '#,##,###.##'), '1,00,00,000.00');
|
|
||||||
assert.equal(numberFormat.formatNumber(100.1234, '#,##,###.##'), '100.12');
|
|
||||||
assert.equal(numberFormat.formatNumber(1000.1234, '#,##,###.##'), '1,000.12');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,6 +1,6 @@
|
|||||||
const numberFormat = require('./numberFormat');
|
|
||||||
const luxon = require('luxon');
|
const luxon = require('luxon');
|
||||||
const frappe = require('frappejs');
|
const frappe = require('frappejs');
|
||||||
|
const { DEFAULT_DISPLAY_PRECISION, DEFAULT_LOCALE } = require('./consts');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
format(value, df, doc) {
|
format(value, df, doc) {
|
||||||
@ -13,7 +13,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (df.fieldtype === 'Currency') {
|
if (df.fieldtype === 'Currency') {
|
||||||
value = formatCurrency(value, df, doc);
|
const currency = getCurrency(df, doc);
|
||||||
|
value = formatCurrency(value, currency);
|
||||||
} else if (df.fieldtype === 'Date') {
|
} else if (df.fieldtype === 'Date') {
|
||||||
let dateFormat;
|
let dateFormat;
|
||||||
if (!frappe.SystemSettings) {
|
if (!frappe.SystemSettings) {
|
||||||
@ -47,8 +48,62 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
formatCurrency,
|
||||||
|
formatNumber,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function formatCurrency(value, currency) {
|
||||||
|
let valueString;
|
||||||
|
try {
|
||||||
|
valueString = formatNumber(value);
|
||||||
|
} catch (err) {
|
||||||
|
err.message += ` value: '${value}', type: ${typeof value}`;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currencySymbol = frappe.currencySymbols[currency];
|
||||||
|
if (currencySymbol) {
|
||||||
|
return currencySymbol + ' ' + valueString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatNumber(value) {
|
||||||
|
const currencyFormatter = getNumberFormatter();
|
||||||
|
if (typeof value === 'number') {
|
||||||
|
return currencyFormatter.format(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.round) {
|
||||||
|
return currencyFormatter.format(value.round());
|
||||||
|
}
|
||||||
|
|
||||||
|
const formattedCurrency = currencyFormatter.format(value);
|
||||||
|
if (formattedCurrency === 'NaN') {
|
||||||
|
throw Error(
|
||||||
|
`invalid value passed to formatCurrency: '${value}' of type ${typeof value}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedCurrency;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNumberFormatter() {
|
||||||
|
if (frappe.currencyFormatter) {
|
||||||
|
return frappe.currencyFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const locale = frappe.SystemSettings.locale ?? DEFAULT_LOCALE;
|
||||||
|
const display =
|
||||||
|
frappe.SystemSettings.displayPrecision ?? DEFAULT_DISPLAY_PRECISION;
|
||||||
|
|
||||||
|
return (frappe.currencyFormatter = Intl.NumberFormat(locale, {
|
||||||
|
style: 'decimal',
|
||||||
|
minimumFractionDigits: display,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function getCurrency(df, doc) {
|
function getCurrency(df, doc) {
|
||||||
if (!(doc && df.getCurrency)) {
|
if (!(doc && df.getCurrency)) {
|
||||||
return df.currency || frappe.AccountingSettings.currency || '';
|
return df.currency || frappe.AccountingSettings.currency || '';
|
||||||
@ -60,21 +115,3 @@ function getCurrency(df, doc) {
|
|||||||
|
|
||||||
return df.getCurrency(doc);
|
return df.getCurrency(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatCurrency(value, df, doc) {
|
|
||||||
const currency = getCurrency(df, doc);
|
|
||||||
let valueString;
|
|
||||||
try {
|
|
||||||
valueString = numberFormat.formatCurrency(value);
|
|
||||||
} catch (err) {
|
|
||||||
err.message += ` value: '${value}', type: ${typeof value}`;
|
|
||||||
console.error(df);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
const currencySymbol = frappe.currencySymbols[currency];
|
|
||||||
|
|
||||||
if (currencySymbol) {
|
|
||||||
return currencySymbol + ' ' + valueString;
|
|
||||||
}
|
|
||||||
return valueString;
|
|
||||||
}
|
|
||||||
|
@ -1,146 +0,0 @@
|
|||||||
const frappe = require('frappejs');
|
|
||||||
const { DEFAULT_DISPLAY_PRECISION, DEFAULT_LOCALE } = require('./consts');
|
|
||||||
const numberFormats = {
|
|
||||||
'#,###.##': { fractionSep: '.', groupSep: ',', precision: 2 },
|
|
||||||
'#.###,##': { fractionSep: ',', groupSep: '.', precision: 2 },
|
|
||||||
'# ###.##': { fractionSep: '.', groupSep: ' ', precision: 2 },
|
|
||||||
'# ###,##': { fractionSep: ',', groupSep: ' ', precision: 2 },
|
|
||||||
"#'###.##": { fractionSep: '.', groupSep: "'", precision: 2 },
|
|
||||||
'#, ###.##': { fractionSep: '.', groupSep: ', ', precision: 2 },
|
|
||||||
'#,##,###.##': { fractionSep: '.', groupSep: ',', precision: 2 },
|
|
||||||
'#,###.###': { fractionSep: '.', groupSep: ',', precision: 3 },
|
|
||||||
'#.###': { fractionSep: '', groupSep: '.', precision: 0 },
|
|
||||||
'#,###': { fractionSep: '', groupSep: ',', precision: 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
// parse a formatted number string
|
|
||||||
// from "4,555,000.34" -> 4555000.34
|
|
||||||
parseNumber(number, format = '#,###.##') {
|
|
||||||
if (!number) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (typeof number === 'number') {
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
const info = this.getFormatInfo(format);
|
|
||||||
return parseFloat(this.removeSeparator(number, info.groupSep));
|
|
||||||
},
|
|
||||||
|
|
||||||
formatNumber(number, format = '#,###.##', precision = null) {
|
|
||||||
if (!number) {
|
|
||||||
number = 0;
|
|
||||||
}
|
|
||||||
let info = this.getFormatInfo(format);
|
|
||||||
if (precision) {
|
|
||||||
info.precision = precision;
|
|
||||||
}
|
|
||||||
let is_negative = false;
|
|
||||||
|
|
||||||
number = this.parseNumber(number);
|
|
||||||
if (number < 0) {
|
|
||||||
is_negative = true;
|
|
||||||
}
|
|
||||||
number = Math.abs(number);
|
|
||||||
number = number.toFixed(info.precision);
|
|
||||||
|
|
||||||
var parts = number.split('.');
|
|
||||||
|
|
||||||
// get group position and parts
|
|
||||||
var group_position = info.groupSep ? 3 : 0;
|
|
||||||
|
|
||||||
if (group_position) {
|
|
||||||
var integer = parts[0];
|
|
||||||
var str = '';
|
|
||||||
|
|
||||||
for (var i = integer.length; i >= 0; i--) {
|
|
||||||
var l = this.removeSeparator(str, info.groupSep).length;
|
|
||||||
if (format == '#,##,###.##' && str.indexOf(',') != -1) {
|
|
||||||
// INR
|
|
||||||
group_position = 2;
|
|
||||||
l += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
str += integer.charAt(i);
|
|
||||||
|
|
||||||
if (l && !((l + 1) % group_position) && i != 0) {
|
|
||||||
str += info.groupSep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parts[0] = str.split('').reverse().join('');
|
|
||||||
}
|
|
||||||
if (parts[0] + '' == '') {
|
|
||||||
parts[0] = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// join decimal
|
|
||||||
parts[1] = parts[1] && info.fractionSep ? info.fractionSep + parts[1] : '';
|
|
||||||
|
|
||||||
// join
|
|
||||||
return (is_negative ? '-' : '') + parts[0] + parts[1];
|
|
||||||
},
|
|
||||||
|
|
||||||
getFormatInfo(format) {
|
|
||||||
let format_info = numberFormats[format];
|
|
||||||
|
|
||||||
if (!format_info) {
|
|
||||||
throw new Error(`Unknown number format "${format}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return format_info;
|
|
||||||
},
|
|
||||||
|
|
||||||
round(num, precision) {
|
|
||||||
var is_negative = num < 0 ? true : false;
|
|
||||||
var d = parseInt(precision || 0);
|
|
||||||
var m = Math.pow(10, d);
|
|
||||||
var n = +(d ? Math.abs(num) * m : Math.abs(num)).toFixed(8); // Avoid rounding errors
|
|
||||||
var i = Math.floor(n),
|
|
||||||
f = n - i;
|
|
||||||
var r = !precision && f == 0.5 ? (i % 2 == 0 ? i : i + 1) : Math.round(n);
|
|
||||||
r = d ? r / m : r;
|
|
||||||
return is_negative ? -r : r;
|
|
||||||
},
|
|
||||||
|
|
||||||
removeSeparator(text, sep) {
|
|
||||||
return text.replace(new RegExp(sep === '.' ? '\\.' : sep, 'g'), '');
|
|
||||||
},
|
|
||||||
|
|
||||||
getDisplayPrecision() {
|
|
||||||
return frappe.SystemSettings.displayPrecision ?? DEFAULT_DISPLAY_PRECISION;
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurrencyFormatter() {
|
|
||||||
if (frappe.currencyFormatter) {
|
|
||||||
return frappe.currencyFormatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
const locale = frappe.SystemSettings.locale ?? DEFAULT_LOCALE;
|
|
||||||
const display = this.getDisplayPrecision();
|
|
||||||
|
|
||||||
return (frappe.currencyFormatter = Intl.NumberFormat(locale, {
|
|
||||||
style: 'decimal',
|
|
||||||
minimumFractionDigits: display,
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
|
|
||||||
formatCurrency(value) {
|
|
||||||
const currencyFormatter = this.getCurrencyFormatter();
|
|
||||||
if (typeof value === 'number') {
|
|
||||||
return currencyFormatter.format(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.round) {
|
|
||||||
return currencyFormatter.format(value.round());
|
|
||||||
}
|
|
||||||
|
|
||||||
const formattedCurrency = currencyFormatter.format(value);
|
|
||||||
if (formattedCurrency === 'NaN') {
|
|
||||||
throw Error(
|
|
||||||
`invalid value passed to formatCurrency: '${value}' of type ${typeof value}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return formattedCurrency;
|
|
||||||
},
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user