projects/wms-framework/src/lib/utils/BaseNumericStringFormatter.ts
Base class for the string formatting functionality
Methods |
|
Private ConvertAbsoluteNumericValueToString | ||||||||||||||||||
ConvertAbsoluteNumericValueToString(value: number, decimalDigits: number, decimalSeparator: string, groupSizes: number[], groupSeparator: string)
|
||||||||||||||||||
Converts a number to a string using specifying the number of:
The value returned will be the string representation of the absolute value
Parameters :
Returns :
any
|
Private FormatCurrencyToNegativeValue | |||||||||
FormatCurrencyToNegativeValue(strValue: string, globalizationInfo: GlobalizationHelper)
|
|||||||||
Formats the number with the currency symbol considering it is a negative value
Parameters :
Returns :
string
{string} |
Private FormatCurrencyToPositiveValue | |||||||||
FormatCurrencyToPositiveValue(strValue: string, globalizationInfo: GlobalizationHelper)
|
|||||||||
Formats the number with the currency symbol considering it is a positive value
Parameters :
Returns :
string
{string} |
Public FormatNumber | ||||||||||||||||
FormatNumber(value: number, formatString: string, globalizationInfo?: GlobalizationHelper)
|
||||||||||||||||
Format a number with the given format string and for the specified globalization info
Parameters :
Returns :
string
{string} the formatted number |
Private FormatNumberToNegativeValue | |||||||||
FormatNumberToNegativeValue(strValue: string, globalizationInfo: GlobalizationHelper)
|
|||||||||
Formats the number a negative value
Parameters :
Returns :
string
{string} |
Private FormatPercentToNegativeValue | |||||||||
FormatPercentToNegativeValue(strValue: string, globalizationInfo: GlobalizationHelper)
|
|||||||||
Formats the number with the percent symbol considering it is a negative value
Parameters :
Returns :
string
{string} |
Private FormatPercentToPositiveValue | |||||||||
FormatPercentToPositiveValue(strValue: string, globalizationInfo: GlobalizationHelper)
|
|||||||||
Formats the number with the percent symbol considering it is a positive value
Parameters :
Returns :
string
{string} |
Protected Abstract PerformCustomNumericFormatting | ||||||||||||
PerformCustomNumericFormatting(value: number, preprocessedValue: string)
|
||||||||||||
Performs the string formatting using the presprocessed string
Parameters :
Returns :
string
{string} the formatted string |
Protected PerformStandardCurrencyFormatting | ||||||||||||
PerformStandardCurrencyFormatting(value: number, precision: number, globalizationInfo: GlobalizationHelper)
|
||||||||||||
Performs the string formatting to currency
Parameters :
Returns :
string
{string} |
Protected PerformStandardNumericFormatting | ||||||||||||
PerformStandardNumericFormatting(value: number, precision: number, globalizationInfo: GlobalizationHelper)
|
||||||||||||
Performs the string formatting to numeric
Parameters :
Returns :
string
{string} |
Protected PerformStandardPercentFormatting | ||||||||||||
PerformStandardPercentFormatting(value: number, precision: number, globalizationInfo: GlobalizationHelper)
|
||||||||||||
Performs the string formatting to percentage
Parameters :
Returns :
string
{string} |
Private ResolveStandardFormatApplied | ||||||
ResolveStandardFormatApplied(formatString: string)
|
||||||
Tryies to resolve if the format applied is a standard numeric format and if a precision was specified
Parameters :
Returns :
literal type
{{ StandardFormat: StandardNumericFormatsEnum, Precision: number }} |
import { GlobalizationHelper } from '../baseframework/globalization';
import { StandardNumericFormatsEnum } from './StandardNumericFormatsEnum';
/**
* Base class for the string formatting functionality
*
* @export
* @abstract
* @class BaseNumericStringFormatter
*/
export abstract class BaseNumericStringFormatter {
/**
* Format a number with the given format string and for the specified globalization info
*
* @param {number} value number to format
* @param {string} formatString formatting string
* @param {GlobalizationHelper} [globalizationInfo] optional globalization fino
* @return {*} {string} the formatted number
* @memberof BaseNumericStringFormatter
*/
public FormatNumber(
value: number,
formatString: string,
globalizationInfo?: GlobalizationHelper
): string {
const formatDetails = this.ResolveStandardFormatApplied(formatString);
switch (formatDetails.StandardFormat) {
case StandardNumericFormatsEnum.Currency:
return this.PerformStandardCurrencyFormatting(
value,
formatDetails.Precision,
globalizationInfo ?? GlobalizationHelper.Current
);
case StandardNumericFormatsEnum.Percent:
return this.PerformStandardPercentFormatting(
value,
formatDetails.Precision,
globalizationInfo ?? GlobalizationHelper.Current
);
case StandardNumericFormatsEnum.Number:
return this.PerformStandardNumericFormatting(
value,
formatDetails.Precision,
globalizationInfo ?? GlobalizationHelper.Current
);
default:
return this.PerformCustomNumericFormatting(value, formatString);
}
}
/**
* Tryies to resolve if the format applied is a standard numeric format and if a precision was
* specified
*
* @private
* @param {string} formatString
* @return {*} {{ StandardFormat: StandardNumericFormatsEnum, Precision: number }}
* @memberof BaseNumericStringFormatter
*/
private ResolveStandardFormatApplied(formatString: string): {
StandardFormat: StandardNumericFormatsEnum;
Precision: number;
} {
let formatType: StandardNumericFormatsEnum =
StandardNumericFormatsEnum.Unknown;
let precision: number = null;
formatString = formatString ?? '';
const matchForAlias = formatString
.toLowerCase()
.match(/^([cdefgnprx])([0-9]*)$/i);
if (matchForAlias) {
if (matchForAlias.length >= 2 && matchForAlias[2] !== '') {
precision = parseInt(matchForAlias[2], 10);
}
switch (matchForAlias[1]) {
case 'c':
formatType = StandardNumericFormatsEnum.Currency;
break;
case 'd':
formatType = StandardNumericFormatsEnum.Decimal;
break;
case 'e':
formatType = StandardNumericFormatsEnum.Exponential;
break;
case 'f':
formatType = StandardNumericFormatsEnum.FixedPoint;
break;
case 'g':
formatType = StandardNumericFormatsEnum.General;
break;
case 'n':
formatType = StandardNumericFormatsEnum.Number;
break;
case 'p':
formatType = StandardNumericFormatsEnum.Percent;
break;
case 'r':
formatType = StandardNumericFormatsEnum.RoundTrip;
break;
case 'x':
formatType = StandardNumericFormatsEnum.Hexadecimal;
break;
}
}
return {
StandardFormat: formatType,
Precision: precision,
};
}
/**
* Performs the string formatting using the presprocessed string
*
* @protected
* @abstract
* @param {number} value value to format
* @param {string} preprocessedValue preprocessed format string
* @return {*} {string} the formatted string
* @memberof BaseNumericStringFormatter
*/
protected abstract PerformCustomNumericFormatting(
value: number,
preprocessedValue: string
): string;
/**
* Performs the string formatting to currency
*
* @protected
* @param {number} value
* @param {number} precision
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
protected PerformStandardCurrencyFormatting(
value: number,
precision: number,
globalizationInfo: GlobalizationHelper
): string {
const decimalDigitCount =
precision ?? globalizationInfo?.NumberFormat?.CurrencyDecimalDigits ?? 2;
const groupSizes =
globalizationInfo?.NumberFormat?.CurrencyGroupSizes != null &&
globalizationInfo?.NumberFormat?.CurrencyGroupSizes?.length > 0
? [...globalizationInfo.NumberFormat.CurrencyGroupSizes]
: [3]; //default value
const decimalSeparator =
globalizationInfo?.NumberFormat?.CurrencyDecimalSeparator ?? '.';
const groupSeparator =
globalizationInfo?.NumberFormat?.CurrencyGroupSeparator ?? ',';
//Reduces the decimal to the one requested and split integer from decimal part
let strValue = this.ConvertAbsoluteNumericValueToString(
value,
decimalDigitCount,
decimalSeparator,
groupSizes,
groupSeparator
);
if (value < 0) {
return this.FormatCurrencyToNegativeValue(strValue, globalizationInfo);
} else {
return this.FormatCurrencyToPositiveValue(strValue, globalizationInfo);
}
}
/**
* Performs the string formatting to percentage
*
* @protected
* @param {number} value
* @param {number} precision
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
protected PerformStandardPercentFormatting(
value: number,
precision: number,
globalizationInfo: GlobalizationHelper
): string {
const decimalDigitCount =
precision ?? globalizationInfo?.NumberFormat?.PercentDecimalDigits ?? 2;
const groupSizes =
globalizationInfo?.NumberFormat?.PercentGroupSizes != null &&
globalizationInfo?.NumberFormat?.PercentGroupSizes?.length > 0
? [...globalizationInfo.NumberFormat.PercentGroupSizes]
: [3]; //default value
const decimalSeparator =
globalizationInfo?.NumberFormat?.PercentDecimalSeparator ?? '.';
const groupSeparator =
globalizationInfo?.NumberFormat?.PercentGroupSeparator ?? ',';
value = (value ?? 0) * 100.0;
//Reduces the decimal to the one requested and split integer from decimal part
let strValue = this.ConvertAbsoluteNumericValueToString(
value,
decimalDigitCount,
decimalSeparator,
groupSizes,
groupSeparator
);
if (value < 0) {
return this.FormatPercentToNegativeValue(strValue, globalizationInfo);
} else {
return this.FormatPercentToPositiveValue(strValue, globalizationInfo);
}
}
/**
* Performs the string formatting to numeric
*
* @protected
* @param {number} value
* @param {number} precision
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
protected PerformStandardNumericFormatting(
value: number,
precision: number,
globalizationInfo: GlobalizationHelper
): string {
const decimalDigitCount =
precision ?? globalizationInfo?.NumberFormat?.NumberDecimalDigits ?? 2;
const groupSizes =
globalizationInfo?.NumberFormat?.NumberGroupSizes != null &&
globalizationInfo?.NumberFormat?.NumberGroupSizes?.length > 0
? [...globalizationInfo.NumberFormat.NumberGroupSizes]
: [3]; //default value
const decimalSeparator =
globalizationInfo?.NumberFormat?.NumberDecimalSeparator ?? '.';
const groupSeparator =
globalizationInfo?.NumberFormat?.NumberGroupSeparator ?? ',';
//Reduces the decimal to the one requested and split integer from decimal part
let strValue = this.ConvertAbsoluteNumericValueToString(
value,
decimalDigitCount,
decimalSeparator,
groupSizes,
groupSeparator
);
if (value < 0) {
return this.FormatNumberToNegativeValue(strValue, globalizationInfo);
} else {
return strValue;
}
}
/**
* Converts a number to a string using specifying the number of:
* - decimal digits to use
* - decimal separator string to use
* - group sizes to use
* - group separator string to use
*
* The value returned will be the string representation of the absolute value
*
* @private
* @param {number} value
* @param {number} decimalDigits
* @param {string} decimalSeparator
* @param {number[]} groupSizes
* @param {string} groupSeparator
* @return {*}
* @memberof BaseNumericStringFormatter
*/
private ConvertAbsoluteNumericValueToString(
value: number,
decimalDigits: number,
decimalSeparator: string,
groupSizes: number[],
groupSeparator: string
) {
const valueParts = Math.abs(value).toFixed(decimalDigits).split('.');
const strDecimals = valueParts.length == 2 ? valueParts[1] : null;
let strInteger = valueParts[0];
const strIntegerPars = [];
//Create the groups of the integer part
let groupSize: number = 0;
while (strInteger != '') {
if (groupSizes.length > 0) groupSize = groupSizes.shift();
if (strInteger.length >= groupSize) {
strIntegerPars.unshift(
strInteger.substring(strInteger.length - groupSize)
);
strInteger = strInteger.substring(0, strInteger.length - groupSize);
} else {
strIntegerPars.unshift(strInteger);
strInteger = '';
}
}
//Joining all elements using the required separators
let strValue = strIntegerPars.join(groupSeparator);
if (strDecimals) {
strValue += `${decimalSeparator}${strDecimals}`;
}
return strValue;
}
/**
* Formats the number with the currency symbol considering it is a positive value
*
* @private
* @param {string} strValue
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
private FormatCurrencyToPositiveValue(
strValue: string,
globalizationInfo: GlobalizationHelper
): string {
const symbol = globalizationInfo?.NumberFormat?.CurrencySymbol ?? '$';
switch (globalizationInfo?.NumberFormat?.CurrencyPositivePattern) {
case 0: // $n
return `${symbol}${strValue}`;
case 1: // n$
return `${strValue}${symbol}`;
case 2: // $ n
return `${symbol} ${strValue}`;
case 3: // n $
return `${strValue} ${symbol}`;
default: // $n
return `${symbol}${strValue}`;
}
}
/**
* Formats the number with the currency symbol considering it is a negative value
*
* @private
* @param {string} strValue
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
private FormatCurrencyToNegativeValue(
strValue: string,
globalizationInfo: GlobalizationHelper
): string {
const symbol = globalizationInfo?.NumberFormat?.CurrencySymbol ?? '$';
const negativeSign = globalizationInfo?.NumberFormat?.NegativeSign ?? '-';
switch (globalizationInfo?.NumberFormat?.CurrencyNegativePattern) {
case 0: // ($n)
return `(${symbol}${strValue})`;
case 1: // -$n
return `${negativeSign}${symbol}${strValue}`;
case 2: // $-n
return `${symbol}${negativeSign}${strValue}`;
case 3: // $n-
return `${symbol}${strValue}${negativeSign}`;
case 4: // (n$)
return `(${strValue}${symbol})`;
case 5: // -n$
return `${negativeSign}${strValue}${symbol}`;
case 6: // n-$
return `${strValue}${negativeSign}${symbol}`;
case 7: // n$-
return `${strValue}${symbol}${negativeSign}`;
case 8: // -n $
return `${negativeSign}${strValue} ${symbol}`;
case 9: // -$ n
return `${negativeSign}${symbol} ${strValue}`;
case 10: // n $-
return `${strValue} ${symbol}${negativeSign}`;
case 11: // $ n-
return `${symbol} ${strValue}${negativeSign}`;
case 12: // $ -n
return `${symbol} ${negativeSign}${strValue}`;
case 13: // n- $
return `${strValue}${negativeSign} ${symbol}`;
case 14: // ($ n)
return `(${symbol} ${strValue})`;
case 15: // (n $)
return `(${strValue} ${symbol})`;
default: // ($n)
return `(${symbol}${strValue})`;
}
}
/**
* Formats the number with the percent symbol considering it is a positive value
*
* @private
* @param {string} strValue
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
private FormatPercentToPositiveValue(
strValue: string,
globalizationInfo: GlobalizationHelper
): string {
const symbol = globalizationInfo?.NumberFormat?.PercentSymbol ?? '%';
switch (globalizationInfo?.NumberFormat?.PercentPositivePattern) {
case 0: // n %
return `${strValue} ${symbol}`;
case 1: // n%
return `${strValue}${symbol}`;
case 2: // %n
return `${symbol}${strValue}`;
case 3: // % n
return `${symbol} ${strValue}`;
default: // n %
return `${strValue} ${symbol}`;
}
}
/**
* Formats the number with the percent symbol considering it is a negative value
*
* @private
* @param {string} strValue
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
private FormatPercentToNegativeValue(
strValue: string,
globalizationInfo: GlobalizationHelper
): string {
const symbol = globalizationInfo?.NumberFormat?.PercentSymbol ?? '%';
const negativeSign = globalizationInfo?.NumberFormat?.NegativeSign ?? '-';
switch (globalizationInfo?.NumberFormat?.PercentNegativePattern) {
case 0: // -n %
return `${negativeSign}${strValue} ${symbol}`;
case 1: // -n%
return `${negativeSign}${strValue}${symbol}`;
case 2: // -%n
return `${negativeSign}${symbol}${strValue}`;
case 3: // %-n
return `${symbol}${negativeSign}${strValue}`;
case 4: // %n-
return `${symbol}${strValue}${negativeSign}`;
case 5: // n-%
return `${strValue}${negativeSign}${symbol}`;
case 6: // n%-
return `${strValue}${symbol}${negativeSign}`;
case 7: // -% n
return `${negativeSign}${symbol} ${strValue}`;
case 8: // n %-
return `${strValue} ${symbol}${negativeSign}`;
case 9: // % n-
return `${symbol} ${strValue}${negativeSign}`;
case 10: // % -n
return `${symbol} ${negativeSign}${strValue}`;
case 11: // n- %
return `${strValue}${negativeSign} ${symbol}`;
default: // -n %
return `${negativeSign}${strValue} ${symbol}`;
}
}
/**
* Formats the number a negative value
*
* @private
* @param {string} strValue
* @param {GlobalizationHelper} globalizationInfo
* @return {*} {string}
* @memberof BaseNumericStringFormatter
*/
private FormatNumberToNegativeValue(
strValue: string,
globalizationInfo: GlobalizationHelper
): string {
const negativeSign = globalizationInfo?.NumberFormat?.NegativeSign ?? '-';
switch (globalizationInfo?.NumberFormat?.NumberNegativePattern) {
case 0: // (n)
return `(${strValue})`;
case 1: // -n
return `${negativeSign}${strValue}`;
case 2: // - n
return `${negativeSign} ${strValue}`;
case 3: // n-
return `${strValue}${negativeSign}`;
case 4: // n -
return `${strValue} ${negativeSign}`;
default: // (n)
return `(${strValue})`;
}
}
}