support changing numeral system
This commit is contained in:
+2
-1
@@ -951,10 +951,11 @@ func printUserInfo(user *models.User) {
|
|||||||
fmt.Printf("[LongTimeFormat] %s (%d)\n", user.LongTimeFormat, user.LongTimeFormat)
|
fmt.Printf("[LongTimeFormat] %s (%d)\n", user.LongTimeFormat, user.LongTimeFormat)
|
||||||
fmt.Printf("[ShortTimeFormat] %s (%d)\n", user.ShortTimeFormat, user.ShortTimeFormat)
|
fmt.Printf("[ShortTimeFormat] %s (%d)\n", user.ShortTimeFormat, user.ShortTimeFormat)
|
||||||
fmt.Printf("[FiscalYearFormat] %s (%d)\n", user.FiscalYearFormat, user.FiscalYearFormat)
|
fmt.Printf("[FiscalYearFormat] %s (%d)\n", user.FiscalYearFormat, user.FiscalYearFormat)
|
||||||
|
fmt.Printf("[CurrencyDisplayType] %s (%d)\n", user.CurrencyDisplayType, user.CurrencyDisplayType)
|
||||||
|
fmt.Printf("[NumeralSystem] %s (%d)\n", user.NumeralSystem, user.NumeralSystem)
|
||||||
fmt.Printf("[DecimalSeparator] %s (%d)\n", user.DecimalSeparator, user.DecimalSeparator)
|
fmt.Printf("[DecimalSeparator] %s (%d)\n", user.DecimalSeparator, user.DecimalSeparator)
|
||||||
fmt.Printf("[DigitGroupingSymbol] %s (%d)\n", user.DigitGroupingSymbol, user.DigitGroupingSymbol)
|
fmt.Printf("[DigitGroupingSymbol] %s (%d)\n", user.DigitGroupingSymbol, user.DigitGroupingSymbol)
|
||||||
fmt.Printf("[DigitGrouping] %s (%d)\n", user.DigitGrouping, user.DigitGrouping)
|
fmt.Printf("[DigitGrouping] %s (%d)\n", user.DigitGrouping, user.DigitGrouping)
|
||||||
fmt.Printf("[CurrencyDisplayType] %s (%d)\n", user.CurrencyDisplayType, user.CurrencyDisplayType)
|
|
||||||
fmt.Printf("[CoordinateDisplayType] %s (%d)\n", user.CoordinateDisplayType, user.CoordinateDisplayType)
|
fmt.Printf("[CoordinateDisplayType] %s (%d)\n", user.CoordinateDisplayType, user.CoordinateDisplayType)
|
||||||
fmt.Printf("[ExpenseAmountColor] %s (%d)\n", user.ExpenseAmountColor, user.ExpenseAmountColor)
|
fmt.Printf("[ExpenseAmountColor] %s (%d)\n", user.ExpenseAmountColor, user.ExpenseAmountColor)
|
||||||
fmt.Printf("[IncomeAmountColor] %s (%d)\n", user.IncomeAmountColor, user.IncomeAmountColor)
|
fmt.Printf("[IncomeAmountColor] %s (%d)\n", user.IncomeAmountColor, user.IncomeAmountColor)
|
||||||
|
|||||||
+18
-9
@@ -404,6 +404,24 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
|
|||||||
userNew.FiscalYearFormat = core.FISCAL_YEAR_FORMAT_INVALID
|
userNew.FiscalYearFormat = core.FISCAL_YEAR_FORMAT_INVALID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if userUpdateReq.CurrencyDisplayType != nil && *userUpdateReq.CurrencyDisplayType != user.CurrencyDisplayType {
|
||||||
|
user.CurrencyDisplayType = *userUpdateReq.CurrencyDisplayType
|
||||||
|
userNew.CurrencyDisplayType = *userUpdateReq.CurrencyDisplayType
|
||||||
|
modifyProfileBasicInfo = true
|
||||||
|
anythingUpdate = true
|
||||||
|
} else {
|
||||||
|
userNew.CurrencyDisplayType = core.CURRENCY_DISPLAY_TYPE_INVALID
|
||||||
|
}
|
||||||
|
|
||||||
|
if userUpdateReq.NumeralSystem != nil && *userUpdateReq.NumeralSystem != user.NumeralSystem {
|
||||||
|
user.NumeralSystem = *userUpdateReq.NumeralSystem
|
||||||
|
userNew.NumeralSystem = *userUpdateReq.NumeralSystem
|
||||||
|
modifyProfileBasicInfo = true
|
||||||
|
anythingUpdate = true
|
||||||
|
} else {
|
||||||
|
userNew.NumeralSystem = core.NUMERAL_SYSTEM_INVALID
|
||||||
|
}
|
||||||
|
|
||||||
if userUpdateReq.DecimalSeparator != nil && *userUpdateReq.DecimalSeparator != user.DecimalSeparator {
|
if userUpdateReq.DecimalSeparator != nil && *userUpdateReq.DecimalSeparator != user.DecimalSeparator {
|
||||||
user.DecimalSeparator = *userUpdateReq.DecimalSeparator
|
user.DecimalSeparator = *userUpdateReq.DecimalSeparator
|
||||||
userNew.DecimalSeparator = *userUpdateReq.DecimalSeparator
|
userNew.DecimalSeparator = *userUpdateReq.DecimalSeparator
|
||||||
@@ -431,15 +449,6 @@ func (a *UsersApi) UserUpdateProfileHandler(c *core.WebContext) (any, *errs.Erro
|
|||||||
userNew.DigitGrouping = core.DIGIT_GROUPING_TYPE_INVALID
|
userNew.DigitGrouping = core.DIGIT_GROUPING_TYPE_INVALID
|
||||||
}
|
}
|
||||||
|
|
||||||
if userUpdateReq.CurrencyDisplayType != nil && *userUpdateReq.CurrencyDisplayType != user.CurrencyDisplayType {
|
|
||||||
user.CurrencyDisplayType = *userUpdateReq.CurrencyDisplayType
|
|
||||||
userNew.CurrencyDisplayType = *userUpdateReq.CurrencyDisplayType
|
|
||||||
modifyProfileBasicInfo = true
|
|
||||||
anythingUpdate = true
|
|
||||||
} else {
|
|
||||||
userNew.CurrencyDisplayType = core.CURRENCY_DISPLAY_TYPE_INVALID
|
|
||||||
}
|
|
||||||
|
|
||||||
if userUpdateReq.CoordinateDisplayType != nil && *userUpdateReq.CoordinateDisplayType != user.CoordinateDisplayType {
|
if userUpdateReq.CoordinateDisplayType != nil && *userUpdateReq.CoordinateDisplayType != user.CoordinateDisplayType {
|
||||||
user.CoordinateDisplayType = *userUpdateReq.CoordinateDisplayType
|
user.CoordinateDisplayType = *userUpdateReq.CoordinateDisplayType
|
||||||
userNew.CoordinateDisplayType = *userUpdateReq.CoordinateDisplayType
|
userNew.CoordinateDisplayType = *userUpdateReq.CoordinateDisplayType
|
||||||
|
|||||||
@@ -4,6 +4,40 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NumeralSystem represents the type of numeral system
|
||||||
|
type NumeralSystem byte
|
||||||
|
|
||||||
|
// Numeral System
|
||||||
|
const (
|
||||||
|
NUMERAL_SYSTEM_DEFAULT NumeralSystem = 0
|
||||||
|
NUMERAL_SYSTEM_WESTERN_ARABIC_NUMERALS NumeralSystem = 1
|
||||||
|
NUMERAL_SYSTEM_EASTERN_ARABIC_NUMERALS NumeralSystem = 2
|
||||||
|
NUMERAL_SYSTEM_PERSIAN_DIGITS NumeralSystem = 3
|
||||||
|
NUMERAL_SYSTEM_BURMESE_NUMERALS NumeralSystem = 4
|
||||||
|
NUMERAL_SYSTEM_DEVANAGARI_NUMERALS NumeralSystem = 5
|
||||||
|
NUMERAL_SYSTEM_INVALID NumeralSystem = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns a textual representation of the decimal separator enum
|
||||||
|
func (f NumeralSystem) String() string {
|
||||||
|
switch f {
|
||||||
|
case NUMERAL_SYSTEM_DEFAULT:
|
||||||
|
return "Default"
|
||||||
|
case NUMERAL_SYSTEM_WESTERN_ARABIC_NUMERALS:
|
||||||
|
return "Western Arabic Numerals"
|
||||||
|
case NUMERAL_SYSTEM_EASTERN_ARABIC_NUMERALS:
|
||||||
|
return "Eastern Arabic Numerals"
|
||||||
|
case NUMERAL_SYSTEM_PERSIAN_DIGITS:
|
||||||
|
return "Persian Digits"
|
||||||
|
case NUMERAL_SYSTEM_BURMESE_NUMERALS:
|
||||||
|
return "Burmese Numerals"
|
||||||
|
case NUMERAL_SYSTEM_DEVANAGARI_NUMERALS:
|
||||||
|
return "Devanagari Numerals"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("Invalid(%d)", int(f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DecimalSeparator represents the type of decimal separator
|
// DecimalSeparator represents the type of decimal separator
|
||||||
type DecimalSeparator byte
|
type DecimalSeparator byte
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -100,10 +100,11 @@ type User struct {
|
|||||||
LongTimeFormat core.LongTimeFormat `xorm:"TINYINT"`
|
LongTimeFormat core.LongTimeFormat `xorm:"TINYINT"`
|
||||||
ShortTimeFormat core.ShortTimeFormat `xorm:"TINYINT"`
|
ShortTimeFormat core.ShortTimeFormat `xorm:"TINYINT"`
|
||||||
FiscalYearFormat core.FiscalYearFormat `xorm:"TINYINT"`
|
FiscalYearFormat core.FiscalYearFormat `xorm:"TINYINT"`
|
||||||
|
CurrencyDisplayType core.CurrencyDisplayType `xorm:"TINYINT"`
|
||||||
|
NumeralSystem core.NumeralSystem `xorm:"TINYINT"`
|
||||||
DecimalSeparator core.DecimalSeparator `xorm:"TINYINT"`
|
DecimalSeparator core.DecimalSeparator `xorm:"TINYINT"`
|
||||||
DigitGroupingSymbol core.DigitGroupingSymbol `xorm:"TINYINT"`
|
DigitGroupingSymbol core.DigitGroupingSymbol `xorm:"TINYINT"`
|
||||||
DigitGrouping core.DigitGroupingType `xorm:"TINYINT"`
|
DigitGrouping core.DigitGroupingType `xorm:"TINYINT"`
|
||||||
CurrencyDisplayType core.CurrencyDisplayType `xorm:"TINYINT"`
|
|
||||||
CoordinateDisplayType core.CoordinateDisplayType `xorm:"TINYINT"`
|
CoordinateDisplayType core.CoordinateDisplayType `xorm:"TINYINT"`
|
||||||
ExpenseAmountColor AmountColorType `xorm:"TINYINT"`
|
ExpenseAmountColor AmountColorType `xorm:"TINYINT"`
|
||||||
IncomeAmountColor AmountColorType `xorm:"TINYINT"`
|
IncomeAmountColor AmountColorType `xorm:"TINYINT"`
|
||||||
@@ -135,10 +136,11 @@ type UserBasicInfo struct {
|
|||||||
LongTimeFormat core.LongTimeFormat `json:"longTimeFormat"`
|
LongTimeFormat core.LongTimeFormat `json:"longTimeFormat"`
|
||||||
ShortTimeFormat core.ShortTimeFormat `json:"shortTimeFormat"`
|
ShortTimeFormat core.ShortTimeFormat `json:"shortTimeFormat"`
|
||||||
FiscalYearFormat core.FiscalYearFormat `json:"fiscalYearFormat"`
|
FiscalYearFormat core.FiscalYearFormat `json:"fiscalYearFormat"`
|
||||||
|
CurrencyDisplayType core.CurrencyDisplayType `json:"currencyDisplayType"`
|
||||||
|
NumeralSystem core.NumeralSystem `json:"numeralSystem"`
|
||||||
DecimalSeparator core.DecimalSeparator `json:"decimalSeparator"`
|
DecimalSeparator core.DecimalSeparator `json:"decimalSeparator"`
|
||||||
DigitGroupingSymbol core.DigitGroupingSymbol `json:"digitGroupingSymbol"`
|
DigitGroupingSymbol core.DigitGroupingSymbol `json:"digitGroupingSymbol"`
|
||||||
DigitGrouping core.DigitGroupingType `json:"digitGrouping"`
|
DigitGrouping core.DigitGroupingType `json:"digitGrouping"`
|
||||||
CurrencyDisplayType core.CurrencyDisplayType `json:"currencyDisplayType"`
|
|
||||||
CoordinateDisplayType core.CoordinateDisplayType `json:"coordinateDisplayType"`
|
CoordinateDisplayType core.CoordinateDisplayType `json:"coordinateDisplayType"`
|
||||||
ExpenseAmountColor AmountColorType `json:"expenseAmountColor"`
|
ExpenseAmountColor AmountColorType `json:"expenseAmountColor"`
|
||||||
IncomeAmountColor AmountColorType `json:"incomeAmountColor"`
|
IncomeAmountColor AmountColorType `json:"incomeAmountColor"`
|
||||||
@@ -198,10 +200,11 @@ type UserProfileUpdateRequest struct {
|
|||||||
LongTimeFormat *core.LongTimeFormat `json:"longTimeFormat" binding:"omitempty,min=0,max=3"`
|
LongTimeFormat *core.LongTimeFormat `json:"longTimeFormat" binding:"omitempty,min=0,max=3"`
|
||||||
ShortTimeFormat *core.ShortTimeFormat `json:"shortTimeFormat" binding:"omitempty,min=0,max=3"`
|
ShortTimeFormat *core.ShortTimeFormat `json:"shortTimeFormat" binding:"omitempty,min=0,max=3"`
|
||||||
FiscalYearFormat *core.FiscalYearFormat `json:"fiscalYearFormat" binding:"omitempty,min=0,max=5"`
|
FiscalYearFormat *core.FiscalYearFormat `json:"fiscalYearFormat" binding:"omitempty,min=0,max=5"`
|
||||||
|
CurrencyDisplayType *core.CurrencyDisplayType `json:"currencyDisplayType" binding:"omitempty,min=0,max=11"`
|
||||||
|
NumeralSystem *core.NumeralSystem `json:"numeralSystem" binding:"omitempty,min=0,max=5"`
|
||||||
DecimalSeparator *core.DecimalSeparator `json:"decimalSeparator" binding:"omitempty,min=0,max=3"`
|
DecimalSeparator *core.DecimalSeparator `json:"decimalSeparator" binding:"omitempty,min=0,max=3"`
|
||||||
DigitGroupingSymbol *core.DigitGroupingSymbol `json:"digitGroupingSymbol" binding:"omitempty,min=0,max=4"`
|
DigitGroupingSymbol *core.DigitGroupingSymbol `json:"digitGroupingSymbol" binding:"omitempty,min=0,max=4"`
|
||||||
DigitGrouping *core.DigitGroupingType `json:"digitGrouping" binding:"omitempty,min=0,max=3"`
|
DigitGrouping *core.DigitGroupingType `json:"digitGrouping" binding:"omitempty,min=0,max=3"`
|
||||||
CurrencyDisplayType *core.CurrencyDisplayType `json:"currencyDisplayType" binding:"omitempty,min=0,max=11"`
|
|
||||||
CoordinateDisplayType *core.CoordinateDisplayType `json:"coordinateDisplayType" binding:"omitempty,min=0,max=6"`
|
CoordinateDisplayType *core.CoordinateDisplayType `json:"coordinateDisplayType" binding:"omitempty,min=0,max=6"`
|
||||||
ExpenseAmountColor *AmountColorType `json:"expenseAmountColor" binding:"omitempty,min=0,max=4"`
|
ExpenseAmountColor *AmountColorType `json:"expenseAmountColor" binding:"omitempty,min=0,max=4"`
|
||||||
IncomeAmountColor *AmountColorType `json:"incomeAmountColor" binding:"omitempty,min=0,max=4"`
|
IncomeAmountColor *AmountColorType `json:"incomeAmountColor" binding:"omitempty,min=0,max=4"`
|
||||||
@@ -287,9 +290,10 @@ func (u *User) ToUserBasicInfo(avatarProvider core.UserAvatarProviderType, avata
|
|||||||
ShortTimeFormat: u.ShortTimeFormat,
|
ShortTimeFormat: u.ShortTimeFormat,
|
||||||
DecimalSeparator: u.DecimalSeparator,
|
DecimalSeparator: u.DecimalSeparator,
|
||||||
FiscalYearFormat: u.FiscalYearFormat,
|
FiscalYearFormat: u.FiscalYearFormat,
|
||||||
|
CurrencyDisplayType: u.CurrencyDisplayType,
|
||||||
|
NumeralSystem: u.NumeralSystem,
|
||||||
DigitGroupingSymbol: u.DigitGroupingSymbol,
|
DigitGroupingSymbol: u.DigitGroupingSymbol,
|
||||||
DigitGrouping: u.DigitGrouping,
|
DigitGrouping: u.DigitGrouping,
|
||||||
CurrencyDisplayType: u.CurrencyDisplayType,
|
|
||||||
CoordinateDisplayType: u.CoordinateDisplayType,
|
CoordinateDisplayType: u.CoordinateDisplayType,
|
||||||
ExpenseAmountColor: u.ExpenseAmountColor,
|
ExpenseAmountColor: u.ExpenseAmountColor,
|
||||||
IncomeAmountColor: u.IncomeAmountColor,
|
IncomeAmountColor: u.IncomeAmountColor,
|
||||||
|
|||||||
@@ -313,6 +313,14 @@ func (s *UserService) UpdateUser(c core.Context, user *models.User, modifyUserLa
|
|||||||
updateCols = append(updateCols, "fiscal_year_format")
|
updateCols = append(updateCols, "fiscal_year_format")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if core.CURRENCY_DISPLAY_TYPE_DEFAULT <= user.CurrencyDisplayType && user.CurrencyDisplayType <= core.CURRENCY_DISPLAY_TYPE_NAME_AFTER_AMOUNT {
|
||||||
|
updateCols = append(updateCols, "currency_display_type")
|
||||||
|
}
|
||||||
|
|
||||||
|
if core.NUMERAL_SYSTEM_DEFAULT <= user.NumeralSystem && user.NumeralSystem <= core.NUMERAL_SYSTEM_DEVANAGARI_NUMERALS {
|
||||||
|
updateCols = append(updateCols, "numeral_system")
|
||||||
|
}
|
||||||
|
|
||||||
if core.DECIMAL_SEPARATOR_DEFAULT <= user.DecimalSeparator && user.DecimalSeparator <= core.DECIMAL_SEPARATOR_COMMA {
|
if core.DECIMAL_SEPARATOR_DEFAULT <= user.DecimalSeparator && user.DecimalSeparator <= core.DECIMAL_SEPARATOR_COMMA {
|
||||||
updateCols = append(updateCols, "decimal_separator")
|
updateCols = append(updateCols, "decimal_separator")
|
||||||
}
|
}
|
||||||
@@ -325,10 +333,6 @@ func (s *UserService) UpdateUser(c core.Context, user *models.User, modifyUserLa
|
|||||||
updateCols = append(updateCols, "digit_grouping")
|
updateCols = append(updateCols, "digit_grouping")
|
||||||
}
|
}
|
||||||
|
|
||||||
if core.CURRENCY_DISPLAY_TYPE_DEFAULT <= user.CurrencyDisplayType && user.CurrencyDisplayType <= core.CURRENCY_DISPLAY_TYPE_NAME_AFTER_AMOUNT {
|
|
||||||
updateCols = append(updateCols, "currency_display_type")
|
|
||||||
}
|
|
||||||
|
|
||||||
if core.COORDINATE_DISPLAY_TYPE_DEFAULT <= user.CoordinateDisplayType && user.CoordinateDisplayType <= core.COORDINATE_DISPLAY_TYPE_LONGITUDE_LATITUDE_DEGREES_MINUTES_SECONDS {
|
if core.COORDINATE_DISPLAY_TYPE_DEFAULT <= user.CoordinateDisplayType && user.CoordinateDisplayType <= core.COORDINATE_DISPLAY_TYPE_LONGITUDE_LATITUDE_DEGREES_MINUTES_SECONDS {
|
||||||
updateCols = append(updateCols, "coordinate_display_type")
|
updateCols = append(updateCols, "coordinate_display_type")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { ref } from 'vue';
|
|||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
|
||||||
import { removeAll } from '@/lib/common.ts';
|
import { removeAll } from '@/lib/common.ts';
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
|
|
||||||
@@ -19,6 +21,7 @@ export type GetValidFormattedValueFunction = (value: number, textualValue: strin
|
|||||||
|
|
||||||
export function useCommonNumberInputBase(props: CommonNumberInputProps, maxDecimalCount: number, initValue: string, parseNumber: ParseNumberFunction, formatNumber: FormatNumberFunction, getValidFormattedValue: GetValidFormattedValueFunction) {
|
export function useCommonNumberInputBase(props: CommonNumberInputProps, maxDecimalCount: number, initValue: string, parseNumber: ParseNumberFunction, formatNumber: FormatNumberFunction, getValidFormattedValue: GetValidFormattedValueFunction) {
|
||||||
const {
|
const {
|
||||||
|
getCurrentNumeralSystemType,
|
||||||
getCurrentDecimalSeparator,
|
getCurrentDecimalSeparator,
|
||||||
getCurrentDigitGroupingSymbol
|
getCurrentDigitGroupingSymbol
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
@@ -38,10 +41,11 @@ export function useCommonNumberInputBase(props: CommonNumberInputProps, maxDecim
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const digitGroupingSymbol = getCurrentDigitGroupingSymbol();
|
const digitGroupingSymbol = getCurrentDigitGroupingSymbol();
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
|
|
||||||
if (!('0' <= e.key && e.key <= '9') && e.key !== '-' && e.key !== decimalSeparator) {
|
if (!NumeralSystem.WesternArabicNumerals.isDigit(e.key) && !numeralSystem.isDigit(e.key) && e.key !== '-' && e.key !== decimalSeparator) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -86,7 +90,7 @@ export function useCommonNumberInputBase(props: CommonNumberInputProps, maxDecim
|
|||||||
str = str.substring(1);
|
str = str.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
str = (negative ? '-0' : '0') + str;
|
str = (negative ? `-${numeralSystem.digitZero}` : numeralSystem.digitZero) + str;
|
||||||
target.value = str;
|
target.value = str;
|
||||||
currentValue.value = target.value;
|
currentValue.value = target.value;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -98,14 +102,14 @@ export function useCommonNumberInputBase(props: CommonNumberInputProps, maxDecim
|
|||||||
|
|
||||||
if (decimalIndex >= 0) {
|
if (decimalIndex >= 0) {
|
||||||
decimalLength = str.length - str.indexOf(decimalSeparator) - 1;
|
decimalLength = str.length - str.indexOf(decimalSeparator) - 1;
|
||||||
} else if ((str.startsWith('0') && str.length >= 2) || (str.startsWith('-0') && str.length >= 3)) {
|
} else if ((str.startsWith(numeralSystem.digitZero) && str.length >= 2) || (str.startsWith(`-${numeralSystem.digitZero}`) && str.length >= 3)) {
|
||||||
const negative = str.charAt(0) === '-';
|
const negative = str.charAt(0) === '-';
|
||||||
|
|
||||||
if (negative) {
|
if (negative) {
|
||||||
str = str.substring(1);
|
str = str.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (str.charAt(0) === '0' && (str.length >= 2 || e.key !== '0')) {
|
while (str.charAt(0) === numeralSystem.digitZero && (str.length >= 2 || e.key !== numeralSystem.digitZero)) {
|
||||||
str = str.substring(1);
|
str = str.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +142,7 @@ export function useCommonNumberInputBase(props: CommonNumberInputProps, maxDecim
|
|||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
logger.warn('cannot parse input number, original value is ' + str, ex);
|
logger.warn('cannot parse input number, original value is ' + str, ex);
|
||||||
target.value = '0';
|
target.value = numeralSystem.digitZero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
|||||||
import { type CommonNumberInputProps, useCommonNumberInputBase } from '@/components/base/CommonNumberInputBase.ts';
|
import { type CommonNumberInputProps, useCommonNumberInputBase } from '@/components/base/CommonNumberInputBase.ts';
|
||||||
|
|
||||||
import { isNumber, replaceAll, removeAll } from '@/lib/common.ts';
|
import { isNumber, replaceAll, removeAll } from '@/lib/common.ts';
|
||||||
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
|
||||||
export interface NumberInputProps extends CommonNumberInputProps {
|
export interface NumberInputProps extends CommonNumberInputProps {
|
||||||
minValue?: number;
|
minValue?: number;
|
||||||
@@ -17,6 +18,7 @@ export interface NumberInputEmits {
|
|||||||
|
|
||||||
export function useNumberInputBase(props: NumberInputProps, emit: NumberInputEmits) {
|
export function useNumberInputBase(props: NumberInputProps, emit: NumberInputEmits) {
|
||||||
const {
|
const {
|
||||||
|
getCurrentNumeralSystemType,
|
||||||
getCurrentDecimalSeparator,
|
getCurrentDecimalSeparator,
|
||||||
getCurrentDigitGroupingSymbol
|
getCurrentDigitGroupingSymbol
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
@@ -32,17 +34,20 @@ export function useNumberInputBase(props: NumberInputProps, emit: NumberInputEmi
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
|
|
||||||
let finalValue = '';
|
let finalValue = '';
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
if (!('0' <= value[i] && value[i] <= '9') && value[i] !== '-' && value[i] !== decimalSeparator) {
|
if (!NumeralSystem.WesternArabicNumerals.isDigit(value[i]) && !numeralSystem.isDigit(value[i]) && value[i] !== '-' && value[i] !== decimalSeparator) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalValue += value[i];
|
finalValue += value[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalValue = numeralSystem.replaceLocalizedDigitsToWesternArabicDigits(finalValue);
|
||||||
|
|
||||||
if (decimalSeparator !== '.') {
|
if (decimalSeparator !== '.') {
|
||||||
finalValue = replaceAll(finalValue, decimalSeparator, '.');
|
finalValue = replaceAll(finalValue, decimalSeparator, '.');
|
||||||
}
|
}
|
||||||
@@ -65,50 +70,72 @@ export function useNumberInputBase(props: NumberInputProps, emit: NumberInputEmi
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedValue(value: number): string {
|
function getFormattedValue(value: number): string {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
|
||||||
if (!Number.isNaN(value) && Number.isFinite(value)) {
|
if (!Number.isNaN(value) && Number.isFinite(value)) {
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
|
|
||||||
if (isNumber(props.maxDecimalCount) && props.maxDecimalCount >= 0) {
|
if (isNumber(props.maxDecimalCount) && props.maxDecimalCount >= 0) {
|
||||||
return replaceAll(value.toFixed(props.maxDecimalCount), '.', decimalSeparator);
|
return replaceAll(numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(value.toFixed(props.maxDecimalCount)), '.', decimalSeparator);
|
||||||
} else {
|
} else {
|
||||||
return replaceAll(value.toString(), '.', decimalSeparator);
|
return replaceAll(numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(value.toString(10)), '.', decimalSeparator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return '0';
|
return numeralSystem.digitZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.modelValue, (newValue) => {
|
watch(() => props.modelValue, (newValue) => {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const numericCurrentValue = parseNumber(currentValue.value);
|
const numericCurrentValue = parseNumber(currentValue.value);
|
||||||
|
|
||||||
if (newValue !== numericCurrentValue) {
|
if (newValue !== numericCurrentValue) {
|
||||||
const newStringValue = getFormattedValue(newValue);
|
const newStringValue = getFormattedValue(newValue);
|
||||||
|
|
||||||
if (!(newStringValue === '0' && currentValue.value === '')) {
|
if (!(newStringValue === numeralSystem.digitZero && currentValue.value === '')) {
|
||||||
currentValue.value = newStringValue;
|
currentValue.value = newStringValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(currentValue, (newValue) => {
|
watch(currentValue, (newValue) => {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
let actualNumeralSystem: NumeralSystem | undefined = undefined;
|
||||||
let finalValue = '';
|
let finalValue = '';
|
||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
|
|
||||||
for (let i = 0; i < newValue.length; i++) {
|
if (newValue[0] === '-' || newValue[0] === decimalSeparator) {
|
||||||
if (!('0' <= newValue[i] && newValue[i] <= '9') && newValue[i] !== '-' && newValue[i] !== decimalSeparator) {
|
actualNumeralSystem = NumeralSystem.detect(newValue[1]);
|
||||||
break;
|
} else {
|
||||||
|
actualNumeralSystem = NumeralSystem.detect(newValue[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actualNumeralSystem && (actualNumeralSystem.type === NumeralSystem.WesternArabicNumerals.type || actualNumeralSystem.type === numeralSystem.type)) {
|
||||||
|
for (let i = 0; i < newValue.length; i++) {
|
||||||
|
if (!NumeralSystem.WesternArabicNumerals.isDigit(newValue[i]) && !numeralSystem.isDigit(newValue[i]) && newValue[i] !== '-' && newValue[i] !== decimalSeparator) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalValue += newValue[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
finalValue += newValue[i];
|
finalValue = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(finalValue);
|
||||||
|
} else if (newValue === '-' || newValue === decimalSeparator || newValue === `-${decimalSeparator}`) {
|
||||||
|
finalValue = newValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalValue !== newValue) {
|
if (finalValue !== newValue) {
|
||||||
currentValue.value = finalValue;
|
currentValue.value = finalValue;
|
||||||
} else {
|
} else {
|
||||||
const value: number = parseNumber(finalValue);
|
let value: number = parseNumber(finalValue);
|
||||||
|
|
||||||
|
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
emit('update:modelValue', value);
|
emit('update:modelValue', value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export interface CommonPieChartProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function usePieChartBase(props: CommonPieChartProps) {
|
export function usePieChartBase(props: CommonPieChartProps) {
|
||||||
const { formatAmountWithCurrency, formatPercent } = useI18n();
|
const { formatAmountToLocalizedNumeralsWithCurrency, formatPercentToLocalizedNumerals } = useI18n();
|
||||||
|
|
||||||
const selectedIndex = ref<number>(0);
|
const selectedIndex = ref<number>(0);
|
||||||
|
|
||||||
@@ -72,8 +72,8 @@ export function usePieChartBase(props: CommonPieChartProps) {
|
|||||||
sourceItem: item
|
sourceItem: item
|
||||||
};
|
};
|
||||||
|
|
||||||
finalItem.displayPercent = formatPercent(finalItem.percent, 2, '<0.01');
|
finalItem.displayPercent = formatPercentToLocalizedNumerals(finalItem.percent, 2, '<0.01');
|
||||||
finalItem.displayValue = formatAmountWithCurrency(finalItem.value, props.defaultCurrency);
|
finalItem.displayValue = formatAmountToLocalizedNumeralsWithCurrency(finalItem.value, props.defaultCurrency);
|
||||||
|
|
||||||
validItems.push(finalItem);
|
validItems.push(finalItem);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, useTemplateRef } from 'vue';
|
import { ref, computed, watch, useTemplateRef } from 'vue';
|
||||||
|
|
||||||
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
|
||||||
interface PinCode {
|
interface PinCode {
|
||||||
value: string;
|
value: string;
|
||||||
inputType: string;
|
inputType: string;
|
||||||
@@ -42,6 +46,8 @@ const emit = defineEmits<{
|
|||||||
(e: 'pincode:confirm', value: string): void;
|
(e: 'pincode:confirm', value: string): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const { getCurrentNumeralSystemType } = useI18n();
|
||||||
|
|
||||||
const codes = ref<PinCode[]>([]);
|
const codes = ref<PinCode[]>([]);
|
||||||
const pinCodeInputs = useTemplateRef<HTMLInputElement[]>('pin-code-input');
|
const pinCodeInputs = useTemplateRef<HTMLInputElement[]>('pin-code-input');
|
||||||
|
|
||||||
@@ -148,6 +154,8 @@ function setNextFocus(index: number): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onKeydown(index: number, event: KeyboardEvent): void {
|
function onKeydown(index: number, event: KeyboardEvent): void {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
|
||||||
if (event.altKey || (event.key.indexOf('F') === 0 && (event.key.length === 2 || event.key.length === 3))) {
|
if (event.altKey || (event.key.indexOf('F') === 0 && (event.key.length === 2 || event.key.length === 3))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -208,13 +216,23 @@ function onKeydown(index: number, event: KeyboardEvent): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key.length === 1 && '0' <= event.key && event.key <= '9') {
|
if (event.key.length === 1) {
|
||||||
codes.value[index].value = event.key;
|
let digit = '';
|
||||||
setInputType(index);
|
|
||||||
setNextFocus(index);
|
|
||||||
|
|
||||||
if (props.autoConfirm && finalPinCode.value.length === props.length) {
|
if (NumeralSystem.WesternArabicNumerals.isDigit(event.key)) {
|
||||||
emit('pincode:confirm', finalPinCode.value);
|
digit = event.key;
|
||||||
|
} else if (numeralSystem.isDigit(event.key)) {
|
||||||
|
digit = numeralSystem.replaceLocalizedDigitsToWesternArabicDigits(event.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (digit) {
|
||||||
|
codes.value[index].value = digit;
|
||||||
|
setInputType(index);
|
||||||
|
setNextFocus(index);
|
||||||
|
|
||||||
|
if (props.autoConfirm && finalPinCode.value.length === props.length) {
|
||||||
|
emit('pincode:confirm', finalPinCode.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ interface AccountBalanceTrendsChartDataItem {
|
|||||||
const props = defineProps<DesktopAccountBalanceTrendsChartProps>();
|
const props = defineProps<DesktopAccountBalanceTrendsChartProps>();
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { tt, formatAmountWithCurrency } = useI18n();
|
const { tt, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
const { allDataItems, allDisplayDateRanges } = useAccountBalanceTrendsChartBase(props);
|
const { allDataItems, allDisplayDateRanges } = useAccountBalanceTrendsChartBase(props);
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -129,8 +129,8 @@ const yAxisWidth = computed<number>(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxValueText = formatAmountWithCurrency(maxValue, props.account.currency);
|
const maxValueText = formatAmountToLocalizedNumeralsWithCurrency(maxValue, props.account.currency);
|
||||||
const minValueText = formatAmountWithCurrency(minValue, props.account.currency);
|
const minValueText = formatAmountToLocalizedNumeralsWithCurrency(minValue, props.account.currency);
|
||||||
const maxLengthText = maxValueText.length > minValueText.length ? maxValueText : minValueText;
|
const maxLengthText = maxValueText.length > minValueText.length ? maxValueText : minValueText;
|
||||||
|
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
@@ -175,27 +175,27 @@ const chartOptions = computed<object>(() => {
|
|||||||
const displayItems: NameValue[] = [
|
const displayItems: NameValue[] = [
|
||||||
{
|
{
|
||||||
name: tt('Opening Balance'),
|
name: tt('Opening Balance'),
|
||||||
value: formatAmountWithCurrency(dataItem.openingBalance, props.account.currency)
|
value: formatAmountToLocalizedNumeralsWithCurrency(dataItem.openingBalance, props.account.currency)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: tt('Closing Balance'),
|
name: tt('Closing Balance'),
|
||||||
value: formatAmountWithCurrency(dataItem.closingBalance, props.account.currency)
|
value: formatAmountToLocalizedNumeralsWithCurrency(dataItem.closingBalance, props.account.currency)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: tt('Minimum Balance'),
|
name: tt('Minimum Balance'),
|
||||||
value: formatAmountWithCurrency(dataItem.minimumBalance, props.account.currency)
|
value: formatAmountToLocalizedNumeralsWithCurrency(dataItem.minimumBalance, props.account.currency)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: tt('Maximum Balance'),
|
name: tt('Maximum Balance'),
|
||||||
value: formatAmountWithCurrency(dataItem.maximumBalance, props.account.currency)
|
value: formatAmountToLocalizedNumeralsWithCurrency(dataItem.maximumBalance, props.account.currency)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: tt('Median Balance'),
|
name: tt('Median Balance'),
|
||||||
value: formatAmountWithCurrency(dataItem.medianBalance, props.account.currency)
|
value: formatAmountToLocalizedNumeralsWithCurrency(dataItem.medianBalance, props.account.currency)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: tt('Average Balance'),
|
name: tt('Average Balance'),
|
||||||
value: formatAmountWithCurrency(dataItem.averageBalance, props.account.currency)
|
value: formatAmountToLocalizedNumeralsWithCurrency(dataItem.averageBalance, props.account.currency)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ const chartOptions = computed<object>(() => {
|
|||||||
return tooltip;
|
return tooltip;
|
||||||
} else {
|
} else {
|
||||||
const amount = params[0].data as number;
|
const amount = params[0].data as number;
|
||||||
const value = formatAmountWithCurrency(amount, props.account.currency);
|
const value = formatAmountToLocalizedNumeralsWithCurrency(amount, props.account.currency);
|
||||||
|
|
||||||
return `${params[0].name}<br/>`
|
return `${params[0].name}<br/>`
|
||||||
+ '<div><span class="chart-pointer" style="background-color: #' + DEFAULT_CHART_COLORS[0] + '"></span>'
|
+ '<div><span class="chart-pointer" style="background-color: #' + DEFAULT_CHART_COLORS[0] + '"></span>'
|
||||||
@@ -234,13 +234,13 @@ const chartOptions = computed<object>(() => {
|
|||||||
type: 'value',
|
type: 'value',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: (value: string) => {
|
formatter: (value: string) => {
|
||||||
return formatAmountWithCurrency(value, props.account.currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(parseInt(value), props.account.currency);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
label: {
|
label: {
|
||||||
formatter: (params: CallbackDataParams) => {
|
formatter: (params: CallbackDataParams) => {
|
||||||
return formatAmountWithCurrency(Math.floor(params.value as number), props.account.currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(Math.floor(params.value as number), props.account.currency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -74,11 +74,11 @@ import { ref, computed, useTemplateRef, watch } from 'vue';
|
|||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
import { type CommonNumberInputProps, useCommonNumberInputBase } from '@/components/base/CommonNumberInputBase.ts';
|
import { type CommonNumberInputProps, useCommonNumberInputBase } from '@/components/base/CommonNumberInputBase.ts';
|
||||||
|
|
||||||
import { DecimalSeparator } from '@/core/numeral.ts';
|
import { NumeralSystem, DecimalSeparator } from '@/core/numeral.ts';
|
||||||
import type { CurrencyPrependAndAppendText } from '@/core/currency.ts';
|
import type { CurrencyPrependAndAppendText } from '@/core/currency.ts';
|
||||||
import { DEFAULT_DECIMAL_NUMBER_COUNT } from '@/consts/numeral.ts';
|
import { DEFAULT_DECIMAL_NUMBER_COUNT } from '@/consts/numeral.ts';
|
||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||||
import { isNumber, replaceAll, removeAll } from '@/lib/common.ts';
|
import { isNumber, replaceAll } from '@/lib/common.ts';
|
||||||
import { evaluateExpression } from '@/lib/evaluator.ts';
|
import { evaluateExpression } from '@/lib/evaluator.ts';
|
||||||
import type { ComponentDensity } from '@/lib/ui/desktop.ts';
|
import type { ComponentDensity } from '@/lib/ui/desktop.ts';
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
@@ -112,11 +112,11 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
tt,
|
tt,
|
||||||
|
getCurrentNumeralSystemType,
|
||||||
getCurrentDecimalSeparator,
|
getCurrentDecimalSeparator,
|
||||||
getCurrentDigitGroupingSymbol,
|
parseAmountFromLocalizedNumerals,
|
||||||
parseAmount,
|
formatAmountToLocalizedNumeralsWithoutDigitGrouping,
|
||||||
formatAmount,
|
formatNumberToLocalizedNumerals,
|
||||||
formatNumber,
|
|
||||||
getAmountPrependAndAppendText
|
getAmountPrependAndAppendText
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ const {
|
|||||||
currentValue,
|
currentValue,
|
||||||
onKeyUpDown,
|
onKeyUpDown,
|
||||||
onPaste
|
onPaste
|
||||||
} = useCommonNumberInputBase(props, DEFAULT_DECIMAL_NUMBER_COUNT, getInitedFormattedValue(props.modelValue, props.flipNegative), parseAmount, getFormattedValue, getValidFormattedValue);
|
} = useCommonNumberInputBase(props, DEFAULT_DECIMAL_NUMBER_COUNT, getInitedFormattedValue(props.modelValue, props.flipNegative), parseAmountFromLocalizedNumerals, getFormattedValue, getValidFormattedValue);
|
||||||
|
|
||||||
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ const rules = [
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const val = parseAmount(v);
|
const val = parseAmountFromLocalizedNumerals(v);
|
||||||
|
|
||||||
if (Number.isNaN(val) || !Number.isFinite(val)) {
|
if (Number.isNaN(val) || !Number.isFinite(val)) {
|
||||||
return tt('Amount value is not number');
|
return tt('Amount value is not number');
|
||||||
@@ -205,6 +205,7 @@ function enterFormulaMode(): void {
|
|||||||
|
|
||||||
function calculateFormula(): void {
|
function calculateFormula(): void {
|
||||||
const systemDecimalSeparator = DecimalSeparator.Dot.symbol;
|
const systemDecimalSeparator = DecimalSeparator.Dot.symbol;
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
let finalFormula = currentFormula.value;
|
let finalFormula = currentFormula.value;
|
||||||
|
|
||||||
@@ -215,12 +216,13 @@ function calculateFormula(): void {
|
|||||||
finalFormula = replaceAll(currentFormula.value, decimalSeparator, systemDecimalSeparator);
|
finalFormula = replaceAll(currentFormula.value, decimalSeparator, systemDecimalSeparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalFormula = numeralSystem.replaceLocalizedDigitsToWesternArabicDigits(finalFormula);
|
||||||
const calculatedValue = evaluateExpression(finalFormula);
|
const calculatedValue = evaluateExpression(finalFormula);
|
||||||
|
|
||||||
if (isNumber(calculatedValue)) {
|
if (isNumber(calculatedValue)) {
|
||||||
const textualValue = formatNumber(calculatedValue, 2);
|
const textualValue = formatNumberToLocalizedNumerals(calculatedValue, 2);
|
||||||
const hasDecimalSeparator = textualValue.indexOf(decimalSeparator) >= 0;
|
const hasDecimalSeparator = textualValue.indexOf(decimalSeparator) >= 0;
|
||||||
currentValue.value = getValidFormattedValue(calculatedValue, textualValue, hasDecimalSeparator);
|
currentValue.value = getValidFormattedValue(calculatedValue * 100, textualValue, hasDecimalSeparator);
|
||||||
formulaMode.value = false;
|
formulaMode.value = false;
|
||||||
} else {
|
} else {
|
||||||
snackbar.value?.showMessage('Formula is invalid');
|
snackbar.value?.showMessage('Formula is invalid');
|
||||||
@@ -273,33 +275,36 @@ function getInitedFormattedValue(value: number, flipNegative?: boolean): string
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedValue(value: number): string {
|
function getFormattedValue(value: number): string {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
|
||||||
if (!Number.isNaN(value) && Number.isFinite(value)) {
|
if (!Number.isNaN(value) && Number.isFinite(value)) {
|
||||||
const digitGroupingSymbol = getCurrentDigitGroupingSymbol();
|
return formatAmountToLocalizedNumeralsWithoutDigitGrouping(value, props.currency);
|
||||||
return removeAll(formatAmount(value, props.currency), digitGroupingSymbol);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return '0';
|
return numeralSystem.digitZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayCurrencyPrependAndAppendText(): CurrencyPrependAndAppendText | null {
|
function getDisplayCurrencyPrependAndAppendText(): CurrencyPrependAndAppendText | null {
|
||||||
const numericCurrentValue = parseAmount(currentValue.value);
|
const numericCurrentValue = parseAmountFromLocalizedNumerals(currentValue.value);
|
||||||
const isPlural = numericCurrentValue !== 100 && numericCurrentValue !== -100;
|
const isPlural = numericCurrentValue !== 100 && numericCurrentValue !== -100;
|
||||||
|
|
||||||
return getAmountPrependAndAppendText(props.currency, isPlural);
|
return getAmountPrependAndAppendText(props.currency, isPlural);
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(() => props.currency, () => {
|
watch(() => props.currency, () => {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const newStringValue = getInitedFormattedValue(props.modelValue, props.flipNegative);
|
const newStringValue = getInitedFormattedValue(props.modelValue, props.flipNegative);
|
||||||
|
|
||||||
if (!(newStringValue === '0' && currentValue.value === '')) {
|
if (!(newStringValue === numeralSystem.digitZero && currentValue.value === '')) {
|
||||||
currentValue.value = newStringValue;
|
currentValue.value = newStringValue;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => props.flipNegative, (newValue) => {
|
watch(() => props.flipNegative, (newValue) => {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const newStringValue = getInitedFormattedValue(props.modelValue, newValue);
|
const newStringValue = getInitedFormattedValue(props.modelValue, newValue);
|
||||||
|
|
||||||
if (!(newStringValue === '0' && currentValue.value === '')) {
|
if (!(newStringValue === numeralSystem.digitZero && currentValue.value === '')) {
|
||||||
currentValue.value = newStringValue;
|
currentValue.value = newStringValue;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -309,36 +314,55 @@ watch(() => props.modelValue, (newValue) => {
|
|||||||
newValue = -newValue;
|
newValue = -newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numericCurrentValue = parseAmount(currentValue.value);
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
const numericCurrentValue = parseAmountFromLocalizedNumerals(currentValue.value);
|
||||||
|
|
||||||
if (newValue !== numericCurrentValue) {
|
if (newValue !== numericCurrentValue) {
|
||||||
const newStringValue = getFormattedValue(newValue);
|
const newStringValue = getFormattedValue(newValue);
|
||||||
|
|
||||||
if (!(newStringValue === '0' && currentValue.value === '')) {
|
if (!(newStringValue === numeralSystem.digitZero && currentValue.value === '')) {
|
||||||
currentValue.value = newStringValue;
|
currentValue.value = newStringValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(currentValue, (newValue) => {
|
watch(currentValue, (newValue) => {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
let actualNumeralSystem: NumeralSystem | undefined = undefined;
|
||||||
let finalValue = '';
|
let finalValue = '';
|
||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
|
|
||||||
for (let i = 0; i < newValue.length; i++) {
|
if (newValue[0] === '-' || newValue[0] === decimalSeparator) {
|
||||||
if (!('0' <= newValue[i] && newValue[i] <= '9') && newValue[i] !== '-' && newValue[i] !== decimalSeparator) {
|
actualNumeralSystem = NumeralSystem.detect(newValue[1]);
|
||||||
break;
|
} else {
|
||||||
|
actualNumeralSystem = NumeralSystem.detect(newValue[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actualNumeralSystem && (actualNumeralSystem.type === NumeralSystem.WesternArabicNumerals.type || actualNumeralSystem.type === numeralSystem.type)) {
|
||||||
|
for (let i = 0; i < newValue.length; i++) {
|
||||||
|
if (!NumeralSystem.WesternArabicNumerals.isDigit(newValue[i]) && !numeralSystem.isDigit(newValue[i]) && newValue[i] !== '-' && newValue[i] !== decimalSeparator) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalValue += newValue[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
finalValue += newValue[i];
|
finalValue = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(finalValue);
|
||||||
|
} else if (newValue === '-' || newValue === decimalSeparator || newValue === `-${decimalSeparator}`) {
|
||||||
|
finalValue = newValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalValue !== newValue) {
|
if (finalValue !== newValue) {
|
||||||
currentValue.value = finalValue;
|
currentValue.value = finalValue;
|
||||||
} else {
|
} else {
|
||||||
let value: number = parseAmount(finalValue);
|
let value: number = parseAmountFromLocalizedNumerals(finalValue);
|
||||||
|
|
||||||
|
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (props.flipNegative) {
|
if (props.flipNegative) {
|
||||||
value = -value;
|
value = -value;
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ import {
|
|||||||
isArray,
|
isArray,
|
||||||
isNumber
|
isNumber
|
||||||
} from '@/lib/common.ts';
|
} from '@/lib/common.ts';
|
||||||
import {
|
|
||||||
formatAmount
|
|
||||||
} from '@/lib/numeral.ts';
|
|
||||||
import {
|
import {
|
||||||
getYearMonthFirstUnixTime,
|
getYearMonthFirstUnixTime,
|
||||||
getYearMonthLastUnixTime,
|
getYearMonthLastUnixTime,
|
||||||
@@ -73,7 +70,16 @@ const emit = defineEmits<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { tt, formatUnixTimeToShortYear, formatYearQuarter, formatUnixTimeToShortYearMonth, formatUnixTimeToFiscalYear, formatAmountWithCurrency } = useI18n();
|
|
||||||
|
const { tt,
|
||||||
|
formatUnixTimeToShortYear,
|
||||||
|
formatYearQuarter,
|
||||||
|
formatUnixTimeToShortYearMonth,
|
||||||
|
formatUnixTimeToFiscalYear,
|
||||||
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||||
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { allDateRanges, getItemName, getColor } = useMonthlyTrendsChartBase(props);
|
const { allDateRanges, getItemName, getColor } = useMonthlyTrendsChartBase(props);
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -252,8 +258,8 @@ const yAxisWidth = computed<number>(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxValueText = formatAmountWithCurrency(maxValue, props.defaultCurrency);
|
const maxValueText = formatAmountToLocalizedNumeralsWithCurrency(maxValue, props.defaultCurrency);
|
||||||
const minValueText = formatAmountWithCurrency(minValue, props.defaultCurrency);
|
const minValueText = formatAmountToLocalizedNumeralsWithCurrency(minValue, props.defaultCurrency);
|
||||||
const maxLengthText = maxValueText.length > minValueText.length ? maxValueText : minValueText;
|
const maxLengthText = maxValueText.length > minValueText.length ? maxValueText : minValueText;
|
||||||
|
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
@@ -319,7 +325,7 @@ const chartOptions = computed<object>(() => {
|
|||||||
const item = displayItems[i];
|
const item = displayItems[i];
|
||||||
|
|
||||||
if (displayItems.length === 1 || item.totalAmount !== 0) {
|
if (displayItems.length === 1 || item.totalAmount !== 0) {
|
||||||
const value = formatAmountWithCurrency(item.totalAmount, props.defaultCurrency);
|
const value = formatAmountToLocalizedNumeralsWithCurrency(item.totalAmount, props.defaultCurrency);
|
||||||
tooltip += '<div><span class="chart-pointer" style="background-color: ' + item.color + '"></span>';
|
tooltip += '<div><span class="chart-pointer" style="background-color: ' + item.color + '"></span>';
|
||||||
tooltip += `<span>${item.name}</span><span style="margin-left: 20px; float: right">${value}</span><br/>`;
|
tooltip += `<span>${item.name}</span><span style="margin-left: 20px; float: right">${value}</span><br/>`;
|
||||||
tooltip += '</div>';
|
tooltip += '</div>';
|
||||||
@@ -327,7 +333,7 @@ const chartOptions = computed<object>(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (props.showTotalAmountInTooltip) {
|
if (props.showTotalAmountInTooltip) {
|
||||||
const displayTotalAmount = formatAmountWithCurrency(totalAmount, props.defaultCurrency);
|
const displayTotalAmount = formatAmountToLocalizedNumeralsWithCurrency(totalAmount, props.defaultCurrency);
|
||||||
tooltip = '<div style="border-bottom: ' + (isDarkMode.value ? '#eee' : '#333') + ' dashed 1px">'
|
tooltip = '<div style="border-bottom: ' + (isDarkMode.value ? '#eee' : '#333') + ' dashed 1px">'
|
||||||
+ '<span class="chart-pointer" style="background-color: ' + (isDarkMode.value ? '#eee' : '#333') + '"></span>'
|
+ '<span class="chart-pointer" style="background-color: ' + (isDarkMode.value ? '#eee' : '#333') + '"></span>'
|
||||||
+ `<span>${tt('Total Amount')}</span><span style="margin-left: 20px; float: right">${displayTotalAmount}</span><br/>`
|
+ `<span>${tt('Total Amount')}</span><span style="margin-left: 20px; float: right">${displayTotalAmount}</span><br/>`
|
||||||
@@ -367,13 +373,13 @@ const chartOptions = computed<object>(() => {
|
|||||||
type: 'value',
|
type: 'value',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: (value: string) => {
|
formatter: (value: string) => {
|
||||||
return formatAmountWithCurrency(value, props.defaultCurrency);
|
return formatAmountToLocalizedNumeralsWithCurrency(parseInt(value), props.defaultCurrency);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
label: {
|
label: {
|
||||||
formatter: (params: CallbackDataParams) => {
|
formatter: (params: CallbackDataParams) => {
|
||||||
return formatAmountWithCurrency(Math.floor(params.value as number), props.defaultCurrency);
|
return formatAmountToLocalizedNumeralsWithCurrency(Math.floor(params.value as number), props.defaultCurrency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -443,7 +449,7 @@ function exportData(): { headers: string[], data: string[][] } {
|
|||||||
for (let i = 0; i < allDisplayDateRanges.value.length; i++) {
|
for (let i = 0; i < allDisplayDateRanges.value.length; i++) {
|
||||||
const row: string[] = [];
|
const row: string[] = [];
|
||||||
row.push(allDisplayDateRanges.value[i]);
|
row.push(allDisplayDateRanges.value[i]);
|
||||||
row.push(...allSeries.value.map(item => formatAmount(item.data[i], {})));
|
row.push(...allSeries.value.map(item => formatAmountToWesternArabicNumeralsWithoutDigitGrouping(item.data[i])));
|
||||||
data.push(row);
|
data.push(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const { formatAmountWithCurrency } = useI18n();
|
const { formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
const { selectedIndex, validItems } = usePieChartBase(props);
|
const { selectedIndex, validItems } = usePieChartBase(props);
|
||||||
|
|
||||||
const selectedLegends = ref<Record<string, boolean> | null>(null);
|
const selectedLegends = ref<Record<string, boolean> | null>(null);
|
||||||
@@ -133,7 +133,7 @@ const chartOptions = computed<object>(() => {
|
|||||||
formatter: (params: CallbackDataParams) => {
|
formatter: (params: CallbackDataParams) => {
|
||||||
const dataItem = params.data as DesktopPieChartDataItem;
|
const dataItem = params.data as DesktopPieChartDataItem;
|
||||||
const name = dataItem ? dataItem.displayName : '';
|
const name = dataItem ? dataItem.displayName : '';
|
||||||
const value = dataItem ? dataItem.displayValue : formatAmountWithCurrency(params.value as number);
|
const value = dataItem ? dataItem.displayValue : formatAmountToLocalizedNumeralsWithCurrency(params.value as number);
|
||||||
let percent = dataItem ? dataItem.displayPercent : (params.percent + '%');
|
let percent = dataItem ? dataItem.displayPercent : (params.percent + '%');
|
||||||
|
|
||||||
if (hasUnselectedItem.value) {
|
if (hasUnselectedItem.value) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
:style="`top: ${virtualDataItems.topPosition}px`"
|
:style="`top: ${virtualDataItems.topPosition}px`"
|
||||||
:virtual-list-index="item.index"
|
:virtual-list-index="item.index"
|
||||||
:title="item.displayDate"
|
:title="item.displayDate"
|
||||||
:after="formatAmountWithCurrency(item.closingBalance, account.currency)"
|
:after="formatAmountToLocalizedNumeralsWithCurrency(item.closingBalance, account.currency)"
|
||||||
v-for="item in virtualDataItems.items"
|
v-for="item in virtualDataItems.items"
|
||||||
>
|
>
|
||||||
<template #media>
|
<template #media>
|
||||||
@@ -80,7 +80,7 @@ interface MobileAccountBalanceTrendsChartVirtualListData {
|
|||||||
|
|
||||||
const props = defineProps<MobileAccountBalanceTrendsChartProps>();
|
const props = defineProps<MobileAccountBalanceTrendsChartProps>();
|
||||||
|
|
||||||
const { tt, formatAmountWithCurrency } = useI18n();
|
const { tt, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
const { allDataItems } = useAccountBalanceTrendsChartBase(props);
|
const { allDataItems } = useAccountBalanceTrendsChartBase(props);
|
||||||
|
|
||||||
const virtualDataItems = ref<MobileAccountBalanceTrendsChartVirtualListData>({
|
const virtualDataItems = ref<MobileAccountBalanceTrendsChartVirtualListData>({
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #after>
|
<template #after>
|
||||||
<span>{{ formatAmountWithCurrency(item.totalAmount, defaultCurrency) }}</span>
|
<span>{{ formatAmountToLocalizedNumeralsWithCurrency(item.totalAmount, defaultCurrency) }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #inner-end>
|
<template #inner-end>
|
||||||
@@ -148,7 +148,15 @@ const emit = defineEmits<{
|
|||||||
(e: 'click', value: MonthlyTrendsBarChartClickEvent): void;
|
(e: 'click', value: MonthlyTrendsBarChartClickEvent): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, formatUnixTimeToShortYear, formatYearQuarter, formatUnixTimeToShortYearMonth, formatUnixTimeToFiscalYear, formatAmountWithCurrency } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
formatUnixTimeToShortYear,
|
||||||
|
formatYearQuarter,
|
||||||
|
formatUnixTimeToShortYearMonth,
|
||||||
|
formatUnixTimeToFiscalYear,
|
||||||
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { allDateRanges, getItemName, getColor } = useMonthlyTrendsChartBase(props);
|
const { allDateRanges, getItemName, getColor } = useMonthlyTrendsChartBase(props);
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|||||||
@@ -11,37 +11,37 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="numpad-buttons">
|
<div class="numpad-buttons">
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(7)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(7)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">7</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[7] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(8)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(8)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">8</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[8] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(9)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(9)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">9</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[9] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-function no-right-border" @click="setSymbol('×')">
|
<f7-button class="numpad-button numpad-button-function no-right-border" @click="setSymbol('×')">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">×</span>
|
<span class="numpad-button-text numpad-button-text-normal">×</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(4)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(4)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">4</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[4] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(5)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(5)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">5</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[5] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(6)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(6)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">6</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[6] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-function no-right-border" @click="setSymbol('−')">
|
<f7-button class="numpad-button numpad-button-function no-right-border" @click="setSymbol('−')">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">−</span>
|
<span class="numpad-button-text numpad-button-text-normal">−</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(1)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(1)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">1</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[1] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(2)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(2)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">2</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[2] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(3)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(3)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">3</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[3] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-function no-right-border" @click="setSymbol('+')">
|
<f7-button class="numpad-button numpad-button-function no-right-border" @click="setSymbol('+')">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">+</span>
|
<span class="numpad-button-text numpad-button-text-normal">+</span>
|
||||||
@@ -50,10 +50,10 @@
|
|||||||
<span class="numpad-button-text numpad-button-text-normal">{{ decimalSeparator }}</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ decimalSeparator }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" v-if="!supportDecimalSeparator" @click="inputDoubleNum(0)">
|
<f7-button class="numpad-button numpad-button-num" v-if="!supportDecimalSeparator" @click="inputDoubleNum(0)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">00</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[0] + digits[0] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="inputNum(0)">
|
<f7-button class="numpad-button numpad-button-num" @click="inputNum(0)">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">0</span>
|
<span class="numpad-button-text numpad-button-text-normal">{{ digits[0] }}</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="backspace" @taphold="clear()">
|
<f7-button class="numpad-button numpad-button-num" @click="backspace" @taphold="clear()">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">
|
<span class="numpad-button-text numpad-button-text-normal">
|
||||||
@@ -74,8 +74,9 @@ import { ref, computed, watch } from 'vue';
|
|||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
|
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
|
||||||
|
|
||||||
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||||
import { isString, isNumber, removeAll } from '@/lib/common.ts';
|
import { isNumber } from '@/lib/common.ts';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue: number;
|
modelValue: number;
|
||||||
@@ -94,11 +95,12 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
tt,
|
tt,
|
||||||
|
getAllLocalizedDigits,
|
||||||
|
getCurrentNumeralSystemType,
|
||||||
getCurrentDecimalSeparator,
|
getCurrentDecimalSeparator,
|
||||||
getCurrentDigitGroupingSymbol,
|
parseAmountFromWesternArabicNumerals,
|
||||||
appendDigitGroupingSymbol,
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||||
parseAmount,
|
appendDigitGroupingSymbolAndDecimalSeparator
|
||||||
formatAmount
|
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
const { showToast } = useI18nUIComponents();
|
const { showToast } = useI18nUIComponents();
|
||||||
|
|
||||||
@@ -106,6 +108,7 @@ const previousValue = ref<string>('');
|
|||||||
const currentSymbol = ref<string>('');
|
const currentSymbol = ref<string>('');
|
||||||
const currentValue = ref<string>(getInitedStringValue(props.modelValue, props.flipNegative));
|
const currentValue = ref<string>(getInitedStringValue(props.modelValue, props.flipNegative));
|
||||||
|
|
||||||
|
const digits = computed<string[]>(() => getAllLocalizedDigits());
|
||||||
const decimalSeparator = computed<string>(() => getCurrentDecimalSeparator());
|
const decimalSeparator = computed<string>(() => getCurrentDecimalSeparator());
|
||||||
|
|
||||||
const supportDecimalSeparator = computed<boolean>(() => {
|
const supportDecimalSeparator = computed<boolean>(() => {
|
||||||
@@ -117,8 +120,21 @@ const supportDecimalSeparator = computed<boolean>(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const currentDisplay = computed<string>(() => {
|
const currentDisplay = computed<string>(() => {
|
||||||
const finalPreviousValue = appendDigitGroupingSymbol(previousValue.value);
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const finalCurrentValue = appendDigitGroupingSymbol(currentValue.value);
|
const finalPreviousValue = appendDigitGroupingSymbolAndDecimalSeparator(numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(previousValue.value));
|
||||||
|
let finalCurrentValue = currentValue.value;
|
||||||
|
let currentValueSuffix = '';
|
||||||
|
|
||||||
|
if (finalCurrentValue && finalCurrentValue[finalCurrentValue.length - 1] === decimalSeparator.value) {
|
||||||
|
finalCurrentValue = finalCurrentValue.substring(0, finalCurrentValue.length - 1);
|
||||||
|
currentValueSuffix = decimalSeparator.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
finalCurrentValue = appendDigitGroupingSymbolAndDecimalSeparator(numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(finalCurrentValue));
|
||||||
|
|
||||||
|
if (currentValueSuffix) {
|
||||||
|
finalCurrentValue += currentValueSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentSymbol.value) {
|
if (currentSymbol.value) {
|
||||||
return `${finalPreviousValue} ${currentSymbol.value} ${finalCurrentValue}`;
|
return `${finalPreviousValue} ${currentSymbol.value} ${finalCurrentValue}`;
|
||||||
@@ -150,45 +166,39 @@ function getInitedStringValue(value: number, flipNegative?: boolean): string {
|
|||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getStringValue(value);
|
return getStringValue(value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringValue(value: number | string): string {
|
function getStringValue(value: number, hideZero: boolean): string {
|
||||||
if (!isNumber(value) && !isString(value)) {
|
if (!isNumber(value)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let str = formatAmount(value, props.currency);
|
const textualNumber = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(value, props.currency);
|
||||||
|
|
||||||
const digitGroupingSymbol = getCurrentDigitGroupingSymbol();
|
|
||||||
|
|
||||||
if (str.indexOf(digitGroupingSymbol) >= 0) {
|
|
||||||
str = removeAll(str, digitGroupingSymbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
const decimalSeparator = getCurrentDecimalSeparator();
|
const decimalSeparator = getCurrentDecimalSeparator();
|
||||||
const decimalSeparatorPos = str.indexOf(decimalSeparator);
|
const decimalSeparatorPos = textualNumber.indexOf(decimalSeparator);
|
||||||
|
|
||||||
if (decimalSeparatorPos < 0) {
|
if (decimalSeparatorPos < 0) {
|
||||||
if (str === '0') {
|
if (hideZero && textualNumber === NumeralSystem.WesternArabicNumerals.digitZero) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return textualNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
const integer = str.substring(0, decimalSeparatorPos);
|
const integer = textualNumber.substring(0, decimalSeparatorPos);
|
||||||
const decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
const decimals = textualNumber.substring(decimalSeparatorPos + 1, textualNumber.length);
|
||||||
let newDecimals = '';
|
let newDecimals = '';
|
||||||
|
|
||||||
for (let i = decimals.length - 1; i >= 0; i--) {
|
for (let i = decimals.length - 1; i >= 0; i--) {
|
||||||
if (decimals[i] !== '0' || newDecimals.length > 0) {
|
if (decimals[i] !== NumeralSystem.WesternArabicNumerals.digitZero || newDecimals.length > 0) {
|
||||||
newDecimals = decimals[i] + newDecimals;
|
newDecimals = decimals[i] + newDecimals;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newDecimals.length < 1) {
|
if (newDecimals.length < 1) {
|
||||||
if (integer === '0') {
|
if (hideZero && integer === NumeralSystem.WesternArabicNumerals.digitZero) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,10 +214,10 @@ function inputNum(num: number): void {
|
|||||||
currentSymbol.value = '';
|
currentSymbol.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentValue.value === '0') {
|
if (currentValue.value === NumeralSystem.WesternArabicNumerals.digitZero) {
|
||||||
currentValue.value = num.toString();
|
currentValue.value = num.toString();
|
||||||
return;
|
return;
|
||||||
} else if (currentValue.value === '-0') {
|
} else if (currentValue.value === `-${NumeralSystem.WesternArabicNumerals.digitZero}`) {
|
||||||
currentValue.value = '-' + num.toString();
|
currentValue.value = '-' + num.toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -221,7 +231,7 @@ function inputNum(num: number): void {
|
|||||||
const newValue = currentValue.value + num.toString();
|
const newValue = currentValue.value + num.toString();
|
||||||
|
|
||||||
if (isNumber(props.minValue)) {
|
if (isNumber(props.minValue)) {
|
||||||
const current = parseAmount(newValue);
|
const current = parseAmountFromWesternArabicNumerals(newValue);
|
||||||
|
|
||||||
if (current < (props.minValue)) {
|
if (current < (props.minValue)) {
|
||||||
return;
|
return;
|
||||||
@@ -229,7 +239,7 @@ function inputNum(num: number): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isNumber(props.maxValue)) {
|
if (isNumber(props.maxValue)) {
|
||||||
const current = parseAmount(newValue);
|
const current = parseAmountFromWesternArabicNumerals(newValue);
|
||||||
|
|
||||||
if (current > (props.maxValue)) {
|
if (current > (props.maxValue)) {
|
||||||
return;
|
return;
|
||||||
@@ -255,9 +265,9 @@ function inputDecimalSeparator(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentValue.value.length < 1) {
|
if (currentValue.value.length < 1) {
|
||||||
currentValue.value = '0';
|
currentValue.value = NumeralSystem.WesternArabicNumerals.digitZero;
|
||||||
} else if (currentValue.value === '-') {
|
} else if (currentValue.value === '-') {
|
||||||
currentValue.value = '-0';
|
currentValue.value = '-' + NumeralSystem.WesternArabicNumerals.digitZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentValue.value = currentValue.value + decimalSeparator.value;
|
currentValue.value = currentValue.value + decimalSeparator.value;
|
||||||
@@ -302,8 +312,8 @@ function clear(): void {
|
|||||||
|
|
||||||
function confirm(): boolean {
|
function confirm(): boolean {
|
||||||
if (currentSymbol.value && currentValue.value.length >= 1) {
|
if (currentSymbol.value && currentValue.value.length >= 1) {
|
||||||
const previous = parseAmount(previousValue.value);
|
const previous = parseAmountFromWesternArabicNumerals(previousValue.value);
|
||||||
const current = parseAmount(currentValue.value);
|
const current = parseAmountFromWesternArabicNumerals(currentValue.value);
|
||||||
let finalValue = 0;
|
let finalValue = 0;
|
||||||
|
|
||||||
switch (currentSymbol.value) {
|
switch (currentSymbol.value) {
|
||||||
@@ -334,7 +344,7 @@ function confirm(): boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentValue.value = getStringValue(finalValue);
|
currentValue.value = getStringValue(finalValue, false);
|
||||||
previousValue.value = '';
|
previousValue.value = '';
|
||||||
currentSymbol.value = '';
|
currentSymbol.value = '';
|
||||||
|
|
||||||
@@ -346,7 +356,7 @@ function confirm(): boolean {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
let value: number = parseAmount(currentValue.value);
|
let value: number = parseAmountFromWesternArabicNumerals(currentValue.value);
|
||||||
|
|
||||||
if (props.flipNegative) {
|
if (props.flipNegative) {
|
||||||
value = -value;
|
value = -value;
|
||||||
|
|||||||
@@ -1,2 +1,7 @@
|
|||||||
|
import type { HiddenAmount } from '@/core/numeral.ts';
|
||||||
|
|
||||||
export const DEFAULT_DECIMAL_NUMBER_COUNT: number = 2;
|
export const DEFAULT_DECIMAL_NUMBER_COUNT: number = 2;
|
||||||
export const MAX_SUPPORTED_DECIMAL_NUMBER_COUNT: number = 2;
|
export const MAX_SUPPORTED_DECIMAL_NUMBER_COUNT: number = 2;
|
||||||
|
|
||||||
|
export const DISPLAY_HIDDEN_AMOUNT: HiddenAmount = '***';
|
||||||
|
export const INCOMPLETE_AMOUNT_SUFFIX: string = '+';
|
||||||
|
|||||||
+168
-3
@@ -1,13 +1,21 @@
|
|||||||
import type { TypeAndName, TypeAndDisplayName } from '@/core/base.ts';
|
import type { TypeAndName, TypeAndDisplayName } from '@/core/base.ts';
|
||||||
|
|
||||||
|
export type HiddenAmount = '***';
|
||||||
|
|
||||||
export interface NumberFormatOptions {
|
export interface NumberFormatOptions {
|
||||||
readonly digitGrouping?: number;
|
readonly numeralSystem: NumeralSystem;
|
||||||
readonly digitGroupingSymbol?: string;
|
readonly digitGrouping: DigitGroupingType;
|
||||||
|
readonly digitGroupingSymbol: string;
|
||||||
|
readonly decimalSeparator: string;
|
||||||
readonly decimalNumberCount?: number;
|
readonly decimalNumberCount?: number;
|
||||||
readonly decimalSeparator?: string;
|
|
||||||
readonly trimTailZero?: boolean;
|
readonly trimTailZero?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface NumberWithSuffix {
|
||||||
|
readonly value: number;
|
||||||
|
readonly suffix: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface NumeralSymbolType {
|
export interface NumeralSymbolType {
|
||||||
readonly type: number;
|
readonly type: number;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
@@ -26,6 +34,163 @@ export interface LocalizedDigitGroupingType extends TypeAndDisplayName {
|
|||||||
readonly displayName: string;
|
readonly displayName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class NumeralSystem implements TypeAndName {
|
||||||
|
private static readonly allInstances: NumeralSystem[] = [];
|
||||||
|
private static readonly allInstancesByType: Record<number, NumeralSystem> = {};
|
||||||
|
private static readonly allInstancesByTypeName: Record<string, NumeralSystem> = {};
|
||||||
|
private static readonly allDigitsToWesternArabic: Record<string, number> = {};
|
||||||
|
private static readonly allDigitsToNumeralSystem: Record<string, NumeralSystem> = {};
|
||||||
|
|
||||||
|
public static readonly LanguageDefaultType: number = 0;
|
||||||
|
public static readonly WesternArabicNumerals = new NumeralSystem(1, 'WesternArabicNumerals', 'Western Arabic Numerals', '\u0030');
|
||||||
|
public static readonly EasternArabicNumerals = new NumeralSystem(2, 'EasternArabicNumerals', 'Eastern Arabic Numerals', '\u0660');
|
||||||
|
public static readonly PersianDigits = new NumeralSystem(3, 'PersianDigits', 'Persian Digits', '\u06F0');
|
||||||
|
public static readonly BurmeseNumerals = new NumeralSystem(4, 'BurmeseNumerals', 'Burmese Numerals', '\u1040');
|
||||||
|
public static readonly DevanagariNumerals = new NumeralSystem(5, 'DevanagariNumerals', 'Devanagari Numerals', '\u0966');
|
||||||
|
|
||||||
|
public static readonly Default = NumeralSystem.WesternArabicNumerals;
|
||||||
|
|
||||||
|
public readonly type: number;
|
||||||
|
public readonly typeName: string;
|
||||||
|
public readonly name: string;
|
||||||
|
public readonly digitZero: string;
|
||||||
|
public readonly doubleDigitZero: string;
|
||||||
|
public readonly textualAllDigits: string;
|
||||||
|
private readonly allDigits: string[];
|
||||||
|
private readonly digitsToWesternArabic: Record<string, number> = {};
|
||||||
|
|
||||||
|
private constructor(type: number, typeName: string, name: string, digitZero: string) {
|
||||||
|
this.type = type;
|
||||||
|
this.typeName = typeName;
|
||||||
|
this.name = name;
|
||||||
|
this.digitZero = digitZero;
|
||||||
|
this.doubleDigitZero = digitZero + digitZero;
|
||||||
|
this.allDigits = [];
|
||||||
|
this.digitsToWesternArabic = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
const digit = String.fromCharCode(this.digitZero.charCodeAt(0) + i);
|
||||||
|
this.allDigits.push(digit);
|
||||||
|
this.digitsToWesternArabic[digit] = i;
|
||||||
|
NumeralSystem.allDigitsToWesternArabic[digit] = i;
|
||||||
|
NumeralSystem.allDigitsToNumeralSystem[digit] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.textualAllDigits = this.allDigits.join('');
|
||||||
|
|
||||||
|
NumeralSystem.allInstances.push(this);
|
||||||
|
NumeralSystem.allInstancesByType[type] = this;
|
||||||
|
NumeralSystem.allInstancesByTypeName[typeName] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAllDigits(): string[] {
|
||||||
|
return this.allDigits.slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
public isDigit(digit: string): boolean {
|
||||||
|
return this.digitsToWesternArabic.hasOwnProperty(digit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getLocalizedDigit(digit: number): string {
|
||||||
|
if (digit < 0 || digit > 9) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.allDigits[digit];
|
||||||
|
}
|
||||||
|
|
||||||
|
public parseInt(value: string): number {
|
||||||
|
if (!value) {
|
||||||
|
return Number.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === NumeralSystem.WesternArabicNumerals.type) {
|
||||||
|
return parseInt(value, 10);
|
||||||
|
} else {
|
||||||
|
const westernArabicValue = this.replaceLocalizedDigitsToWesternArabicDigits(value);
|
||||||
|
return parseInt(westernArabicValue, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public formatNumber(value: number): string {
|
||||||
|
if (Number.isNaN(value) || !Number.isFinite(value)) {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === NumeralSystem.WesternArabicNumerals.type) {
|
||||||
|
return value.toString(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value === 0) {
|
||||||
|
return this.digitZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.replaceWesternArabicDigitsToLocalizedDigits(value.toString(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
public replaceWesternArabicDigitsToLocalizedDigits(value: string): string {
|
||||||
|
if (!value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
const ch = value[i];
|
||||||
|
|
||||||
|
if (NumeralSystem.WesternArabicNumerals.isDigit(ch)) {
|
||||||
|
const digit = NumeralSystem.WesternArabicNumerals.digitsToWesternArabic[ch];
|
||||||
|
result += this.allDigits[digit];
|
||||||
|
} else {
|
||||||
|
result += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public replaceLocalizedDigitsToWesternArabicDigits(value: string): string {
|
||||||
|
if (!value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
const ch = value[i];
|
||||||
|
|
||||||
|
if (this.isDigit(ch)) {
|
||||||
|
const digit = this.digitsToWesternArabic[ch];
|
||||||
|
result += NumeralSystem.WesternArabicNumerals.allDigits[digit];
|
||||||
|
} else {
|
||||||
|
result += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static values(): NumeralSystem[] {
|
||||||
|
return NumeralSystem.allInstances;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static valueOf(type: number): NumeralSystem | undefined {
|
||||||
|
return NumeralSystem.allInstancesByType[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static parse(typeName: string): NumeralSystem | undefined {
|
||||||
|
return NumeralSystem.allInstancesByTypeName[typeName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static detect(digit: string): NumeralSystem | undefined {
|
||||||
|
return NumeralSystem.allDigitsToNumeralSystem[digit];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static toNumber(digit: string): number | undefined {
|
||||||
|
return NumeralSystem.allDigitsToWesternArabic[digit];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class DecimalSeparator implements TypeAndName, NumeralSymbolType {
|
export class DecimalSeparator implements TypeAndName, NumeralSymbolType {
|
||||||
private static readonly allInstances: DecimalSeparator[] = [];
|
private static readonly allInstances: DecimalSeparator[] = [];
|
||||||
private static readonly allInstancesByType: Record<number, DecimalSeparator> = {};
|
private static readonly allInstancesByType: Record<number, DecimalSeparator> = {};
|
||||||
|
|||||||
+1
-7
@@ -1,8 +1,6 @@
|
|||||||
import { CurrencyDisplaySymbol, CurrencyDisplayLocation, type CurrencyPrependAndAppendText, CurrencyDisplayType } from '@/core/currency.ts';
|
import { CurrencyDisplaySymbol, CurrencyDisplayLocation, type CurrencyPrependAndAppendText, CurrencyDisplayType } from '@/core/currency.ts';
|
||||||
import { ALL_CURRENCIES, DEFAULT_CURRENCY_SYMBOL } from '@/consts/currency.ts';
|
import { ALL_CURRENCIES, DEFAULT_CURRENCY_SYMBOL } from '@/consts/currency.ts';
|
||||||
|
|
||||||
import { isNumber } from './common.ts';
|
|
||||||
|
|
||||||
export function getCurrencyFraction(currencyCode?: string): number | undefined {
|
export function getCurrencyFraction(currencyCode?: string): number | undefined {
|
||||||
if (!currencyCode) {
|
if (!currencyCode) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -12,11 +10,7 @@ export function getCurrencyFraction(currencyCode?: string): number | undefined {
|
|||||||
return currencyInfo?.fraction;
|
return currencyInfo?.fraction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function appendCurrencySymbol(value: number | string, currencyDisplayType: CurrencyDisplayType, currencyCode: string, currencyUnit: string, currencyName: string, isPlural: boolean): string {
|
export function appendCurrencySymbol(value: string, currencyDisplayType: CurrencyDisplayType, currencyCode: string, currencyUnit: string, currencyName: string, isPlural: boolean): string {
|
||||||
if (isNumber(value)) {
|
|
||||||
value = value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
const symbol = getAmountPrependAndAppendCurrencySymbol(currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
|
const symbol = getAmountPrependAndAppendCurrencySymbol(currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
|
||||||
|
|
||||||
if (!symbol) {
|
if (!symbol) {
|
||||||
|
|||||||
+136
-182
@@ -1,7 +1,14 @@
|
|||||||
import { type NumberFormatOptions, DecimalSeparator, DigitGroupingSymbol, DigitGroupingType } from '@/core/numeral.ts';
|
import {
|
||||||
import { DEFAULT_DECIMAL_NUMBER_COUNT, MAX_SUPPORTED_DECIMAL_NUMBER_COUNT } from '@/consts/numeral.ts';
|
type HiddenAmount,
|
||||||
|
type NumberFormatOptions,
|
||||||
|
NumeralSystem,
|
||||||
|
DecimalSeparator,
|
||||||
|
DigitGroupingSymbol
|
||||||
|
} from '@/core/numeral.ts';
|
||||||
|
|
||||||
import { isString, isNumber, replaceAll, removeAll } from './common.ts';
|
import { DEFAULT_DECIMAL_NUMBER_COUNT, MAX_SUPPORTED_DECIMAL_NUMBER_COUNT, DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
|
import { isDefined, isString, isNumber, replaceAll, removeAll } from './common.ts';
|
||||||
|
|
||||||
export function sumAmounts(amounts: number[]): number {
|
export function sumAmounts(amounts: number[]): number {
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
@@ -13,138 +20,77 @@ export function sumAmounts(amounts: number[]): number {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function appendDigitGroupingSymbol(value: number | string, options: NumberFormatOptions): string {
|
export function appendDigitGroupingSymbolAndDecimalSeparator(textualNumber: string, options: NumberFormatOptions): string {
|
||||||
let textualValue = '';
|
if (!textualNumber) {
|
||||||
|
return textualNumber;
|
||||||
if (isNumber(value)) {
|
|
||||||
textualValue = value.toString();
|
|
||||||
} else {
|
|
||||||
textualValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!textualValue) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNumber(options.digitGrouping)) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const digitGroupingType = DigitGroupingType.valueOf(options.digitGrouping);
|
|
||||||
|
|
||||||
if (!digitGroupingType || !digitGroupingType.enabled) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textualValue.length <= 1) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const negative = textualValue.charAt(0) === '-';
|
|
||||||
|
|
||||||
if (negative) {
|
|
||||||
textualValue = textualValue.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textualValue.length <= 1) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
|
const digitGroupingType = options.digitGrouping;
|
||||||
const digitGroupingSymbol = options.digitGroupingSymbol || DigitGroupingSymbol.Default.symbol;
|
const digitGroupingSymbol = options.digitGroupingSymbol || DigitGroupingSymbol.Default.symbol;
|
||||||
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
||||||
|
|
||||||
const integerChars = [];
|
const negative = textualNumber.charAt(0) === '-';
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
textualNumber = textualNumber.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const integerChars: string[] = [];
|
||||||
|
const decimalChars: string[] = [];
|
||||||
let currentDecimalSeparator = '';
|
let currentDecimalSeparator = '';
|
||||||
let decimals = '';
|
|
||||||
|
|
||||||
for (let i = 0; i < textualValue.length; i++) {
|
if (textualNumber === DISPLAY_HIDDEN_AMOUNT) {
|
||||||
const ch = textualValue.charAt(i);
|
for (let i = 0; i < textualNumber.length - 2; i++) {
|
||||||
|
integerChars.push(textualNumber.charAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
if ('0' <= ch && ch <= '9') {
|
const decimalStartIndex = Math.max(0, textualNumber.length - 2);
|
||||||
integerChars.push(ch);
|
|
||||||
} else {
|
for (let i = decimalStartIndex; i < textualNumber.length; i++) {
|
||||||
currentDecimalSeparator = ch;
|
decimalChars.push(textualNumber.charAt(i));
|
||||||
decimals = textualValue.substring(i + 1);
|
}
|
||||||
break;
|
} else {
|
||||||
|
for (let i = 0; i < textualNumber.length; i++) {
|
||||||
|
const ch = textualNumber.charAt(i);
|
||||||
|
|
||||||
|
if (!currentDecimalSeparator) {
|
||||||
|
if (numeralSystem.isDigit(ch)) {
|
||||||
|
integerChars.push(ch);
|
||||||
|
} else {
|
||||||
|
currentDecimalSeparator = ch;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (numeralSystem.isDigit(ch)) {
|
||||||
|
decimalChars.push(ch);
|
||||||
|
} else {
|
||||||
|
throw new Error('Number \"' + textualNumber + '\" is not a valid textual number');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let newInteger = digitGroupingType.format(integerChars, digitGroupingSymbol);
|
|
||||||
|
|
||||||
if (negative) {
|
|
||||||
newInteger = `-${newInteger}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentDecimalSeparator) {
|
|
||||||
return `${newInteger}${decimalSeparator}${decimals}`;
|
|
||||||
} else {
|
|
||||||
return newInteger;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function appendDecimalSeparator(value: number | string, options: NumberFormatOptions): string {
|
|
||||||
let textualValue = '';
|
|
||||||
|
|
||||||
if (isNumber(value)) {
|
|
||||||
textualValue = value.toString();
|
|
||||||
} else {
|
|
||||||
textualValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!textualValue) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isString(options.decimalSeparator)) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textualValue.length < 1) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const negative = textualValue.charAt(0) === '-';
|
|
||||||
|
|
||||||
if (negative) {
|
|
||||||
textualValue = textualValue.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
|
||||||
|
|
||||||
let currentDecimalSeparator = '';
|
|
||||||
let integer = '';
|
let integer = '';
|
||||||
let decimals = '';
|
|
||||||
|
|
||||||
for (let i = 0; i < textualValue.length; i++) {
|
if (digitGroupingType) {
|
||||||
const ch = textualValue.charAt(i);
|
integer = digitGroupingType.format(integerChars, digitGroupingSymbol);
|
||||||
|
} else {
|
||||||
if ('0' <= ch && ch <= '9') {
|
integer = integerChars.join('');
|
||||||
integer += ch;
|
|
||||||
} else {
|
|
||||||
currentDecimalSeparator = ch;
|
|
||||||
decimals = textualValue.substring(i + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const decimals = decimalChars.join('');
|
||||||
|
|
||||||
|
if (decimals) {
|
||||||
|
textualNumber = `${integer}${decimalSeparator}${decimals}`;
|
||||||
|
} else {
|
||||||
|
textualNumber = integer;
|
||||||
|
}
|
||||||
|
|
||||||
if (negative) {
|
if (negative) {
|
||||||
integer = `-${integer}`;
|
textualNumber = `-${textualNumber}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentDecimalSeparator) {
|
return textualNumber;
|
||||||
return `${integer}${decimalSeparator}${decimals}`;
|
|
||||||
} else {
|
|
||||||
return integer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseAmount(str: string, options: NumberFormatOptions): number {
|
export function parseAmount(str: string, options: NumberFormatOptions): number {
|
||||||
@@ -152,10 +98,6 @@ export function parseAmount(str: string, options: NumberFormatOptions): number {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!str || str.length < 1) {
|
if (!str || str.length < 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -172,6 +114,7 @@ export function parseAmount(str: string, options: NumberFormatOptions): number {
|
|||||||
|
|
||||||
const sign = negative ? -1 : 1;
|
const sign = negative ? -1 : 1;
|
||||||
|
|
||||||
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
||||||
const digitGroupingSymbol = options.digitGroupingSymbol || DigitGroupingSymbol.Default.symbol;
|
const digitGroupingSymbol = options.digitGroupingSymbol || DigitGroupingSymbol.Default.symbol;
|
||||||
|
|
||||||
@@ -182,9 +125,9 @@ export function parseAmount(str: string, options: NumberFormatOptions): number {
|
|||||||
let decimalSeparatorPos = str.indexOf(decimalSeparator);
|
let decimalSeparatorPos = str.indexOf(decimalSeparator);
|
||||||
|
|
||||||
if (decimalSeparatorPos < 0) {
|
if (decimalSeparatorPos < 0) {
|
||||||
return sign * parseInt(str) * 100;
|
return sign * numeralSystem.parseInt(str) * 100;
|
||||||
} else if (decimalSeparatorPos === 0) {
|
} else if (decimalSeparatorPos === 0) {
|
||||||
str = '0' + str;
|
str = numeralSystem.digitZero + str;
|
||||||
decimalSeparatorPos++;
|
decimalSeparatorPos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,39 +135,36 @@ export function parseAmount(str: string, options: NumberFormatOptions): number {
|
|||||||
const decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
const decimals = str.substring(decimalSeparatorPos + 1, str.length);
|
||||||
|
|
||||||
if (decimals.length < 1) {
|
if (decimals.length < 1) {
|
||||||
return sign * parseInt(integer) * 100;
|
return sign * numeralSystem.parseInt(integer) * 100;
|
||||||
} else if (decimals.length === 1) {
|
} else if (decimals.length === 1) {
|
||||||
return sign * parseInt(integer) * 100 + sign * parseInt(decimals) * 10;
|
return sign * numeralSystem.parseInt(integer) * 100 + sign * numeralSystem.parseInt(decimals) * 10;
|
||||||
} else if (decimals.length === 2) {
|
} else if (decimals.length === 2) {
|
||||||
return sign * parseInt(integer) * 100 + sign * parseInt(decimals);
|
return sign * numeralSystem.parseInt(integer) * 100 + sign * numeralSystem.parseInt(decimals);
|
||||||
} else {
|
} else {
|
||||||
return sign * parseInt(integer) * 100 + sign * parseInt(decimals.substring(0, 2));
|
return sign * numeralSystem.parseInt(integer) * 100 + sign * numeralSystem.parseInt(decimals.substring(0, 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatAmount(value: number | string, options: NumberFormatOptions): string {
|
export function formatAmount(value: number, options: NumberFormatOptions): string {
|
||||||
let textualValue = '';
|
if (!Number.isSafeInteger(value)) {
|
||||||
|
throw new Error('Number \"' + value + '\" is not amount number');
|
||||||
if (isNumber(value)) {
|
|
||||||
textualValue = value.toString();
|
|
||||||
} else {
|
|
||||||
textualValue = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!textualValue) {
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
return textualValue;
|
let textualNumber = numeralSystem.formatNumber(value);
|
||||||
|
|
||||||
|
if (!textualNumber) {
|
||||||
|
return textualNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options) {
|
const negative = textualNumber.charAt(0) === '-';
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const negative = textualValue.charAt(0) === '-';
|
|
||||||
|
|
||||||
if (negative) {
|
if (negative) {
|
||||||
textualValue = textualValue.substring(1);
|
textualNumber = textualNumber.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const digitGroupingType = options.digitGrouping;
|
||||||
|
const digitGroupingSymbol = options.digitGroupingSymbol || DigitGroupingSymbol.Default.symbol;
|
||||||
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
||||||
let decimalNumberCount = options.decimalNumberCount;
|
let decimalNumberCount = options.decimalNumberCount;
|
||||||
|
|
||||||
@@ -232,62 +172,75 @@ export function formatAmount(value: number | string, options: NumberFormatOption
|
|||||||
decimalNumberCount = DEFAULT_DECIMAL_NUMBER_COUNT;
|
decimalNumberCount = DEFAULT_DECIMAL_NUMBER_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
let integer = '0';
|
let integer = numeralSystem.digitZero;
|
||||||
let decimals = '00';
|
let decimals = numeralSystem.doubleDigitZero;
|
||||||
|
|
||||||
if (textualValue.length > 2) {
|
if (textualNumber.length > 2) {
|
||||||
integer = textualValue.substring(0, textualValue.length - 2);
|
integer = textualNumber.substring(0, textualNumber.length - 2);
|
||||||
decimals = textualValue.substring(textualValue.length - 2);
|
decimals = textualNumber.substring(textualNumber.length - 2);
|
||||||
} else if (textualValue.length === 2) {
|
} else if (textualNumber.length === 2) {
|
||||||
decimals = textualValue;
|
decimals = textualNumber;
|
||||||
} else if (textualValue.length === 1) {
|
} else if (textualNumber.length === 1) {
|
||||||
decimals = '0' + textualValue;
|
decimals = numeralSystem.digitZero + textualNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decimalNumberCount === 0) {
|
if (decimalNumberCount === 0) {
|
||||||
if (decimals === '00') {
|
if (decimals === numeralSystem.doubleDigitZero) {
|
||||||
decimals = '';
|
decimals = '';
|
||||||
} else if (decimals.charAt(1) === '0') {
|
} else if (decimals.charAt(1) === numeralSystem.digitZero) {
|
||||||
decimals = decimals.charAt(0);
|
decimals = decimals.charAt(0);
|
||||||
}
|
}
|
||||||
} else if (decimalNumberCount === 1) {
|
} else if (decimalNumberCount === 1) {
|
||||||
if (decimals.charAt(1) === '0') {
|
if (decimals.charAt(1) === numeralSystem.digitZero) {
|
||||||
decimals = decimals.charAt(0);
|
decimals = decimals.charAt(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.trimTailZero) {
|
if (options.trimTailZero) {
|
||||||
if (decimals.charAt(0) === '0' && decimals.charAt(1) === '0') {
|
if (decimals.charAt(0) === numeralSystem.digitZero && decimals.charAt(1) === numeralSystem.digitZero) {
|
||||||
decimals = '';
|
decimals = '';
|
||||||
} else if (decimals.charAt(0) !== '0' && decimals.charAt(1) === '0') {
|
} else if (decimals.charAt(0) !== numeralSystem.digitZero && decimals.charAt(1) === numeralSystem.digitZero) {
|
||||||
decimals = decimals.charAt(0);
|
decimals = decimals.charAt(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
integer = appendDigitGroupingSymbol(integer, options);
|
if (integer && integer.length > 1 && digitGroupingType) {
|
||||||
|
integer = digitGroupingType.format(integer.split(''), digitGroupingSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
if (decimals !== '') {
|
if (decimals) {
|
||||||
textualValue = `${integer}${decimalSeparator}${decimals}`;
|
textualNumber = `${integer}${decimalSeparator}${decimals}`;
|
||||||
} else {
|
} else {
|
||||||
textualValue = integer;
|
textualNumber = integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative) {
|
if (negative) {
|
||||||
textualValue = `-${textualValue}`;
|
textualNumber = `-${textualNumber}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return textualValue;
|
return textualNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatNumber(value: number, precision: number, options: NumberFormatOptions): string {
|
export function formatHiddenAmount(value: HiddenAmount, options: NumberFormatOptions): string {
|
||||||
const ratio = Math.pow(10, precision);
|
return appendDigitGroupingSymbolAndDecimalSeparator(value, options);
|
||||||
const normalizedValue = Math.floor(value * ratio);
|
}
|
||||||
const textualValue = (normalizedValue / ratio).toString();
|
|
||||||
|
|
||||||
return appendDecimalSeparator(textualValue, options);
|
export function formatNumber(value: number, options: NumberFormatOptions, precision?: number): string {
|
||||||
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
|
|
||||||
|
if (isDefined(precision)) {
|
||||||
|
const ratio = Math.pow(10, precision);
|
||||||
|
const normalizedValue = Math.floor(value * ratio);
|
||||||
|
const textualValue = numeralSystem.formatNumber(normalizedValue / ratio);
|
||||||
|
return appendDigitGroupingSymbolAndDecimalSeparator(textualValue, options);
|
||||||
|
} else {
|
||||||
|
const textualValue = numeralSystem.formatNumber(value);
|
||||||
|
return appendDigitGroupingSymbolAndDecimalSeparator(textualValue, options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatPercent(value: number, precision: number, lowPrecisionValue: string, options: NumberFormatOptions): string {
|
export function formatPercent(value: number, precision: number, lowPrecisionValue: string, options: NumberFormatOptions): string {
|
||||||
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
const ratio = Math.pow(10, precision);
|
const ratio = Math.pow(10, precision);
|
||||||
const normalizedValue = Math.floor(value * ratio);
|
const normalizedValue = Math.floor(value * ratio);
|
||||||
|
|
||||||
@@ -295,6 +248,8 @@ export function formatPercent(value: number, precision: number, lowPrecisionValu
|
|||||||
const systemDecimalSeparator = DecimalSeparator.Dot.symbol;
|
const systemDecimalSeparator = DecimalSeparator.Dot.symbol;
|
||||||
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
const decimalSeparator = options.decimalSeparator || DecimalSeparator.Default.symbol;
|
||||||
|
|
||||||
|
lowPrecisionValue = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(lowPrecisionValue);
|
||||||
|
|
||||||
if (systemDecimalSeparator === decimalSeparator) {
|
if (systemDecimalSeparator === decimalSeparator) {
|
||||||
return lowPrecisionValue + '%';
|
return lowPrecisionValue + '%';
|
||||||
}
|
}
|
||||||
@@ -302,7 +257,7 @@ export function formatPercent(value: number, precision: number, lowPrecisionValu
|
|||||||
return replaceAll(lowPrecisionValue, systemDecimalSeparator, decimalSeparator) + '%';
|
return replaceAll(lowPrecisionValue, systemDecimalSeparator, decimalSeparator) + '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatNumber(value, precision, options) + '%';
|
return formatNumber(value, options, precision) + '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAmountWithDecimalNumberCount(amount: number, decimalNumberCount: number): number {
|
export function getAmountWithDecimalNumberCount(amount: number, decimalNumberCount: number): number {
|
||||||
@@ -315,32 +270,31 @@ export function getAmountWithDecimalNumberCount(amount: number, decimalNumberCou
|
|||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatExchangeRateAmount(exchangeRateAmount: number | string, options: NumberFormatOptions): string {
|
export function formatExchangeRateAmount(exchangeRateAmount: number, options: NumberFormatOptions): string {
|
||||||
if (!options) {
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
options = {};
|
const rateStr = numeralSystem.formatNumber(exchangeRateAmount);
|
||||||
}
|
|
||||||
|
|
||||||
const rateStr = exchangeRateAmount.toString();
|
|
||||||
const decimalSeparator = DecimalSeparator.Dot.symbol;
|
const decimalSeparator = DecimalSeparator.Dot.symbol;
|
||||||
|
|
||||||
if (rateStr.indexOf(decimalSeparator) < 0) {
|
if (rateStr.indexOf(decimalSeparator) < 0) {
|
||||||
return appendDigitGroupingSymbol(rateStr, options);
|
return appendDigitGroupingSymbolAndDecimalSeparator(rateStr, options);
|
||||||
} else {
|
} else {
|
||||||
let firstNonZeroPos = 0;
|
let firstNonZeroPos = 0;
|
||||||
|
|
||||||
for (let i = 0; i < rateStr.length; i++) {
|
for (let i = 0; i < rateStr.length; i++) {
|
||||||
if (rateStr.charAt(i) !== decimalSeparator && rateStr.charAt(i) !== '0') {
|
if (rateStr.charAt(i) !== decimalSeparator && rateStr.charAt(i) !== numeralSystem.digitZero) {
|
||||||
firstNonZeroPos = Math.min(i + 4, rateStr.length);
|
firstNonZeroPos = Math.min(i + 4, rateStr.length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const trimmedRateStr = rateStr.substring(0, Math.max(6, Math.max(firstNonZeroPos, rateStr.indexOf(decimalSeparator) + 2)));
|
const trimmedRateStr = rateStr.substring(0, Math.max(6, Math.max(firstNonZeroPos, rateStr.indexOf(decimalSeparator) + 2)));
|
||||||
return appendDigitGroupingSymbol(trimmedRateStr, options);
|
return appendDigitGroupingSymbolAndDecimalSeparator(trimmedRateStr, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, fromExchangeRate: { rate: string }, toExchangeRate: { rate: string }, options: NumberFormatOptions): string | null {
|
export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, fromExchangeRate: { rate: string }, toExchangeRate: { rate: string }, options: NumberFormatOptions): string | null {
|
||||||
|
const numeralSystem = options.numeralSystem || NumeralSystem.Default;
|
||||||
|
|
||||||
if (!amount1 || !amount2 || amount1 === amount2) {
|
if (!amount1 || !amount2 || amount1 === amount2) {
|
||||||
if (!fromExchangeRate || !fromExchangeRate.rate || !toExchangeRate || !toExchangeRate.rate) {
|
if (!fromExchangeRate || !fromExchangeRate.rate || !toExchangeRate || !toExchangeRate.rate) {
|
||||||
return null;
|
return null;
|
||||||
@@ -351,13 +305,13 @@ export function getAdaptiveDisplayAmountRate(amount1: number, amount2: number, f
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (amount1 > amount2) {
|
if (amount1 > amount2) {
|
||||||
const rateStr = (amount1 / amount2).toString();
|
const rate = amount1 / amount2;
|
||||||
const displayRateStr = formatExchangeRateAmount(rateStr, options);
|
const displayRateStr = formatExchangeRateAmount(rate, options);
|
||||||
return `${displayRateStr} : 1`;
|
return `${displayRateStr} : ${numeralSystem.getLocalizedDigit(1)}`;
|
||||||
} else {
|
} else {
|
||||||
const rateStr = (amount2 / amount1).toString();
|
const rate = amount2 / amount1;
|
||||||
const displayRateStr = formatExchangeRateAmount(rateStr, options);
|
const displayRateStr = formatExchangeRateAmount(rate, options);
|
||||||
return `1 : ${displayRateStr}`;
|
return `${numeralSystem.getLocalizedDigit(1)} : ${displayRateStr}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Dot",
|
"digitGroupingSymbol": "Dot",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Punkt",
|
"Dot": "Punkt",
|
||||||
"Comma": "Komma",
|
"Comma": "Komma",
|
||||||
"Space": "Leerzeichen",
|
"Space": "Leerzeichen",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Langes Zeitformat",
|
"Long Time Format": "Langes Zeitformat",
|
||||||
"Short Time Format": "Kurzes Zeitformat",
|
"Short Time Format": "Kurzes Zeitformat",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Dezimaltrennzeichen",
|
"Decimal Separator": "Dezimaltrennzeichen",
|
||||||
"Digit Grouping Symbol": "Zifferngruppierungssymbol",
|
"Digit Grouping Symbol": "Zifferngruppierungssymbol",
|
||||||
"Digit Grouping": "Zifferngruppierung",
|
"Digit Grouping": "Zifferngruppierung",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "MMDDYYYY",
|
"shortDateFormat": "MMDDYYYY",
|
||||||
"longTimeFormat": "HHMMSSA",
|
"longTimeFormat": "HHMMSSA",
|
||||||
"shortTimeFormat": "HHMMA",
|
"shortTimeFormat": "HHMMA",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Dot",
|
"decimalSeparator": "Dot",
|
||||||
"digitGroupingSymbol": "Comma",
|
"digitGroupingSymbol": "Comma",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Dot",
|
"Dot": "Dot",
|
||||||
"Comma": "Comma",
|
"Comma": "Comma",
|
||||||
"Space": "Space",
|
"Space": "Space",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Long Time Format",
|
"Long Time Format": "Long Time Format",
|
||||||
"Short Time Format": "Short Time Format",
|
"Short Time Format": "Short Time Format",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Decimal Separator",
|
"Decimal Separator": "Decimal Separator",
|
||||||
"Digit Grouping Symbol": "Digit Grouping Symbol",
|
"Digit Grouping Symbol": "Digit Grouping Symbol",
|
||||||
"Digit Grouping": "Digit Grouping",
|
"Digit Grouping": "Digit Grouping",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Dot",
|
"digitGroupingSymbol": "Dot",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Punto",
|
"Dot": "Punto",
|
||||||
"Comma": "Coma",
|
"Comma": "Coma",
|
||||||
"Space": "Espacio",
|
"Space": "Espacio",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Formato largo de hora",
|
"Long Time Format": "Formato largo de hora",
|
||||||
"Short Time Format": "Formato corto de hora",
|
"Short Time Format": "Formato corto de hora",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Separador decimal",
|
"Decimal Separator": "Separador decimal",
|
||||||
"Digit Grouping Symbol": "Símbolo de agrupación de dígitos",
|
"Digit Grouping Symbol": "Símbolo de agrupación de dígitos",
|
||||||
"Digit Grouping": "Agrupación de dígitos",
|
"Digit Grouping": "Agrupación de dígitos",
|
||||||
|
|||||||
+179
-83
@@ -32,10 +32,13 @@ import {
|
|||||||
} from '@/core/timezone.ts';
|
} from '@/core/timezone.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
type HiddenAmount,
|
||||||
type NumberFormatOptions,
|
type NumberFormatOptions,
|
||||||
|
type NumberWithSuffix,
|
||||||
type NumeralSymbolType,
|
type NumeralSymbolType,
|
||||||
type LocalizedNumeralSymbolType,
|
type LocalizedNumeralSymbolType,
|
||||||
type LocalizedDigitGroupingType,
|
type LocalizedDigitGroupingType,
|
||||||
|
NumeralSystem,
|
||||||
DecimalSeparator,
|
DecimalSeparator,
|
||||||
DigitGroupingSymbol,
|
DigitGroupingSymbol,
|
||||||
DigitGroupingType
|
DigitGroupingType
|
||||||
@@ -110,6 +113,7 @@ import {
|
|||||||
import type { LocaleDefaultSettings } from '@/core/setting.ts';
|
import type { LocaleDefaultSettings } from '@/core/setting.ts';
|
||||||
import type { ErrorResponse } from '@/core/api.ts';
|
import type { ErrorResponse } from '@/core/api.ts';
|
||||||
|
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||||
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
import { UTC_TIMEZONE, ALL_TIMEZONES } from '@/consts/timezone.ts';
|
||||||
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
import { ALL_CURRENCIES } from '@/consts/currency.ts';
|
||||||
import { DEFAULT_EXPENSE_CATEGORIES, DEFAULT_INCOME_CATEGORIES, DEFAULT_TRANSFER_CATEGORIES } from '@/consts/category.ts';
|
import { DEFAULT_EXPENSE_CATEGORIES, DEFAULT_INCOME_CATEGORIES, DEFAULT_TRANSFER_CATEGORIES } from '@/consts/category.ts';
|
||||||
@@ -156,9 +160,10 @@ import {
|
|||||||
} from '@/lib/datetime.ts';
|
} from '@/lib/datetime.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
appendDigitGroupingSymbol,
|
appendDigitGroupingSymbolAndDecimalSeparator,
|
||||||
parseAmount,
|
parseAmount,
|
||||||
formatAmount,
|
formatAmount,
|
||||||
|
formatHiddenAmount,
|
||||||
formatNumber,
|
formatNumber,
|
||||||
formatPercent,
|
formatPercent,
|
||||||
formatExchangeRateAmount,
|
formatExchangeRateAmount,
|
||||||
@@ -401,7 +406,7 @@ export function useI18n() {
|
|||||||
return localizedParameters;
|
return localizedParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllCurrencyDisplayTypes(): TypeAndDisplayName[] {
|
function getAllCurrencyDisplayTypes(numeralSystem: NumeralSystem, decimalSeparator: string): TypeAndDisplayName[] {
|
||||||
const defaultCurrencyDisplayTypeName = t('default.currencyDisplayType');
|
const defaultCurrencyDisplayTypeName = t('default.currencyDisplayType');
|
||||||
let defaultCurrencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
|
let defaultCurrencyDisplayType = CurrencyDisplayType.parse(defaultCurrencyDisplayTypeName);
|
||||||
|
|
||||||
@@ -412,7 +417,7 @@ export function useI18n() {
|
|||||||
const defaultCurrency = userStore.currentUserDefaultCurrency;
|
const defaultCurrency = userStore.currentUserDefaultCurrency;
|
||||||
|
|
||||||
const ret = [];
|
const ret = [];
|
||||||
const defaultSampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, false, defaultCurrencyDisplayType);
|
const defaultSampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, defaultCurrencyDisplayType, numeralSystem, decimalSeparator);
|
||||||
|
|
||||||
ret.push({
|
ret.push({
|
||||||
type: CurrencyDisplayType.LanguageDefaultType,
|
type: CurrencyDisplayType.LanguageDefaultType,
|
||||||
@@ -423,7 +428,7 @@ export function useI18n() {
|
|||||||
|
|
||||||
for (let i = 0; i < allCurrencyDisplayTypes.length; i++) {
|
for (let i = 0; i < allCurrencyDisplayTypes.length; i++) {
|
||||||
const type = allCurrencyDisplayTypes[i];
|
const type = allCurrencyDisplayTypes[i];
|
||||||
const sampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, false, type);
|
const sampleValue = getFormattedAmountWithCurrency(12345, defaultCurrency, type, numeralSystem, decimalSeparator);
|
||||||
const displayName = `${t(type.name)} (${sampleValue})`
|
const displayName = `${t(type.name)} (${sampleValue})`
|
||||||
|
|
||||||
ret.push({
|
ret.push({
|
||||||
@@ -587,12 +592,30 @@ export function useI18n() {
|
|||||||
return getLocalizedDateTimeFormat<ShortTimeFormat>('shortTime', ShortTimeFormat.all(), ShortTimeFormat.values(), userStore.currentUserShortTimeFormat, 'shortTimeFormat', ShortTimeFormat.Default);
|
return getLocalizedDateTimeFormat<ShortTimeFormat>('shortTime', ShortTimeFormat.all(), ShortTimeFormat.values(), userStore.currentUserShortTimeFormat, 'shortTimeFormat', ShortTimeFormat.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNumberFormatOptions(currencyCode?: string): NumberFormatOptions {
|
function getNumberFormatOptions({numeralSystem, digitGrouping, decimalSeparator, currencyCode}: {
|
||||||
|
numeralSystem?: NumeralSystem,
|
||||||
|
digitGrouping?: DigitGroupingType,
|
||||||
|
decimalSeparator?: string,
|
||||||
|
currencyCode?: string
|
||||||
|
}): NumberFormatOptions {
|
||||||
|
if (!isDefined(numeralSystem)) {
|
||||||
|
numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDefined(digitGrouping)) {
|
||||||
|
digitGrouping = getCurrentDigitGroupingType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isDefined(decimalSeparator)) {
|
||||||
|
decimalSeparator = getCurrentDecimalSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
decimalSeparator: getCurrentDecimalSeparator(),
|
numeralSystem: numeralSystem,
|
||||||
decimalNumberCount: getCurrencyFraction(currencyCode),
|
digitGrouping: digitGrouping,
|
||||||
digitGroupingSymbol: getCurrentDigitGroupingSymbol(),
|
digitGroupingSymbol: getCurrentDigitGroupingSymbol(),
|
||||||
digitGrouping: getCurrentDigitGroupingType(),
|
decimalSeparator: decimalSeparator,
|
||||||
|
decimalNumberCount: getCurrencyFraction(currencyCode),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,7 +767,7 @@ export function useI18n() {
|
|||||||
return [{
|
return [{
|
||||||
value: true,
|
value: true,
|
||||||
displayName: t('Enable')
|
displayName: t('Enable')
|
||||||
},{
|
}, {
|
||||||
value: false,
|
value: false,
|
||||||
displayName: t('Disable')
|
displayName: t('Disable')
|
||||||
}];
|
}];
|
||||||
@@ -766,7 +789,7 @@ export function useI18n() {
|
|||||||
allCurrencies.push(localizedCurrencyInfo);
|
allCurrencies.push(localizedCurrencyInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
allCurrencies.sort(function(c1, c2) {
|
allCurrencies.sort(function (c1, c2) {
|
||||||
return c1.displayName.localeCompare(c2.displayName);
|
return c1.displayName.localeCompare(c2.displayName);
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -965,7 +988,7 @@ export function useI18n() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
allTimezoneInfos.sort(function(c1, c2) {
|
allTimezoneInfos.sort(function (c1, c2) {
|
||||||
const utcOffset1 = parseInt(c1.utcOffset.replace(':', ''));
|
const utcOffset1 = parseInt(c1.utcOffset.replace(':', ''));
|
||||||
const utcOffset2 = parseInt(c2.utcOffset.replace(':', ''));
|
const utcOffset2 = parseInt(c2.utcOffset.replace(':', ''));
|
||||||
|
|
||||||
@@ -1030,7 +1053,36 @@ export function useI18n() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllDigitGroupingTypes(digitGroupingSymbol: string): LocalizedDigitGroupingType[] {
|
function getAllNumeralSystemTypes(): TypeAndDisplayName[] {
|
||||||
|
const defaultNumeralSystemTypeName = t('default.numeralSystem');
|
||||||
|
let defaultNumeralSystemType = NumeralSystem.parse(defaultNumeralSystemTypeName);
|
||||||
|
|
||||||
|
if (!defaultNumeralSystemType) {
|
||||||
|
defaultNumeralSystemType = NumeralSystem.Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ret: TypeAndDisplayName[] = [];
|
||||||
|
|
||||||
|
ret.push({
|
||||||
|
type: NumeralSystem.LanguageDefaultType,
|
||||||
|
displayName: `${t('Language Default')} (${defaultNumeralSystemType.textualAllDigits})`
|
||||||
|
});
|
||||||
|
|
||||||
|
const allNumeralSystemTypes = NumeralSystem.values();
|
||||||
|
|
||||||
|
for (let i = 0; i < allNumeralSystemTypes.length; i++) {
|
||||||
|
const type = allNumeralSystemTypes[i];
|
||||||
|
|
||||||
|
ret.push({
|
||||||
|
type: type.type,
|
||||||
|
displayName: `${t('numeral.' + type.name)} (${type.textualAllDigits})`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAllDigitGroupingTypes(numeralSystem: NumeralSystem, digitGroupingSymbol: string): LocalizedDigitGroupingType[] {
|
||||||
const defaultDigitGroupingTypeName = t('default.digitGrouping');
|
const defaultDigitGroupingTypeName = t('default.digitGrouping');
|
||||||
let defaultDigitGroupingType = DigitGroupingType.parse(defaultDigitGroupingTypeName);
|
let defaultDigitGroupingType = DigitGroupingType.parse(defaultDigitGroupingTypeName);
|
||||||
|
|
||||||
@@ -1047,10 +1099,11 @@ export function useI18n() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const allDigitGroupingTypes = DigitGroupingType.values();
|
const allDigitGroupingTypes = DigitGroupingType.values();
|
||||||
|
const numberCharacters = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits('123456789').split('');
|
||||||
|
|
||||||
for (let i = 0; i < allDigitGroupingTypes.length; i++) {
|
for (let i = 0; i < allDigitGroupingTypes.length; i++) {
|
||||||
const type = allDigitGroupingTypes[i];
|
const type = allDigitGroupingTypes[i];
|
||||||
const sampleValue = type.format('123456789'.split(''), digitGroupingSymbol);
|
const sampleValue = type.format(numberCharacters, digitGroupingSymbol);
|
||||||
|
|
||||||
ret.push({
|
ret.push({
|
||||||
type: type.type,
|
type: type.type,
|
||||||
@@ -1185,15 +1238,15 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.Name.type) {
|
if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.Name.type) {
|
||||||
availableExchangeRates.sort(function(c1, c2) {
|
availableExchangeRates.sort(function (c1, c2) {
|
||||||
return c1.currencyDisplayName.localeCompare(c2.currencyDisplayName);
|
return c1.currencyDisplayName.localeCompare(c2.currencyDisplayName);
|
||||||
});
|
});
|
||||||
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.CurrencyCode.type) {
|
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.CurrencyCode.type) {
|
||||||
availableExchangeRates.sort(function(c1, c2) {
|
availableExchangeRates.sort(function (c1, c2) {
|
||||||
return c1.currencyCode.localeCompare(c2.currencyCode);
|
return c1.currencyCode.localeCompare(c2.currencyCode);
|
||||||
});
|
});
|
||||||
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.ExchangeRate.type) {
|
} else if (settingsStore.appSettings.currencySortByInExchangeRatesPage === CurrencySortingType.ExchangeRate.type) {
|
||||||
availableExchangeRates.sort(function(c1, c2) {
|
availableExchangeRates.sort(function (c1, c2) {
|
||||||
const rate1 = parseFloat(c1.rate);
|
const rate1 = parseFloat(c1.rate);
|
||||||
const rate2 = parseFloat(c2.rate);
|
const rate2 = parseFloat(c2.rate);
|
||||||
|
|
||||||
@@ -1382,6 +1435,26 @@ export function useI18n() {
|
|||||||
return joinMultiText(finalWeekdayNames);
|
return joinMultiText(finalWeekdayNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllLocalizedDigits(): string[] {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
return numeralSystem.getAllDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentNumeralSystemType(): NumeralSystem {
|
||||||
|
let numeralSystemType = NumeralSystem.valueOf(userStore.currentUserNumeralSystem);
|
||||||
|
|
||||||
|
if (!numeralSystemType) {
|
||||||
|
const defaultNumeralSystemTypeName = t('default.numeralSystem');
|
||||||
|
numeralSystemType = NumeralSystem.parse(defaultNumeralSystemTypeName);
|
||||||
|
|
||||||
|
if (!numeralSystemType) {
|
||||||
|
numeralSystemType = NumeralSystem.Default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return numeralSystemType;
|
||||||
|
}
|
||||||
|
|
||||||
function getCurrentDecimalSeparator(): string {
|
function getCurrentDecimalSeparator(): string {
|
||||||
let decimalSeparatorType = DecimalSeparator.valueOf(userStore.currentUserDecimalSeparator);
|
let decimalSeparatorType = DecimalSeparator.valueOf(userStore.currentUserDecimalSeparator);
|
||||||
|
|
||||||
@@ -1412,7 +1485,7 @@ export function useI18n() {
|
|||||||
return digitGroupingSymbolType.symbol;
|
return digitGroupingSymbolType.symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentDigitGroupingType(): number {
|
function getCurrentDigitGroupingType(): DigitGroupingType {
|
||||||
let digitGroupingType = DigitGroupingType.valueOf(userStore.currentUserDigitGrouping);
|
let digitGroupingType = DigitGroupingType.valueOf(userStore.currentUserDigitGrouping);
|
||||||
|
|
||||||
if (!digitGroupingType) {
|
if (!digitGroupingType) {
|
||||||
@@ -1424,7 +1497,7 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return digitGroupingType.type;
|
return digitGroupingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentFiscalYearFormatType(): number {
|
function getCurrentFiscalYearFormatType(): number {
|
||||||
@@ -1443,6 +1516,10 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getCurrencyName(currencyCode: string): string {
|
function getCurrencyName(currencyCode: string): string {
|
||||||
|
if (!currencyCode) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
return t(`currency.name.${currencyCode}`);
|
return t(`currency.name.${currencyCode}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1633,44 +1710,17 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNumberWithDigitGroupingSymbol(value: number | string): string {
|
function getParsedAmountNumber(value: string, numeralSystem?: NumeralSystem): number {
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem });
|
||||||
return appendDigitGroupingSymbol(value, numberFormatOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getParsedAmountNumber(value: string): number {
|
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
|
||||||
return parseAmount(value, numberFormatOptions);
|
return parseAmount(value, numberFormatOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedAmount(value: number | string, currencyCode?: string): string {
|
function getFormattedAmount(value: number, numeralSystem?: NumeralSystem, digitGrouping?: DigitGroupingType, currencyCode?: string): string {
|
||||||
const numberFormatOptions = getNumberFormatOptions(currencyCode);
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem, digitGrouping, currencyCode });
|
||||||
return formatAmount(value, numberFormatOptions);
|
return formatAmount(value, numberFormatOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedAmountWithCurrency(value: number | string, currencyCode?: string | false, notConvertValue?: boolean, currencyDisplayType?: CurrencyDisplayType): string {
|
function getFormattedAmountWithCurrency(value: number | HiddenAmount | NumberWithSuffix, currencyCode?: string | false, currencyDisplayType?: CurrencyDisplayType, numeralSystem?: NumeralSystem, decimalSeparator?: string): string {
|
||||||
if (isNumber(value)) {
|
|
||||||
value = value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
let textualValue = value;
|
|
||||||
const isPlural: boolean = textualValue !== '100' && textualValue !== '-100';
|
|
||||||
|
|
||||||
if (!notConvertValue) {
|
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
|
||||||
const hasIncompleteFlag = isString(textualValue) && textualValue.charAt(textualValue.length - 1) === '+';
|
|
||||||
|
|
||||||
if (hasIncompleteFlag) {
|
|
||||||
textualValue = textualValue.substring(0, textualValue.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
textualValue = formatAmount(textualValue, numberFormatOptions);
|
|
||||||
|
|
||||||
if (hasIncompleteFlag) {
|
|
||||||
textualValue = textualValue + '+';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let finalCurrencyCode = '';
|
let finalCurrencyCode = '';
|
||||||
|
|
||||||
if (!isBoolean(currencyCode) && !currencyCode) {
|
if (!isBoolean(currencyCode) && !currencyCode) {
|
||||||
@@ -1681,36 +1731,74 @@ export function useI18n() {
|
|||||||
finalCurrencyCode = currencyCode;
|
finalCurrencyCode = currencyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!finalCurrencyCode) {
|
|
||||||
return textualValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currencyDisplayType) {
|
if (!currencyDisplayType) {
|
||||||
currencyDisplayType = getCurrentCurrencyDisplayType();
|
currencyDisplayType = getCurrentCurrencyDisplayType();
|
||||||
}
|
}
|
||||||
|
|
||||||
const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
|
if (!numeralSystem) {
|
||||||
|
numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
}
|
||||||
|
|
||||||
|
let suffix = '';
|
||||||
|
|
||||||
|
if (isObject(value) && isNumber(value.value) && isString(value.suffix)) {
|
||||||
|
suffix = value.suffix;
|
||||||
|
value = value.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem, decimalSeparator, currencyCode: finalCurrencyCode });
|
||||||
const currencyName = getCurrencyName(finalCurrencyCode);
|
const currencyName = getCurrencyName(finalCurrencyCode);
|
||||||
return appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
|
|
||||||
|
if (isNumber(value)) {
|
||||||
|
const isPlural: boolean = value !== 100 && value !== -100;
|
||||||
|
const textualValue = formatAmount(value, numberFormatOptions);
|
||||||
|
|
||||||
|
if (!finalCurrencyCode) {
|
||||||
|
return textualValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
|
||||||
|
const ret = appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
|
||||||
|
|
||||||
|
if (suffix) {
|
||||||
|
return ret + suffix;
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else if (isString(value)) {
|
||||||
|
const isPlural: boolean = true;
|
||||||
|
const textualValue = formatHiddenAmount(value, numberFormatOptions);
|
||||||
|
|
||||||
|
if (!finalCurrencyCode) {
|
||||||
|
return textualValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
|
||||||
|
return appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedNumber(value: number, precision: number): string {
|
function getFormattedNumber(value: number, numeralSystem?: NumeralSystem, precision?: number): string {
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem, digitGrouping: DigitGroupingType.None });
|
||||||
return formatNumber(value, precision, numberFormatOptions);
|
return formatNumber(value, numberFormatOptions, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedPercentValue(value: number, precision: number, lowPrecisionValue: string): string {
|
function getFormattedPercentValue(value: number, precision: number, lowPrecisionValue: string, numeralSystem?: NumeralSystem): string {
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem });
|
||||||
return formatPercent(value, precision, lowPrecisionValue, numberFormatOptions);
|
return formatPercent(value, precision, lowPrecisionValue, numberFormatOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormattedExchangeRateAmount(value: number | string): string {
|
function getFormattedExchangeRateAmount(value: number, numeralSystem?: NumeralSystem): string {
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
const numberFormatOptions = getNumberFormatOptions({ numeralSystem });
|
||||||
return formatExchangeRateAmount(value, numberFormatOptions);
|
return formatExchangeRateAmount(value, numberFormatOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAdaptiveAmountRate(amount1: number, amount2: number, fromExchangeRate: { rate: string }, toExchangeRate: { rate: string }): string | null {
|
function getAdaptiveAmountRate(amount1: number, amount2: number, fromExchangeRate: {
|
||||||
const numberFormatOptions = getNumberFormatOptions();
|
rate: string
|
||||||
|
}, toExchangeRate: { rate: string }): string | null {
|
||||||
|
const numberFormatOptions = getNumberFormatOptions({});
|
||||||
return getAdaptiveDisplayAmountRate(amount1, amount2, fromExchangeRate, toExchangeRate, numberFormatOptions);
|
return getAdaptiveDisplayAmountRate(amount1, amount2, fromExchangeRate, toExchangeRate, numberFormatOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1747,7 +1835,7 @@ export function useI18n() {
|
|||||||
} else if (showAccountBalance && account.isLiability) {
|
} else if (showAccountBalance && account.isLiability) {
|
||||||
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, getFormattedAmountWithCurrency(-account.balance, account.currency));
|
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, getFormattedAmountWithCurrency(-account.balance, account.currency));
|
||||||
} else {
|
} else {
|
||||||
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, '***');
|
accountWithDisplaceBalance = AccountWithDisplayBalance.fromAccount(account, DISPLAY_HIDDEN_AMOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
accountsWithDisplayBalance.push(accountWithDisplaceBalance);
|
accountsWithDisplayBalance.push(accountWithDisplaceBalance);
|
||||||
@@ -1784,15 +1872,13 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
finalTotalBalance = totalBalance.toString();
|
finalTotalBalance = getFormattedAmountWithCurrency(totalBalance, defaultCurrency);
|
||||||
|
|
||||||
if (hasUnCalculatedAmount) {
|
if (hasUnCalculatedAmount) {
|
||||||
finalTotalBalance = finalTotalBalance + '+';
|
finalTotalBalance = finalTotalBalance + INCOMPLETE_AMOUNT_SUFFIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalTotalBalance = getFormattedAmountWithCurrency(finalTotalBalance, defaultCurrency);
|
|
||||||
} else {
|
} else {
|
||||||
finalTotalBalance = '***';
|
finalTotalBalance = DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountCategoryWithDisplayBalance = CategorizedAccountWithDisplayBalance.of(accountCategory, accountsWithDisplayBalance, finalTotalBalance);
|
const accountCategoryWithDisplayBalance = CategorizedAccountWithDisplayBalance.of(accountCategory, accountsWithDisplayBalance, finalTotalBalance);
|
||||||
@@ -1822,11 +1908,11 @@ export function useI18n() {
|
|||||||
|
|
||||||
locale.value = languageKey;
|
locale.value = languageKey;
|
||||||
moment.updateLocale(languageKey, {
|
moment.updateLocale(languageKey, {
|
||||||
months : getAllLongMonthNames(),
|
months: getAllLongMonthNames(),
|
||||||
monthsShort : getAllShortMonthNames(),
|
monthsShort: getAllShortMonthNames(),
|
||||||
weekdays : getAllLongWeekdayNames(),
|
weekdays: getAllLongWeekdayNames(),
|
||||||
weekdaysShort : getAllShortWeekdayNames(),
|
weekdaysShort: getAllShortWeekdayNames(),
|
||||||
weekdaysMin : getAllMinWeekdayNames(),
|
weekdaysMin: getAllMinWeekdayNames(),
|
||||||
meridiem: function (hours) {
|
meridiem: function (hours) {
|
||||||
if (isPM(hours)) {
|
if (isPM(hours)) {
|
||||||
return t(`datetime.${MeridiemIndicator.PM.name}.content`);
|
return t(`datetime.${MeridiemIndicator.PM.name}.content`);
|
||||||
@@ -1924,6 +2010,7 @@ export function useI18n() {
|
|||||||
getAllRecentMonthDateRanges,
|
getAllRecentMonthDateRanges,
|
||||||
getAllTimezones,
|
getAllTimezones,
|
||||||
getAllTimezoneTypesUsedForStatistics,
|
getAllTimezoneTypesUsedForStatistics,
|
||||||
|
getAllNumeralSystemTypes,
|
||||||
getAllDecimalSeparators: () => getLocalizedNumeralSeparatorFormats(DecimalSeparator.values(), DecimalSeparator.parse(t('default.decimalSeparator')), DecimalSeparator.Default, DecimalSeparator.LanguageDefaultType),
|
getAllDecimalSeparators: () => getLocalizedNumeralSeparatorFormats(DecimalSeparator.values(), DecimalSeparator.parse(t('default.decimalSeparator')), DecimalSeparator.Default, DecimalSeparator.LanguageDefaultType),
|
||||||
getAllDigitGroupingSymbols: () => getLocalizedNumeralSeparatorFormats(DigitGroupingSymbol.values(), DigitGroupingSymbol.parse(t('default.digitGroupingSymbol')), DigitGroupingSymbol.Default, DigitGroupingSymbol.LanguageDefaultType),
|
getAllDigitGroupingSymbols: () => getLocalizedNumeralSeparatorFormats(DigitGroupingSymbol.values(), DigitGroupingSymbol.parse(t('default.digitGroupingSymbol')), DigitGroupingSymbol.Default, DigitGroupingSymbol.LanguageDefaultType),
|
||||||
getAllDigitGroupingTypes,
|
getAllDigitGroupingTypes,
|
||||||
@@ -1958,7 +2045,9 @@ export function useI18n() {
|
|||||||
getWeekdayLongName,
|
getWeekdayLongName,
|
||||||
getMultiMonthdayShortNames,
|
getMultiMonthdayShortNames,
|
||||||
getMultiWeekdayLongNames,
|
getMultiWeekdayLongNames,
|
||||||
|
getAllLocalizedDigits,
|
||||||
getCurrentFiscalYearFormatType,
|
getCurrentFiscalYearFormatType,
|
||||||
|
getCurrentNumeralSystemType,
|
||||||
getCurrentDecimalSeparator,
|
getCurrentDecimalSeparator,
|
||||||
getCurrentDigitGroupingSymbol,
|
getCurrentDigitGroupingSymbol,
|
||||||
getCurrentDigitGroupingType,
|
getCurrentDigitGroupingType,
|
||||||
@@ -1997,13 +2086,20 @@ export function useI18n() {
|
|||||||
formatUnixTimeToFiscalYear,
|
formatUnixTimeToFiscalYear,
|
||||||
formatYearToFiscalYear,
|
formatYearToFiscalYear,
|
||||||
getTimezoneDifferenceDisplayText,
|
getTimezoneDifferenceDisplayText,
|
||||||
appendDigitGroupingSymbol: getNumberWithDigitGroupingSymbol,
|
parseAmountFromLocalizedNumerals: (value: string) => getParsedAmountNumber(value),
|
||||||
parseAmount: getParsedAmountNumber,
|
parseAmountFromWesternArabicNumerals: (value: string) => getParsedAmountNumber(value, NumeralSystem.WesternArabicNumerals),
|
||||||
formatAmount: getFormattedAmount,
|
formatAmountToLocalizedNumerals: (value: number, currencyCode?: string) => getFormattedAmount(value, undefined, undefined, currencyCode),
|
||||||
formatAmountWithCurrency: getFormattedAmountWithCurrency,
|
formatAmountToWesternArabicNumerals: (value: number, currencyCode?: string) => getFormattedAmount(value, NumeralSystem.WesternArabicNumerals, undefined, currencyCode),
|
||||||
formatNumber: getFormattedNumber,
|
formatAmountToLocalizedNumeralsWithoutDigitGrouping: (value: number, currencyCode?: string) => getFormattedAmount(value, undefined, DigitGroupingType.None, currencyCode),
|
||||||
formatPercent: getFormattedPercentValue,
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping: (value: number, currencyCode?: string) => getFormattedAmount(value, NumeralSystem.WesternArabicNumerals, DigitGroupingType.None, currencyCode),
|
||||||
formatExchangeRateAmount: getFormattedExchangeRateAmount,
|
formatAmountToLocalizedNumeralsWithCurrency: (value: number | HiddenAmount | NumberWithSuffix, currencyCode?: string | false, currencyDisplayType?: CurrencyDisplayType) => getFormattedAmountWithCurrency(value, currencyCode, currencyDisplayType),
|
||||||
|
formatAmountToWesternArabicNumeralsWithCurrency: (value: number | HiddenAmount | NumberWithSuffix, currencyCode?: string | false, currencyDisplayType?: CurrencyDisplayType) => getFormattedAmountWithCurrency(value, currencyCode, currencyDisplayType, NumeralSystem.WesternArabicNumerals),
|
||||||
|
formatNumberToLocalizedNumerals: (value: number, precision?: number) => getFormattedNumber(value, undefined, precision),
|
||||||
|
formatNumberToWesternArabicNumerals: (value: number, precision?: number) => getFormattedNumber(value, NumeralSystem.WesternArabicNumerals, precision),
|
||||||
|
formatPercentToLocalizedNumerals: (value: number, precision: number, lowPrecisionValue: string) => getFormattedPercentValue(value, precision, lowPrecisionValue),
|
||||||
|
formatPercentToWesternArabicNumerals: (value: number, precision: number, lowPrecisionValue: string) => getFormattedPercentValue(value, precision, lowPrecisionValue, NumeralSystem.WesternArabicNumerals),
|
||||||
|
formatExchangeRateAmountToWesternArabicNumerals: (value: number) => getFormattedExchangeRateAmount(value, NumeralSystem.WesternArabicNumerals),
|
||||||
|
appendDigitGroupingSymbolAndDecimalSeparator: (value: string) => appendDigitGroupingSymbolAndDecimalSeparator(value, getNumberFormatOptions({})),
|
||||||
getAdaptiveAmountRate,
|
getAdaptiveAmountRate,
|
||||||
getAmountPrependAndAppendText,
|
getAmountPrependAndAppendText,
|
||||||
getCategorizedAccountsWithDisplayBalance,
|
getCategorizedAccountsWithDisplayBalance,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Dot",
|
"digitGroupingSymbol": "Dot",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Punto",
|
"Dot": "Punto",
|
||||||
"Comma": "Virgola",
|
"Comma": "Virgola",
|
||||||
"Space": "Spazio",
|
"Space": "Spazio",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Formato ora lungo",
|
"Long Time Format": "Formato ora lungo",
|
||||||
"Short Time Format": "Formato ora breve",
|
"Short Time Format": "Formato ora breve",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Separatore decimale",
|
"Decimal Separator": "Separatore decimale",
|
||||||
"Digit Grouping Symbol": "Simbolo di raggruppamento cifre",
|
"Digit Grouping Symbol": "Simbolo di raggruppamento cifre",
|
||||||
"Digit Grouping": "Raggruppamento cifre",
|
"Digit Grouping": "Raggruppamento cifre",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "YYYYMMDD",
|
"shortDateFormat": "YYYYMMDD",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Dot",
|
"decimalSeparator": "Dot",
|
||||||
"digitGroupingSymbol": "Comma",
|
"digitGroupingSymbol": "Comma",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "ドット",
|
"Dot": "ドット",
|
||||||
"Comma": "コンマ",
|
"Comma": "コンマ",
|
||||||
"Space": "スペース",
|
"Space": "スペース",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "長い時間形式",
|
"Long Time Format": "長い時間形式",
|
||||||
"Short Time Format": "短い時間形式",
|
"Short Time Format": "短い時間形式",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "小数点",
|
"Decimal Separator": "小数点",
|
||||||
"Digit Grouping Symbol": "桁区切り記号",
|
"Digit Grouping Symbol": "桁区切り記号",
|
||||||
"Digit Grouping": "桁区切り位置",
|
"Digit Grouping": "桁区切り位置",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Dot",
|
"digitGroupingSymbol": "Dot",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Dagelijks"
|
"Daily": "Dagelijks"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Punt",
|
"Dot": "Punt",
|
||||||
"Comma": "Komma",
|
"Comma": "Komma",
|
||||||
"Space": "Spatie",
|
"Space": "Spatie",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Lang tijdsformaat",
|
"Long Time Format": "Lang tijdsformaat",
|
||||||
"Short Time Format": "Kort tijdsformaat",
|
"Short Time Format": "Kort tijdsformaat",
|
||||||
"Fiscal Year Format": "Boekjaarformaat",
|
"Fiscal Year Format": "Boekjaarformaat",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Decimaalteken",
|
"Decimal Separator": "Decimaalteken",
|
||||||
"Digit Grouping Symbol": "Scheidingsteken voor duizendtallen",
|
"Digit Grouping Symbol": "Scheidingsteken voor duizendtallen",
|
||||||
"Digit Grouping": "Groeperen van cijfers",
|
"Digit Grouping": "Groeperen van cijfers",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Space",
|
"digitGroupingSymbol": "Space",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Ponto",
|
"Dot": "Ponto",
|
||||||
"Comma": "Vírgula",
|
"Comma": "Vírgula",
|
||||||
"Space": "Espaço",
|
"Space": "Espaço",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Formato de Hora Longa",
|
"Long Time Format": "Formato de Hora Longa",
|
||||||
"Short Time Format": "Formato de Hora Curta",
|
"Short Time Format": "Formato de Hora Curta",
|
||||||
"Fiscal Year Format": "Formato do Ano Fiscal",
|
"Fiscal Year Format": "Formato do Ano Fiscal",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Separador Decimal",
|
"Decimal Separator": "Separador Decimal",
|
||||||
"Digit Grouping Symbol": "Símbolo de Agrupamento de Dígitos",
|
"Digit Grouping Symbol": "Símbolo de Agrupamento de Dígitos",
|
||||||
"Digit Grouping": "Agrupamento de Dígitos",
|
"Digit Grouping": "Agrupamento de Dígitos",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Space",
|
"digitGroupingSymbol": "Space",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Точка",
|
"Dot": "Точка",
|
||||||
"Comma": "Запятая",
|
"Comma": "Запятая",
|
||||||
"Space": "Пробел",
|
"Space": "Пробел",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Длинный формат времени",
|
"Long Time Format": "Длинный формат времени",
|
||||||
"Short Time Format": "Короткий формат времени",
|
"Short Time Format": "Короткий формат времени",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Разделитель десятичных",
|
"Decimal Separator": "Разделитель десятичных",
|
||||||
"Digit Grouping Symbol": "Символ группировки цифр",
|
"Digit Grouping Symbol": "Символ группировки цифр",
|
||||||
"Digit Grouping": "Группировка цифр",
|
"Digit Grouping": "Группировка цифр",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Space",
|
"digitGroupingSymbol": "Space",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Крапка",
|
"Dot": "Крапка",
|
||||||
"Comma": "Кома",
|
"Comma": "Кома",
|
||||||
"Space": "Пробіл",
|
"Space": "Пробіл",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Довгий формат часу",
|
"Long Time Format": "Довгий формат часу",
|
||||||
"Short Time Format": "Короткий формат часу",
|
"Short Time Format": "Короткий формат часу",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Десятковий роздільник",
|
"Decimal Separator": "Десятковий роздільник",
|
||||||
"Digit Grouping Symbol": "Символ групування цифр",
|
"Digit Grouping Symbol": "Символ групування цифр",
|
||||||
"Digit Grouping": "Групування цифр",
|
"Digit Grouping": "Групування цифр",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "DDMMYYYY",
|
"shortDateFormat": "DDMMYYYY",
|
||||||
"longTimeFormat": "HHMMSSA",
|
"longTimeFormat": "HHMMSSA",
|
||||||
"shortTimeFormat": "HHMMA",
|
"shortTimeFormat": "HHMMA",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Comma",
|
"decimalSeparator": "Comma",
|
||||||
"digitGroupingSymbol": "Dot",
|
"digitGroupingSymbol": "Dot",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "Daily"
|
"Daily": "Daily"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "Western Arabic Numerals",
|
||||||
|
"Eastern Arabic Numerals": "Eastern Arabic Numerals",
|
||||||
|
"Persian Digits": "Persian Digits",
|
||||||
|
"Burmese Numerals": "Burmese Numerals",
|
||||||
|
"Devanagari Numerals": "Devanagari Numerals",
|
||||||
"Dot": "Dấu chấm",
|
"Dot": "Dấu chấm",
|
||||||
"Comma": "Dấu phẩy",
|
"Comma": "Dấu phẩy",
|
||||||
"Space": "Khoảng trắng",
|
"Space": "Khoảng trắng",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "Định dạng thời gian dài",
|
"Long Time Format": "Định dạng thời gian dài",
|
||||||
"Short Time Format": "Định dạng thời gian ngắn",
|
"Short Time Format": "Định dạng thời gian ngắn",
|
||||||
"Fiscal Year Format": "Fiscal Year Format",
|
"Fiscal Year Format": "Fiscal Year Format",
|
||||||
|
"Numeral System": "Numeral System",
|
||||||
"Decimal Separator": "Dấu phân cách thập phân",
|
"Decimal Separator": "Dấu phân cách thập phân",
|
||||||
"Digit Grouping Symbol": "Ký hiệu nhóm chữ số",
|
"Digit Grouping Symbol": "Ký hiệu nhóm chữ số",
|
||||||
"Digit Grouping": "Nhóm chữ số",
|
"Digit Grouping": "Nhóm chữ số",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "YYYYMMDD",
|
"shortDateFormat": "YYYYMMDD",
|
||||||
"longTimeFormat": "HHMMSS",
|
"longTimeFormat": "HHMMSS",
|
||||||
"shortTimeFormat": "HHMM",
|
"shortTimeFormat": "HHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Dot",
|
"decimalSeparator": "Dot",
|
||||||
"digitGroupingSymbol": "Comma",
|
"digitGroupingSymbol": "Comma",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "按天"
|
"Daily": "按天"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "阿拉伯数字",
|
||||||
|
"Eastern Arabic Numerals": "东阿拉伯数字",
|
||||||
|
"Persian Digits": "波斯数字",
|
||||||
|
"Burmese Numerals": "缅甸数字",
|
||||||
|
"Devanagari Numerals": "天城文数字",
|
||||||
"Dot": "句点",
|
"Dot": "句点",
|
||||||
"Comma": "逗号",
|
"Comma": "逗号",
|
||||||
"Space": "空格",
|
"Space": "空格",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "长时间格式",
|
"Long Time Format": "长时间格式",
|
||||||
"Short Time Format": "短时间格式",
|
"Short Time Format": "短时间格式",
|
||||||
"Fiscal Year Format": "财年格式",
|
"Fiscal Year Format": "财年格式",
|
||||||
|
"Numeral System": "数字系统",
|
||||||
"Decimal Separator": "小数点",
|
"Decimal Separator": "小数点",
|
||||||
"Digit Grouping Symbol": "数字分组符号",
|
"Digit Grouping Symbol": "数字分组符号",
|
||||||
"Digit Grouping": "数字分组",
|
"Digit Grouping": "数字分组",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"shortDateFormat": "YYYYMMDD",
|
"shortDateFormat": "YYYYMMDD",
|
||||||
"longTimeFormat": "AHHMMSS",
|
"longTimeFormat": "AHHMMSS",
|
||||||
"shortTimeFormat": "AHHMM",
|
"shortTimeFormat": "AHHMM",
|
||||||
|
"numeralSystem": "WesternArabicNumerals",
|
||||||
"decimalSeparator": "Dot",
|
"decimalSeparator": "Dot",
|
||||||
"digitGroupingSymbol": "Comma",
|
"digitGroupingSymbol": "Comma",
|
||||||
"digitGrouping": "ThousandsSeparator",
|
"digitGrouping": "ThousandsSeparator",
|
||||||
@@ -260,6 +261,11 @@
|
|||||||
"Daily": "依日期"
|
"Daily": "依日期"
|
||||||
},
|
},
|
||||||
"numeral": {
|
"numeral": {
|
||||||
|
"Western Arabic Numerals": "阿拉伯數字",
|
||||||
|
"Eastern Arabic Numerals": "東阿拉伯數字",
|
||||||
|
"Persian Digits": "波斯數字",
|
||||||
|
"Burmese Numerals": "緬甸數字",
|
||||||
|
"Devanagari Numerals": "天城文數字",
|
||||||
"Dot": "句點",
|
"Dot": "句點",
|
||||||
"Comma": "逗號",
|
"Comma": "逗號",
|
||||||
"Space": "空格",
|
"Space": "空格",
|
||||||
@@ -1497,6 +1503,7 @@
|
|||||||
"Long Time Format": "長時間格式",
|
"Long Time Format": "長時間格式",
|
||||||
"Short Time Format": "短時間格式",
|
"Short Time Format": "短時間格式",
|
||||||
"Fiscal Year Format": "財政年度格式",
|
"Fiscal Year Format": "財政年度格式",
|
||||||
|
"Numeral System": "數字系統",
|
||||||
"Decimal Separator": "小數點",
|
"Decimal Separator": "小數點",
|
||||||
"Digit Grouping Symbol": "數字分組符號",
|
"Digit Grouping Symbol": "數字分組符號",
|
||||||
"Digit Grouping": "數字分組",
|
"Digit Grouping": "數字分組",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { HiddenAmount, NumberWithSuffix } from '@/core/numeral.ts';
|
||||||
import type { ColorValue } from '@/core/color.ts';
|
import type { ColorValue } from '@/core/color.ts';
|
||||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||||
import { PARENT_ACCOUNT_CURRENCY_PLACEHOLDER } from '@/consts/currency.ts';
|
import { PARENT_ACCOUNT_CURRENCY_PLACEHOLDER } from '@/consts/currency.ts';
|
||||||
@@ -638,7 +639,7 @@ export interface AccountBalance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AccountDisplayBalance {
|
export interface AccountDisplayBalance {
|
||||||
readonly balance: string;
|
readonly balance: number | HiddenAmount | NumberWithSuffix;
|
||||||
readonly currency: string;
|
readonly currency: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-8
@@ -1,5 +1,5 @@
|
|||||||
import { LongDateFormat, ShortDateFormat, LongTimeFormat, ShortTimeFormat } from '@/core/datetime.ts';
|
import { LongDateFormat, ShortDateFormat, LongTimeFormat, ShortTimeFormat } from '@/core/datetime.ts';
|
||||||
import { DecimalSeparator, DigitGroupingSymbol, DigitGroupingType } from '@/core/numeral.ts';
|
import { NumeralSystem, DecimalSeparator, DigitGroupingSymbol, DigitGroupingType } from '@/core/numeral.ts';
|
||||||
import { CurrencyDisplayType } from '@/core/currency.ts';
|
import { CurrencyDisplayType } from '@/core/currency.ts';
|
||||||
import { CoordinateDisplayType } from '@/core/coordinate.ts';
|
import { CoordinateDisplayType } from '@/core/coordinate.ts';
|
||||||
import { PresetAmountColor } from '@/core/color.ts';
|
import { PresetAmountColor } from '@/core/color.ts';
|
||||||
@@ -25,10 +25,11 @@ export class User {
|
|||||||
public longTimeFormat: number = EMPTY_USER_BASIC_INFO.longTimeFormat;
|
public longTimeFormat: number = EMPTY_USER_BASIC_INFO.longTimeFormat;
|
||||||
public shortTimeFormat: number = EMPTY_USER_BASIC_INFO.shortTimeFormat;
|
public shortTimeFormat: number = EMPTY_USER_BASIC_INFO.shortTimeFormat;
|
||||||
public fiscalYearFormat: number = EMPTY_USER_BASIC_INFO.fiscalYearFormat;
|
public fiscalYearFormat: number = EMPTY_USER_BASIC_INFO.fiscalYearFormat;
|
||||||
|
public currencyDisplayType: number = EMPTY_USER_BASIC_INFO.currencyDisplayType;
|
||||||
|
public numeralSystem: number = EMPTY_USER_BASIC_INFO.numeralSystem;
|
||||||
public decimalSeparator: number = EMPTY_USER_BASIC_INFO.decimalSeparator;
|
public decimalSeparator: number = EMPTY_USER_BASIC_INFO.decimalSeparator;
|
||||||
public digitGroupingSymbol: number = EMPTY_USER_BASIC_INFO.digitGroupingSymbol;
|
public digitGroupingSymbol: number = EMPTY_USER_BASIC_INFO.digitGroupingSymbol;
|
||||||
public digitGrouping: number = EMPTY_USER_BASIC_INFO.digitGrouping;
|
public digitGrouping: number = EMPTY_USER_BASIC_INFO.digitGrouping;
|
||||||
public currencyDisplayType: number = EMPTY_USER_BASIC_INFO.currencyDisplayType;
|
|
||||||
public coordinateDisplayType: number = EMPTY_USER_BASIC_INFO.coordinateDisplayType;
|
public coordinateDisplayType: number = EMPTY_USER_BASIC_INFO.coordinateDisplayType;
|
||||||
public expenseAmountColor: number = EMPTY_USER_BASIC_INFO.expenseAmountColor;
|
public expenseAmountColor: number = EMPTY_USER_BASIC_INFO.expenseAmountColor;
|
||||||
public incomeAmountColor: number = EMPTY_USER_BASIC_INFO.incomeAmountColor;
|
public incomeAmountColor: number = EMPTY_USER_BASIC_INFO.incomeAmountColor;
|
||||||
@@ -54,10 +55,11 @@ export class User {
|
|||||||
this.longTimeFormat = user.longTimeFormat;
|
this.longTimeFormat = user.longTimeFormat;
|
||||||
this.shortTimeFormat = user.shortTimeFormat;
|
this.shortTimeFormat = user.shortTimeFormat;
|
||||||
this.fiscalYearFormat = user.fiscalYearFormat;
|
this.fiscalYearFormat = user.fiscalYearFormat;
|
||||||
|
this.currencyDisplayType = user.currencyDisplayType;
|
||||||
|
this.numeralSystem = user.numeralSystem;
|
||||||
this.decimalSeparator = user.decimalSeparator;
|
this.decimalSeparator = user.decimalSeparator;
|
||||||
this.digitGroupingSymbol = user.digitGroupingSymbol;
|
this.digitGroupingSymbol = user.digitGroupingSymbol;
|
||||||
this.digitGrouping = user.digitGrouping;
|
this.digitGrouping = user.digitGrouping;
|
||||||
this.currencyDisplayType = user.currencyDisplayType;
|
|
||||||
this.coordinateDisplayType = user.coordinateDisplayType;
|
this.coordinateDisplayType = user.coordinateDisplayType;
|
||||||
this.expenseAmountColor = user.expenseAmountColor;
|
this.expenseAmountColor = user.expenseAmountColor;
|
||||||
this.incomeAmountColor = user.incomeAmountColor;
|
this.incomeAmountColor = user.incomeAmountColor;
|
||||||
@@ -93,10 +95,11 @@ export class User {
|
|||||||
longTimeFormat: this.longTimeFormat,
|
longTimeFormat: this.longTimeFormat,
|
||||||
shortTimeFormat: this.shortTimeFormat,
|
shortTimeFormat: this.shortTimeFormat,
|
||||||
fiscalYearFormat: this.fiscalYearFormat,
|
fiscalYearFormat: this.fiscalYearFormat,
|
||||||
|
currencyDisplayType: this.currencyDisplayType,
|
||||||
|
numeralSystem: this.numeralSystem,
|
||||||
decimalSeparator: this.decimalSeparator,
|
decimalSeparator: this.decimalSeparator,
|
||||||
digitGroupingSymbol: this.digitGroupingSymbol,
|
digitGroupingSymbol: this.digitGroupingSymbol,
|
||||||
digitGrouping: this.digitGrouping,
|
digitGrouping: this.digitGrouping,
|
||||||
currencyDisplayType: this.currencyDisplayType,
|
|
||||||
coordinateDisplayType: this.coordinateDisplayType,
|
coordinateDisplayType: this.coordinateDisplayType,
|
||||||
expenseAmountColor: this.expenseAmountColor,
|
expenseAmountColor: this.expenseAmountColor,
|
||||||
incomeAmountColor: this.incomeAmountColor
|
incomeAmountColor: this.incomeAmountColor
|
||||||
@@ -113,10 +116,11 @@ export class User {
|
|||||||
user.longTimeFormat = userInfo.longTimeFormat;
|
user.longTimeFormat = userInfo.longTimeFormat;
|
||||||
user.shortTimeFormat = userInfo.shortTimeFormat;
|
user.shortTimeFormat = userInfo.shortTimeFormat;
|
||||||
user.fiscalYearFormat = userInfo.fiscalYearFormat;
|
user.fiscalYearFormat = userInfo.fiscalYearFormat;
|
||||||
|
user.currencyDisplayType = userInfo.currencyDisplayType;
|
||||||
|
user.numeralSystem = userInfo.numeralSystem;
|
||||||
user.decimalSeparator = userInfo.decimalSeparator;
|
user.decimalSeparator = userInfo.decimalSeparator;
|
||||||
user.digitGroupingSymbol = userInfo.digitGroupingSymbol;
|
user.digitGroupingSymbol = userInfo.digitGroupingSymbol;
|
||||||
user.digitGrouping = userInfo.digitGrouping;
|
user.digitGrouping = userInfo.digitGrouping;
|
||||||
user.currencyDisplayType = userInfo.currencyDisplayType;
|
|
||||||
user.coordinateDisplayType = userInfo.coordinateDisplayType;
|
user.coordinateDisplayType = userInfo.coordinateDisplayType;
|
||||||
user.expenseAmountColor = userInfo.expenseAmountColor;
|
user.expenseAmountColor = userInfo.expenseAmountColor;
|
||||||
user.incomeAmountColor = userInfo.incomeAmountColor;
|
user.incomeAmountColor = userInfo.incomeAmountColor;
|
||||||
@@ -146,10 +150,11 @@ export interface UserBasicInfo {
|
|||||||
readonly longTimeFormat: number;
|
readonly longTimeFormat: number;
|
||||||
readonly shortTimeFormat: number;
|
readonly shortTimeFormat: number;
|
||||||
readonly fiscalYearFormat: number;
|
readonly fiscalYearFormat: number;
|
||||||
|
readonly currencyDisplayType: number;
|
||||||
|
readonly numeralSystem: number;
|
||||||
readonly decimalSeparator: number;
|
readonly decimalSeparator: number;
|
||||||
readonly digitGroupingSymbol: number;
|
readonly digitGroupingSymbol: number;
|
||||||
readonly digitGrouping: number;
|
readonly digitGrouping: number;
|
||||||
readonly currencyDisplayType: number;
|
|
||||||
readonly coordinateDisplayType: number;
|
readonly coordinateDisplayType: number;
|
||||||
readonly expenseAmountColor: number;
|
readonly expenseAmountColor: number;
|
||||||
readonly incomeAmountColor: number;
|
readonly incomeAmountColor: number;
|
||||||
@@ -199,10 +204,11 @@ export interface UserProfileUpdateRequest {
|
|||||||
readonly longTimeFormat?: number;
|
readonly longTimeFormat?: number;
|
||||||
readonly shortTimeFormat?: number;
|
readonly shortTimeFormat?: number;
|
||||||
readonly fiscalYearFormat?: number;
|
readonly fiscalYearFormat?: number;
|
||||||
|
readonly currencyDisplayType?: number;
|
||||||
|
readonly numeralSystem?: number;
|
||||||
readonly decimalSeparator?: number;
|
readonly decimalSeparator?: number;
|
||||||
readonly digitGroupingSymbol?: number;
|
readonly digitGroupingSymbol?: number;
|
||||||
readonly digitGrouping?: number;
|
readonly digitGrouping?: number;
|
||||||
readonly currencyDisplayType?: number;
|
|
||||||
readonly coordinateDisplayType?: number;
|
readonly coordinateDisplayType?: number;
|
||||||
readonly expenseAmountColor?: number;
|
readonly expenseAmountColor?: number;
|
||||||
readonly incomeAmountColor?: number;
|
readonly incomeAmountColor?: number;
|
||||||
@@ -234,10 +240,11 @@ export const EMPTY_USER_BASIC_INFO: UserBasicInfo = {
|
|||||||
longTimeFormat: LongTimeFormat.Default.type,
|
longTimeFormat: LongTimeFormat.Default.type,
|
||||||
shortTimeFormat: ShortTimeFormat.Default.type,
|
shortTimeFormat: ShortTimeFormat.Default.type,
|
||||||
fiscalYearFormat: FiscalYearFormat.Default.type,
|
fiscalYearFormat: FiscalYearFormat.Default.type,
|
||||||
|
currencyDisplayType: CurrencyDisplayType.Default.type,
|
||||||
|
numeralSystem: NumeralSystem.Default.type,
|
||||||
decimalSeparator: DecimalSeparator.LanguageDefaultType,
|
decimalSeparator: DecimalSeparator.LanguageDefaultType,
|
||||||
digitGroupingSymbol: DigitGroupingSymbol.LanguageDefaultType,
|
digitGroupingSymbol: DigitGroupingSymbol.LanguageDefaultType,
|
||||||
digitGrouping: DigitGroupingType.LanguageDefaultType,
|
digitGrouping: DigitGroupingType.LanguageDefaultType,
|
||||||
currencyDisplayType: CurrencyDisplayType.Default.type,
|
|
||||||
coordinateDisplayType: CoordinateDisplayType.Default.type,
|
coordinateDisplayType: CoordinateDisplayType.Default.type,
|
||||||
expenseAmountColor: PresetAmountColor.DefaultExpenseColor.type,
|
expenseAmountColor: PresetAmountColor.DefaultExpenseColor.type,
|
||||||
incomeAmountColor: PresetAmountColor.DefaultIncomeColor.type,
|
incomeAmountColor: PresetAmountColor.DefaultIncomeColor.type,
|
||||||
|
|||||||
+44
-31
@@ -6,8 +6,10 @@ import { useUserStore } from './user.ts';
|
|||||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||||
|
|
||||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||||
|
import type { HiddenAmount, NumberWithSuffix } from '@/core/numeral.ts';
|
||||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
type AccountNewDisplayOrderRequest,
|
type AccountNewDisplayOrderRequest,
|
||||||
type AccountDisplayBalance,
|
type AccountDisplayBalance,
|
||||||
@@ -486,9 +488,9 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNetAssets(showAccountBalance: boolean): string {
|
function getNetAssets(showAccountBalance: boolean): number | HiddenAmount | NumberWithSuffix {
|
||||||
if (!showAccountBalance) {
|
if (!showAccountBalance) {
|
||||||
return '***';
|
return DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account =>
|
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account =>
|
||||||
@@ -513,15 +515,18 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasUnCalculatedAmount) {
|
if (hasUnCalculatedAmount) {
|
||||||
return netAssets + '+';
|
return {
|
||||||
|
value: netAssets,
|
||||||
|
suffix: INCOMPLETE_AMOUNT_SUFFIX
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return netAssets.toString();
|
return netAssets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTotalAssets(showAccountBalance: boolean): string {
|
function getTotalAssets(showAccountBalance: boolean): number | HiddenAmount | NumberWithSuffix {
|
||||||
if (!showAccountBalance) {
|
if (!showAccountBalance) {
|
||||||
return '***';
|
return DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account =>
|
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account =>
|
||||||
@@ -546,15 +551,18 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasUnCalculatedAmount) {
|
if (hasUnCalculatedAmount) {
|
||||||
return totalAssets + '+';
|
return {
|
||||||
|
value: totalAssets,
|
||||||
|
suffix: INCOMPLETE_AMOUNT_SUFFIX
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return totalAssets.toString();
|
return totalAssets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTotalLiabilities(showAccountBalance: boolean): string {
|
function getTotalLiabilities(showAccountBalance: boolean): number | HiddenAmount | NumberWithSuffix {
|
||||||
if (!showAccountBalance) {
|
if (!showAccountBalance) {
|
||||||
return '***';
|
return DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account =>
|
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account =>
|
||||||
@@ -579,15 +587,18 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasUnCalculatedAmount) {
|
if (hasUnCalculatedAmount) {
|
||||||
return totalLiabilities + '+';
|
return {
|
||||||
|
value: totalLiabilities,
|
||||||
|
suffix: INCOMPLETE_AMOUNT_SUFFIX
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return totalLiabilities.toString();
|
return totalLiabilities;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccountCategoryTotalBalance(showAccountBalance: boolean, accountCategory: AccountCategory): string {
|
function getAccountCategoryTotalBalance(showAccountBalance: boolean, accountCategory: AccountCategory): number | HiddenAmount | NumberWithSuffix {
|
||||||
if (!showAccountBalance) {
|
if (!showAccountBalance) {
|
||||||
return '***';
|
return DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account => account.category === accountCategory.type);
|
const accountsBalance = getAllFilteredAccountsBalance(allCategorizedAccountsMap.value, account => account.category === accountCategory.type);
|
||||||
@@ -622,27 +633,30 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hasUnCalculatedAmount) {
|
if (hasUnCalculatedAmount) {
|
||||||
return totalBalance + '+';
|
return {
|
||||||
|
value: totalBalance,
|
||||||
|
suffix: INCOMPLETE_AMOUNT_SUFFIX
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
return totalBalance.toString();
|
return totalBalance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAccountBalance(showAccountBalance: boolean, account: Account): string | null {
|
function getAccountBalance(showAccountBalance: boolean, account: Account): number | HiddenAmount | null {
|
||||||
if (account.type !== AccountType.SingleAccount.type) {
|
if (account.type !== AccountType.SingleAccount.type) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showAccountBalance) {
|
if (showAccountBalance) {
|
||||||
if (account.isAsset) {
|
if (account.isAsset) {
|
||||||
return account.balance.toString();
|
return account.balance;
|
||||||
} else if (account.isLiability) {
|
} else if (account.isLiability) {
|
||||||
return (-account.balance).toString();
|
return -account.balance;
|
||||||
} else {
|
} else {
|
||||||
return account.balance.toString();
|
return account.balance;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return '***';
|
return DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,7 +669,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
|
|
||||||
if (!account.subAccounts || !account.subAccounts.length) {
|
if (!account.subAccounts || !account.subAccounts.length) {
|
||||||
return {
|
return {
|
||||||
balance: showAccountBalance ? '0' : '***',
|
balance: showAccountBalance ? 0 : DISPLAY_HIDDEN_AMOUNT,
|
||||||
currency: resultCurrency
|
currency: resultCurrency
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -679,7 +693,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
|
|
||||||
if (allSubAccountCurrencies.length === 0) {
|
if (allSubAccountCurrencies.length === 0) {
|
||||||
return {
|
return {
|
||||||
balance: showAccountBalance ? '0' : '***',
|
balance: showAccountBalance ? 0 : DISPLAY_HIDDEN_AMOUNT,
|
||||||
currency: resultCurrency
|
currency: resultCurrency
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -700,7 +714,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
if (subAccountId) {
|
if (subAccountId) {
|
||||||
if (subAccountId === subAccount.id) {
|
if (subAccountId === subAccount.id) {
|
||||||
return {
|
return {
|
||||||
balance: showAccountBalance ? getAccountBalance(showAccountBalance, subAccount) as string : '***',
|
balance: showAccountBalance ? getAccountBalance(showAccountBalance, subAccount) as number : DISPLAY_HIDDEN_AMOUNT,
|
||||||
currency: subAccount.currency
|
currency: subAccount.currency
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -736,14 +750,13 @@ export const useAccountsStore = defineStore('accounts', () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let displayTotalBalance = totalBalance.toString();
|
const displayTotalBalance: NumberWithSuffix = {
|
||||||
|
value: totalBalance,
|
||||||
if (hasUnCalculatedAmount) {
|
suffix: hasUnCalculatedAmount ? INCOMPLETE_AMOUNT_SUFFIX : ''
|
||||||
displayTotalBalance += '+';
|
};
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
balance: showAccountBalance ? displayTotalBalance : '***',
|
balance: showAccountBalance ? displayTotalBalance : DISPLAY_HIDDEN_AMOUNT,
|
||||||
currency: resultCurrency
|
currency: resultCurrency
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-6
@@ -99,6 +99,16 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
return userInfo.fiscalYearFormat;
|
return userInfo.fiscalYearFormat;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const currentUserCurrencyDisplayType = computed<number>(() => {
|
||||||
|
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
||||||
|
return userInfo.currencyDisplayType;
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentUserNumeralSystem = computed<number>(() => {
|
||||||
|
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
||||||
|
return userInfo.numeralSystem;
|
||||||
|
});
|
||||||
|
|
||||||
const currentUserDecimalSeparator = computed<number>(() => {
|
const currentUserDecimalSeparator = computed<number>(() => {
|
||||||
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
||||||
return userInfo.decimalSeparator;
|
return userInfo.decimalSeparator;
|
||||||
@@ -114,11 +124,6 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
return userInfo.digitGrouping;
|
return userInfo.digitGrouping;
|
||||||
});
|
});
|
||||||
|
|
||||||
const currentUserCurrencyDisplayType = computed<number>(() => {
|
|
||||||
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
|
||||||
return userInfo.currencyDisplayType;
|
|
||||||
});
|
|
||||||
|
|
||||||
const currentUserCoordinateDisplayType = computed<number>(() => {
|
const currentUserCoordinateDisplayType = computed<number>(() => {
|
||||||
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
const userInfo = currentUserBasicInfo.value || EMPTY_USER_BASIC_INFO;
|
||||||
return userInfo.coordinateDisplayType;
|
return userInfo.coordinateDisplayType;
|
||||||
@@ -422,10 +427,11 @@ export const useUserStore = defineStore('user', () => {
|
|||||||
currentUserLongTimeFormat,
|
currentUserLongTimeFormat,
|
||||||
currentUserShortTimeFormat,
|
currentUserShortTimeFormat,
|
||||||
currentUserFiscalYearFormat,
|
currentUserFiscalYearFormat,
|
||||||
|
currentUserCurrencyDisplayType,
|
||||||
|
currentUserNumeralSystem,
|
||||||
currentUserDecimalSeparator,
|
currentUserDecimalSeparator,
|
||||||
currentUserDigitGroupingSymbol,
|
currentUserDigitGroupingSymbol,
|
||||||
currentUserDigitGrouping,
|
currentUserDigitGrouping,
|
||||||
currentUserCurrencyDisplayType,
|
|
||||||
currentUserCoordinateDisplayType,
|
currentUserCoordinateDisplayType,
|
||||||
currentUserExpenseAmountColor,
|
currentUserExpenseAmountColor,
|
||||||
currentUserIncomeAmountColor,
|
currentUserIncomeAmountColor,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import type {
|
|||||||
import { getExchangedAmountByRate } from '@/lib/numeral.ts';
|
import { getExchangedAmountByRate } from '@/lib/numeral.ts';
|
||||||
|
|
||||||
export function useExchangeRatesPageBase() {
|
export function useExchangeRatesPageBase() {
|
||||||
const { getAllDisplayExchangeRates, formatUnixTimeToLongDate, parseAmount } = useI18n();
|
const { getAllDisplayExchangeRates, formatUnixTimeToLongDate, parseAmountFromWesternArabicNumerals } = useI18n();
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const exchangeRatesStore = useExchangeRatesStore();
|
const exchangeRatesStore = useExchangeRatesStore();
|
||||||
@@ -49,7 +49,7 @@ export function useExchangeRatesPageBase() {
|
|||||||
|
|
||||||
function setAsBaseline(currency: string, amount: string): void {
|
function setAsBaseline(currency: string, amount: string): void {
|
||||||
baseCurrency.value = currency;
|
baseCurrency.value = currency;
|
||||||
baseAmount.value = parseAmount(amount);
|
baseAmount.value = parseAmountFromWesternArabicNumerals(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import { useUserStore } from '@/stores/user.ts';
|
|||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
import { useOverviewStore } from '@/stores/overview.ts';
|
import { useOverviewStore } from '@/stores/overview.ts';
|
||||||
|
|
||||||
|
import type { HiddenAmount, NumberWithSuffix } from '@/core/numeral.ts';
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import { Account } from '@/models/account.ts';
|
import { Account } from '@/models/account.ts';
|
||||||
import type {
|
import type {
|
||||||
TransactionOverviewResponse,
|
TransactionOverviewResponse,
|
||||||
@@ -20,7 +23,7 @@ export function useHomePageBase() {
|
|||||||
formatUnixTimeToLongYear,
|
formatUnixTimeToLongYear,
|
||||||
formatUnixTimeToLongMonth,
|
formatUnixTimeToLongMonth,
|
||||||
formatUnixTimeToLongMonthDay,
|
formatUnixTimeToLongMonthDay,
|
||||||
formatAmountWithCurrency
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
@@ -37,18 +40,18 @@ export function useHomePageBase() {
|
|||||||
const allAccounts = computed<Account[]>(() => accountsStore.allAccounts);
|
const allAccounts = computed<Account[]>(() => accountsStore.allAccounts);
|
||||||
|
|
||||||
const netAssets = computed<string>(() => {
|
const netAssets = computed<string>(() => {
|
||||||
const netAssets = accountsStore.getNetAssets(showAmountInHomePage.value);
|
const netAssets: number | HiddenAmount | NumberWithSuffix = accountsStore.getNetAssets(showAmountInHomePage.value);
|
||||||
return formatAmountWithCurrency(netAssets, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(netAssets, defaultCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalAssets = computed<string>(() => {
|
const totalAssets = computed<string>(() => {
|
||||||
const totalAssets = accountsStore.getTotalAssets(showAmountInHomePage.value);
|
const totalAssets: number | HiddenAmount | NumberWithSuffix = accountsStore.getTotalAssets(showAmountInHomePage.value);
|
||||||
return formatAmountWithCurrency(totalAssets, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(totalAssets, defaultCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalLiabilities = computed<string>(() => {
|
const totalLiabilities = computed<string>(() => {
|
||||||
const totalLiabilities = accountsStore.getTotalLiabilities(showAmountInHomePage.value);
|
const totalLiabilities: number | HiddenAmount | NumberWithSuffix = accountsStore.getTotalLiabilities(showAmountInHomePage.value);
|
||||||
return formatAmountWithCurrency(totalLiabilities, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(totalLiabilities, defaultCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const displayDateRange = computed<TransactionOverviewDisplayTime>(() => {
|
const displayDateRange = computed<TransactionOverviewDisplayTime>(() => {
|
||||||
@@ -75,10 +78,10 @@ export function useHomePageBase() {
|
|||||||
|
|
||||||
function getDisplayAmount(amount: number, incomplete: boolean): string {
|
function getDisplayAmount(amount: number, incomplete: boolean): string {
|
||||||
if (!showAmountInHomePage.value) {
|
if (!showAmountInHomePage.value) {
|
||||||
return formatAmountWithCurrency('***', defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(DISPLAY_HIDDEN_AMOUNT, defaultCurrency.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(amount, defaultCurrency.value) + (incomplete ? '+' : '');
|
return formatAmountToLocalizedNumeralsWithCurrency(amount, defaultCurrency.value) + (incomplete ? INCOMPLETE_AMOUNT_SUFFIX : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayIncomeAmount(category: TransactionOverviewResponseItem): string {
|
function getDisplayIncomeAmount(category: TransactionOverviewResponseItem): string {
|
||||||
|
|||||||
@@ -6,14 +6,15 @@ import { useSettingsStore } from '@/stores/setting.ts';
|
|||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
|
|
||||||
|
import type { HiddenAmount, NumberWithSuffix } from '@/core/numeral.ts';
|
||||||
import type { WeekDayValue } from '@/core/datetime.ts';
|
import type { WeekDayValue } from '@/core/datetime.ts';
|
||||||
import { type AccountCategory, AccountType } from '@/core/account.ts';
|
import { type AccountCategory, AccountType } from '@/core/account.ts';
|
||||||
import type { Account, CategorizedAccount } from '@/models/account.ts';
|
import type { Account, CategorizedAccount } from '@/models/account.ts';
|
||||||
|
|
||||||
import { isObject, isString } from '@/lib/common.ts';
|
import { isObject, isNumber, isString } from '@/lib/common.ts';
|
||||||
|
|
||||||
export function useAccountListPageBaseBase() {
|
export function useAccountListPageBaseBase() {
|
||||||
const { formatAmountWithCurrency } = useI18n();
|
const { formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -37,18 +38,18 @@ export function useAccountListPageBaseBase() {
|
|||||||
const allAccountCount = computed<number>(() => accountsStore.allAvailableAccountsCount);
|
const allAccountCount = computed<number>(() => accountsStore.allAvailableAccountsCount);
|
||||||
|
|
||||||
const netAssets = computed<string>(() => {
|
const netAssets = computed<string>(() => {
|
||||||
const netAssets = accountsStore.getNetAssets(showAccountBalance.value);
|
const netAssets: number | HiddenAmount | NumberWithSuffix = accountsStore.getNetAssets(showAccountBalance.value);
|
||||||
return formatAmountWithCurrency(netAssets, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(netAssets, defaultCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalAssets = computed<string>(() => {
|
const totalAssets = computed<string>(() => {
|
||||||
const totalAssets = accountsStore.getTotalAssets(showAccountBalance.value);
|
const totalAssets: number | HiddenAmount | NumberWithSuffix = accountsStore.getTotalAssets(showAccountBalance.value);
|
||||||
return formatAmountWithCurrency(totalAssets, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(totalAssets, defaultCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const totalLiabilities = computed<string>(() => {
|
const totalLiabilities = computed<string>(() => {
|
||||||
const totalLiabilities = accountsStore.getTotalLiabilities(showAccountBalance.value);
|
const totalLiabilities: number | HiddenAmount | NumberWithSuffix = accountsStore.getTotalLiabilities(showAccountBalance.value);
|
||||||
return formatAmountWithCurrency(totalLiabilities, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(totalLiabilities, defaultCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
function accountCategoryTotalBalance(accountCategory?: AccountCategory): string {
|
function accountCategoryTotalBalance(accountCategory?: AccountCategory): string {
|
||||||
@@ -56,19 +57,19 @@ export function useAccountListPageBaseBase() {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalBalance = accountsStore.getAccountCategoryTotalBalance(showAccountBalance.value, accountCategory);
|
const totalBalance: number | HiddenAmount | NumberWithSuffix = accountsStore.getAccountCategoryTotalBalance(showAccountBalance.value, accountCategory);
|
||||||
return formatAmountWithCurrency(totalBalance, defaultCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(totalBalance, defaultCurrency.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function accountBalance(account: Account, currentSubAccountId?: string): string | null {
|
function accountBalance(account: Account, currentSubAccountId?: string): string | null {
|
||||||
if (account.type === AccountType.SingleAccount.type) {
|
if (account.type === AccountType.SingleAccount.type) {
|
||||||
const balance = accountsStore.getAccountBalance(showAccountBalance.value, account);
|
const balance: number| HiddenAmount | null = accountsStore.getAccountBalance(showAccountBalance.value, account);
|
||||||
|
|
||||||
if (!isString(balance)) {
|
if (!isNumber(balance) && !isString(balance)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(balance, account.currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(balance, account.currency);
|
||||||
} else if (account.type === AccountType.MultiSubAccounts.type) {
|
} else if (account.type === AccountType.MultiSubAccounts.type) {
|
||||||
const balanceResult = accountsStore.getAccountSubAccountBalance(showAccountBalance.value, showHidden.value, account, currentSubAccountId);
|
const balanceResult = accountsStore.getAccountSubAccountBalance(showAccountBalance.value, showHidden.value, account, currentSubAccountId);
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ export function useAccountListPageBaseBase() {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(balanceResult.balance, balanceResult.currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(balanceResult.balance, balanceResult.currency);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,7 @@ import type {
|
|||||||
TransactionReconciliationStatementResponseItem
|
TransactionReconciliationStatementResponseItem
|
||||||
} from '@/models/transaction.ts';
|
} from '@/models/transaction.ts';
|
||||||
|
|
||||||
import {
|
import { replaceAll } from '@/lib/common.ts';
|
||||||
replaceAll,
|
|
||||||
removeAll
|
|
||||||
} from '@/lib/common.ts';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getUtcOffsetByUtcOffsetMinutes,
|
getUtcOffsetByUtcOffsetMinutes,
|
||||||
@@ -36,12 +33,11 @@ export function useReconciliationStatementPageBase() {
|
|||||||
tt,
|
tt,
|
||||||
getAllAccountBalanceTrendChartTypes,
|
getAllAccountBalanceTrendChartTypes,
|
||||||
getAllStatisticsDateAggregationTypesWithShortName,
|
getAllStatisticsDateAggregationTypesWithShortName,
|
||||||
getCurrentDigitGroupingSymbol,
|
|
||||||
formatUnixTimeToLongDateTime,
|
formatUnixTimeToLongDateTime,
|
||||||
formatUnixTimeToLongDate,
|
formatUnixTimeToLongDate,
|
||||||
formatUnixTimeToShortTime,
|
formatUnixTimeToShortTime,
|
||||||
formatAmount,
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||||
formatAmountWithCurrency
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
@@ -90,30 +86,30 @@ export function useReconciliationStatementPageBase() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const displayTotalInflows = computed<string>(() => {
|
const displayTotalInflows = computed<string>(() => {
|
||||||
return formatAmountWithCurrency(reconciliationStatements.value?.totalInflows ?? 0, currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(reconciliationStatements.value?.totalInflows ?? 0, currentAccountCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const displayTotalOutflows = computed<string>(() => {
|
const displayTotalOutflows = computed<string>(() => {
|
||||||
return formatAmountWithCurrency(reconciliationStatements.value?.totalOutflows ?? 0, currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(reconciliationStatements.value?.totalOutflows ?? 0, currentAccountCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const displayTotalBalance = computed<string>(() => {
|
const displayTotalBalance = computed<string>(() => {
|
||||||
return formatAmountWithCurrency((reconciliationStatements?.value?.totalInflows ?? 0) - (reconciliationStatements.value?.totalOutflows ?? 0), currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency((reconciliationStatements?.value?.totalInflows ?? 0) - (reconciliationStatements.value?.totalOutflows ?? 0), currentAccountCurrency.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const displayOpeningBalance = computed<string>(() => {
|
const displayOpeningBalance = computed<string>(() => {
|
||||||
if (isCurrentLiabilityAccount.value) {
|
if (isCurrentLiabilityAccount.value) {
|
||||||
return formatAmountWithCurrency(-(reconciliationStatements?.value?.openingBalance ?? 0), currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(-(reconciliationStatements?.value?.openingBalance ?? 0), currentAccountCurrency.value);
|
||||||
} else {
|
} else {
|
||||||
return formatAmountWithCurrency(reconciliationStatements?.value?.openingBalance ?? 0, currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(reconciliationStatements?.value?.openingBalance ?? 0, currentAccountCurrency.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const displayClosingBalance = computed<string>(() => {
|
const displayClosingBalance = computed<string>(() => {
|
||||||
if (isCurrentLiabilityAccount.value) {
|
if (isCurrentLiabilityAccount.value) {
|
||||||
return formatAmountWithCurrency(-(reconciliationStatements?.value?.closingBalance ?? 0), currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(-(reconciliationStatements?.value?.closingBalance ?? 0), currentAccountCurrency.value);
|
||||||
} else {
|
} else {
|
||||||
return formatAmountWithCurrency(reconciliationStatements?.value?.closingBalance ?? 0, currentAccountCurrency.value);
|
return formatAmountToLocalizedNumeralsWithCurrency(reconciliationStatements?.value?.closingBalance ?? 0, currentAccountCurrency.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -159,7 +155,7 @@ export function useReconciliationStatementPageBase() {
|
|||||||
currency = allAccountsMap.value[transaction.sourceAccountId].currency;
|
currency = allAccountsMap.value[transaction.sourceAccountId].currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(transaction.sourceAmount, currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(transaction.sourceAmount, currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayDestinationAmount(transaction: TransactionReconciliationStatementResponseItem): string {
|
function getDisplayDestinationAmount(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||||
@@ -169,7 +165,7 @@ export function useReconciliationStatementPageBase() {
|
|||||||
currency = allAccountsMap.value[transaction.destinationAccountId].currency;
|
currency = allAccountsMap.value[transaction.destinationAccountId].currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(transaction.destinationAmount, currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(transaction.destinationAmount, currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayAccountBalance(transaction: TransactionReconciliationStatementResponseItem): string {
|
function getDisplayAccountBalance(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||||
@@ -187,9 +183,9 @@ export function useReconciliationStatementPageBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isLiabilityAccount) {
|
if (isLiabilityAccount) {
|
||||||
return formatAmountWithCurrency(-transaction.accountClosingBalance, currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(-transaction.accountClosingBalance, currency);
|
||||||
} else {
|
} else {
|
||||||
return formatAmountWithCurrency(transaction.accountClosingBalance, currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(transaction.accountClosingBalance, currency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +196,6 @@ export function useReconciliationStatementPageBase() {
|
|||||||
separator = '\t';
|
separator = '\t';
|
||||||
}
|
}
|
||||||
|
|
||||||
const digitGroupingSymbol = getCurrentDigitGroupingSymbol();
|
|
||||||
const accountBalanceName = isCurrentLiabilityAccount.value ? 'Account Outstanding Balance' : 'Account Balance';
|
const accountBalanceName = isCurrentLiabilityAccount.value ? 'Account Outstanding Balance' : 'Account Balance';
|
||||||
|
|
||||||
const header = [
|
const header = [
|
||||||
@@ -218,13 +213,13 @@ export function useReconciliationStatementPageBase() {
|
|||||||
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
|
const transactionTime = getUnixTime(parseDateFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value));
|
||||||
const type = getDisplayTransactionType(transaction);
|
const type = getDisplayTransactionType(transaction);
|
||||||
let categoryName = allCategoriesMap.value[transaction.categoryId]?.name || '';
|
let categoryName = allCategoriesMap.value[transaction.categoryId]?.name || '';
|
||||||
let displayAmount = removeAll(formatAmount(transaction.sourceAmount), digitGroupingSymbol);
|
let displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.sourceAmount);
|
||||||
let displayAccountName = allAccountsMap.value[transaction.sourceAccountId]?.name || '';
|
let displayAccountName = allAccountsMap.value[transaction.sourceAccountId]?.name || '';
|
||||||
|
|
||||||
if (transaction.type === TransactionType.ModifyBalance) {
|
if (transaction.type === TransactionType.ModifyBalance) {
|
||||||
categoryName = tt('Modify Balance');
|
categoryName = tt('Modify Balance');
|
||||||
} else if (transaction.type === TransactionType.Transfer && transaction.destinationAccountId === accountId.value) {
|
} else if (transaction.type === TransactionType.Transfer && transaction.destinationAccountId === accountId.value) {
|
||||||
displayAmount = removeAll(formatAmount(transaction.destinationAmount), digitGroupingSymbol);
|
displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.destinationAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transaction.type === TransactionType.Transfer && allAccountsMap.value[transaction.destinationAccountId]) {
|
if (transaction.type === TransactionType.Transfer && allAccountsMap.value[transaction.destinationAccountId]) {
|
||||||
@@ -234,9 +229,9 @@ export function useReconciliationStatementPageBase() {
|
|||||||
let displayAccountBalance = '';
|
let displayAccountBalance = '';
|
||||||
|
|
||||||
if (isCurrentLiabilityAccount.value) {
|
if (isCurrentLiabilityAccount.value) {
|
||||||
displayAccountBalance = removeAll(formatAmount(-transaction.accountClosingBalance), digitGroupingSymbol);
|
displayAccountBalance = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(-transaction.accountClosingBalance);
|
||||||
} else {
|
} else {
|
||||||
displayAccountBalance = removeAll(formatAmount(transaction.accountClosingBalance), digitGroupingSymbol);
|
displayAccountBalance = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.accountClosingBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
let description = transaction.comment || '';
|
let description = transaction.comment || '';
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { type TransactionStatisticsFilter, useStatisticsStore } from '@/stores/s
|
|||||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||||
import { type LocalizedDateRange, type WeekDayValue, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
import { type LocalizedDateRange, type WeekDayValue, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||||
import { StatisticsAnalysisType, ChartDataType, ChartSortingType, ChartDateAggregationType } from '@/core/statistics.ts';
|
import { StatisticsAnalysisType, ChartDataType, ChartSortingType, ChartDateAggregationType } from '@/core/statistics.ts';
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||||
import type { TransactionCategoricalAnalysisData, TransactionTrendsAnalysisData } from '@/models/transaction.ts';
|
import type { TransactionCategoricalAnalysisData, TransactionTrendsAnalysisData } from '@/models/transaction.ts';
|
||||||
|
|
||||||
import { limitText, findNameByType, findDisplayNameByType } from '@/lib/common.ts';
|
import { limitText, findNameByType, findDisplayNameByType } from '@/lib/common.ts';
|
||||||
@@ -23,7 +24,7 @@ export function useStatisticsTransactionPageBase() {
|
|||||||
formatUnixTimeToLongDateTime,
|
formatUnixTimeToLongDateTime,
|
||||||
formatUnixTimeToLongYearMonth,
|
formatUnixTimeToLongYearMonth,
|
||||||
formatDateRange,
|
formatDateRange,
|
||||||
formatAmountWithCurrency
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
@@ -200,13 +201,13 @@ export function useStatisticsTransactionPageBase() {
|
|||||||
const trendsAnalysisData = computed<TransactionTrendsAnalysisData | null>(() => statisticsStore.trendsAnalysisData);
|
const trendsAnalysisData = computed<TransactionTrendsAnalysisData | null>(() => statisticsStore.trendsAnalysisData);
|
||||||
|
|
||||||
function getDisplayAmount(amount: number, currency: string, textLimit?: number): string {
|
function getDisplayAmount(amount: number, currency: string, textLimit?: number): string {
|
||||||
const finalAmount = formatAmountWithCurrency(amount, currency);
|
const finalAmount = formatAmountToLocalizedNumeralsWithCurrency(amount, currency);
|
||||||
|
|
||||||
if (!showAccountBalance.value
|
if (!showAccountBalance.value
|
||||||
&& (query.value.chartDataType === ChartDataType.AccountTotalAssets.type
|
&& (query.value.chartDataType === ChartDataType.AccountTotalAssets.type
|
||||||
|| query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type)
|
|| query.value.chartDataType === ChartDataType.AccountTotalLiabilities.type)
|
||||||
) {
|
) {
|
||||||
return '***';
|
return DISPLAY_HIDDEN_AMOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (textLimit) {
|
if (textLimit) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
|||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||||
import type { WeekDayValue } from '@/core/datetime.ts';
|
import type { WeekDayValue } from '@/core/datetime.ts';
|
||||||
import type { LocalizedTimezoneInfo } from '@/core/timezone.ts';
|
import type { LocalizedTimezoneInfo } from '@/core/timezone.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
@@ -59,7 +60,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
|||||||
tt,
|
tt,
|
||||||
getAllTimezones,
|
getAllTimezones,
|
||||||
getTimezoneDifferenceDisplayText,
|
getTimezoneDifferenceDisplayText,
|
||||||
formatAmountWithCurrency,
|
formatAmountToLocalizedNumeralsWithCurrency,
|
||||||
getAdaptiveAmountRate,
|
getAdaptiveAmountRate,
|
||||||
getCategorizedAccountsWithDisplayBalance
|
getCategorizedAccountsWithDisplayBalance
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
@@ -360,12 +361,12 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayAmount(amount: number | string, hideAmount: boolean, currencyCode: string): string {
|
function getDisplayAmount(amount: number, hideAmount: boolean, currencyCode: string): string {
|
||||||
if (hideAmount) {
|
if (hideAmount) {
|
||||||
return formatAmountWithCurrency('***', currencyCode);
|
return formatAmountToLocalizedNumeralsWithCurrency(DISPLAY_HIDDEN_AMOUNT, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(amount, currencyCode);
|
return formatAmountToLocalizedNumeralsWithCurrency(amount, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransactionPictureUrl(pictureInfo?: TransactionPictureInfoBasicResponse | null): string | undefined {
|
function getTransactionPictureUrl(pictureInfo?: TransactionPictureInfoBasicResponse | null): string | undefined {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import type { TypeAndName } from '@/core/base.ts';
|
|||||||
import { type LocalizedDateRange, type WeekDayValue, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
import { type LocalizedDateRange, type WeekDayValue, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||||
import { AccountType } from '@/core/account.ts';
|
import { AccountType } from '@/core/account.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import type { Account } from '@/models/account.ts';
|
import type { Account } from '@/models/account.ts';
|
||||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||||
@@ -84,7 +85,7 @@ export function useTransactionListPageBase() {
|
|||||||
formatUnixTimeToLongYearMonth,
|
formatUnixTimeToLongYearMonth,
|
||||||
formatUnixTimeToShortTime,
|
formatUnixTimeToShortTime,
|
||||||
formatDateRange,
|
formatDateRange,
|
||||||
formatAmountWithCurrency
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
@@ -231,7 +232,7 @@ export function useTransactionListPageBase() {
|
|||||||
const displayAmount: string[] = [];
|
const displayAmount: string[] = [];
|
||||||
|
|
||||||
for (let i = 1; i < amountFilterItems.length; i++) {
|
for (let i = 1; i < amountFilterItems.length; i++) {
|
||||||
displayAmount.push(formatAmountWithCurrency(amountFilterItems[i], false));
|
displayAmount.push(formatAmountToLocalizedNumeralsWithCurrency(parseInt(amountFilterItems[i]), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return displayAmount.join(' ~ ');
|
return displayAmount.join(' ~ ');
|
||||||
@@ -279,10 +280,10 @@ export function useTransactionListPageBase() {
|
|||||||
|
|
||||||
function formatAmount(amount: number, hideAmount: boolean, currencyCode: string): string {
|
function formatAmount(amount: number, hideAmount: boolean, currencyCode: string): string {
|
||||||
if (hideAmount) {
|
if (hideAmount) {
|
||||||
return formatAmountWithCurrency('***', currencyCode);
|
return formatAmountToLocalizedNumeralsWithCurrency(DISPLAY_HIDDEN_AMOUNT, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatAmountWithCurrency(amount, currencyCode);
|
return formatAmountToLocalizedNumeralsWithCurrency(amount, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayTime(transaction: Transaction): string {
|
function getDisplayTime(transaction: Transaction): string {
|
||||||
@@ -337,8 +338,8 @@ export function useTransactionListPageBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayMonthTotalAmount(amount: number, currency: string | false, symbol: string, incomplete: boolean): string {
|
function getDisplayMonthTotalAmount(amount: number, currency: string | false, symbol: string, incomplete: boolean): string {
|
||||||
const displayAmount = formatAmountWithCurrency(amount, currency);
|
const displayAmount = formatAmountToLocalizedNumeralsWithCurrency(amount, currency);
|
||||||
return symbol + displayAmount + (incomplete ? '+' : '');
|
return symbol + displayAmount + (incomplete ? INCOMPLETE_AMOUNT_SUFFIX : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransactionTypeName(type: number | null, defaultName: string): string {
|
function getTransactionTypeName(type: number | null, defaultName: string): string {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useUserStore } from '@/stores/user.ts';
|
|||||||
import type { DataStatisticsResponse, DisplayDataStatistics } from '@/models/data_management.ts';
|
import type { DataStatisticsResponse, DisplayDataStatistics } from '@/models/data_management.ts';
|
||||||
|
|
||||||
export function useDataManagementPageBase() {
|
export function useDataManagementPageBase() {
|
||||||
const { tt, appendDigitGroupingSymbol } = useI18n();
|
const { tt, formatNumberToLocalizedNumerals } = useI18n();
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
@@ -19,13 +19,13 @@ export function useDataManagementPageBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
totalTransactionCount: appendDigitGroupingSymbol(dataStatistics.value.totalTransactionCount),
|
totalTransactionCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalTransactionCount)),
|
||||||
totalAccountCount: appendDigitGroupingSymbol(dataStatistics.value.totalAccountCount),
|
totalAccountCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalAccountCount)),
|
||||||
totalTransactionCategoryCount: appendDigitGroupingSymbol(dataStatistics.value.totalTransactionCategoryCount),
|
totalTransactionCategoryCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalTransactionCategoryCount)),
|
||||||
totalTransactionTagCount: appendDigitGroupingSymbol(dataStatistics.value.totalTransactionTagCount),
|
totalTransactionTagCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalTransactionTagCount)),
|
||||||
totalTransactionPictureCount: appendDigitGroupingSymbol(dataStatistics.value.totalTransactionPictureCount),
|
totalTransactionPictureCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalTransactionPictureCount)),
|
||||||
totalTransactionTemplateCount: appendDigitGroupingSymbol(dataStatistics.value.totalTransactionTemplateCount),
|
totalTransactionTemplateCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalTransactionTemplateCount)),
|
||||||
totalScheduledTransactionCount: appendDigitGroupingSymbol(dataStatistics.value.totalScheduledTransactionCount)
|
totalScheduledTransactionCount: formatNumberToLocalizedNumerals(parseInt(dataStatistics.value.totalScheduledTransactionCount))
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { useOverviewStore } from '@/stores/overview.ts';
|
|||||||
|
|
||||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||||
import { WeekDay } from '@/core/datetime.ts';
|
import { WeekDay } from '@/core/datetime.ts';
|
||||||
import { type LocalizedDigitGroupingType, DigitGroupingSymbol } from '@/core/numeral.ts';
|
import { type LocalizedDigitGroupingType, NumeralSystem, DecimalSeparator, DigitGroupingSymbol } from '@/core/numeral.ts';
|
||||||
|
|
||||||
import { type UserBasicInfo, User } from '@/models/user.ts';
|
import { type UserBasicInfo, User } from '@/models/user.ts';
|
||||||
import { type CategorizedAccount, Account} from '@/models/account.ts';
|
import { type CategorizedAccount, Account} from '@/models/account.ts';
|
||||||
@@ -27,10 +27,11 @@ export function useUserProfilePageBase() {
|
|||||||
getAllLongTimeFormats,
|
getAllLongTimeFormats,
|
||||||
getAllShortTimeFormats,
|
getAllShortTimeFormats,
|
||||||
getAllFiscalYearFormats,
|
getAllFiscalYearFormats,
|
||||||
|
getAllCurrencyDisplayTypes,
|
||||||
|
getAllNumeralSystemTypes,
|
||||||
getAllDecimalSeparators,
|
getAllDecimalSeparators,
|
||||||
getAllDigitGroupingSymbols,
|
getAllDigitGroupingSymbols,
|
||||||
getAllDigitGroupingTypes,
|
getAllDigitGroupingTypes,
|
||||||
getAllCurrencyDisplayTypes,
|
|
||||||
getAllCoordinateDisplayTypes,
|
getAllCoordinateDisplayTypes,
|
||||||
getAllExpenseAmountColors,
|
getAllExpenseAmountColors,
|
||||||
getAllIncomeAmountColors,
|
getAllIncomeAmountColors,
|
||||||
@@ -62,10 +63,11 @@ export function useUserProfilePageBase() {
|
|||||||
const allLongTimeFormats = computed<TypeAndDisplayName[]>(() => getAllLongTimeFormats());
|
const allLongTimeFormats = computed<TypeAndDisplayName[]>(() => getAllLongTimeFormats());
|
||||||
const allShortTimeFormats = computed<TypeAndDisplayName[]>(() => getAllShortTimeFormats());
|
const allShortTimeFormats = computed<TypeAndDisplayName[]>(() => getAllShortTimeFormats());
|
||||||
const allFiscalYearFormats = computed<TypeAndDisplayName[]>(() => getAllFiscalYearFormats());
|
const allFiscalYearFormats = computed<TypeAndDisplayName[]>(() => getAllFiscalYearFormats());
|
||||||
|
const allCurrencyDisplayTypes = computed<TypeAndDisplayName[]>(() => getAllCurrencyDisplayTypes(NumeralSystem.valueOf(newProfile.value.numeralSystem) ?? NumeralSystem.Default, DecimalSeparator.valueOf(newProfile.value.decimalSeparator)?.symbol || DecimalSeparator.Default.symbol));
|
||||||
|
const allNumeralSystemTypes = computed<TypeAndDisplayName[]>(() => getAllNumeralSystemTypes());
|
||||||
const allDecimalSeparators = computed<TypeAndDisplayName[]>(() => getAllDecimalSeparators());
|
const allDecimalSeparators = computed<TypeAndDisplayName[]>(() => getAllDecimalSeparators());
|
||||||
const allDigitGroupingSymbols = computed<TypeAndDisplayName[]>(() => getAllDigitGroupingSymbols());
|
const allDigitGroupingSymbols = computed<TypeAndDisplayName[]>(() => getAllDigitGroupingSymbols());
|
||||||
const allDigitGroupingTypes = computed<LocalizedDigitGroupingType[]>(() => getAllDigitGroupingTypes(DigitGroupingSymbol.valueOf(newProfile.value.digitGroupingSymbol)?.symbol || DigitGroupingSymbol.Default.symbol));
|
const allDigitGroupingTypes = computed<LocalizedDigitGroupingType[]>(() => getAllDigitGroupingTypes(NumeralSystem.valueOf(newProfile.value.numeralSystem) ?? NumeralSystem.Default, DigitGroupingSymbol.valueOf(newProfile.value.digitGroupingSymbol)?.symbol || DigitGroupingSymbol.Default.symbol));
|
||||||
const allCurrencyDisplayTypes = computed<TypeAndDisplayName[]>(() => getAllCurrencyDisplayTypes());
|
|
||||||
const allCoordinateDisplayTypes = computed<TypeAndDisplayName[]>(() => getAllCoordinateDisplayTypes());
|
const allCoordinateDisplayTypes = computed<TypeAndDisplayName[]>(() => getAllCoordinateDisplayTypes());
|
||||||
const allExpenseAmountColorTypes = computed<TypeAndDisplayName[]>(() => getAllExpenseAmountColors());
|
const allExpenseAmountColorTypes = computed<TypeAndDisplayName[]>(() => getAllExpenseAmountColors());
|
||||||
const allIncomeAmountColorTypes = computed<TypeAndDisplayName[]>(() => getAllIncomeAmountColors());
|
const allIncomeAmountColorTypes = computed<TypeAndDisplayName[]>(() => getAllIncomeAmountColors());
|
||||||
@@ -108,10 +110,11 @@ export function useUserProfilePageBase() {
|
|||||||
newProfile.value.longTimeFormat === oldProfile.value.longTimeFormat &&
|
newProfile.value.longTimeFormat === oldProfile.value.longTimeFormat &&
|
||||||
newProfile.value.shortTimeFormat === oldProfile.value.shortTimeFormat &&
|
newProfile.value.shortTimeFormat === oldProfile.value.shortTimeFormat &&
|
||||||
newProfile.value.fiscalYearFormat === oldProfile.value.fiscalYearFormat &&
|
newProfile.value.fiscalYearFormat === oldProfile.value.fiscalYearFormat &&
|
||||||
|
newProfile.value.currencyDisplayType === oldProfile.value.currencyDisplayType &&
|
||||||
|
newProfile.value.numeralSystem === oldProfile.value.numeralSystem &&
|
||||||
newProfile.value.decimalSeparator === oldProfile.value.decimalSeparator &&
|
newProfile.value.decimalSeparator === oldProfile.value.decimalSeparator &&
|
||||||
newProfile.value.digitGroupingSymbol === oldProfile.value.digitGroupingSymbol &&
|
newProfile.value.digitGroupingSymbol === oldProfile.value.digitGroupingSymbol &&
|
||||||
newProfile.value.digitGrouping === oldProfile.value.digitGrouping &&
|
newProfile.value.digitGrouping === oldProfile.value.digitGrouping &&
|
||||||
newProfile.value.currencyDisplayType === oldProfile.value.currencyDisplayType &&
|
|
||||||
newProfile.value.coordinateDisplayType === oldProfile.value.coordinateDisplayType &&
|
newProfile.value.coordinateDisplayType === oldProfile.value.coordinateDisplayType &&
|
||||||
newProfile.value.expenseAmountColor === oldProfile.value.expenseAmountColor &&
|
newProfile.value.expenseAmountColor === oldProfile.value.expenseAmountColor &&
|
||||||
newProfile.value.incomeAmountColor === oldProfile.value.incomeAmountColor) {
|
newProfile.value.incomeAmountColor === oldProfile.value.incomeAmountColor) {
|
||||||
@@ -199,10 +202,11 @@ export function useUserProfilePageBase() {
|
|||||||
allLongTimeFormats,
|
allLongTimeFormats,
|
||||||
allShortTimeFormats,
|
allShortTimeFormats,
|
||||||
allFiscalYearFormats,
|
allFiscalYearFormats,
|
||||||
|
allCurrencyDisplayTypes,
|
||||||
|
allNumeralSystemTypes,
|
||||||
allDecimalSeparators,
|
allDecimalSeparators,
|
||||||
allDigitGroupingSymbols,
|
allDigitGroupingSymbols,
|
||||||
allDigitGroupingTypes,
|
allDigitGroupingTypes,
|
||||||
allCurrencyDisplayTypes,
|
|
||||||
allCoordinateDisplayTypes,
|
allCoordinateDisplayTypes,
|
||||||
allExpenseAmountColorTypes,
|
allExpenseAmountColorTypes,
|
||||||
allIncomeAmountColorTypes,
|
allIncomeAmountColorTypes,
|
||||||
|
|||||||
@@ -202,7 +202,7 @@
|
|||||||
<v-skeleton-loader class="skeleton-no-margin ml-3" type="text" style="width: 80px" :loading="true"></v-skeleton-loader>
|
<v-skeleton-loader class="skeleton-no-margin ml-3" type="text" style="width: 80px" :loading="true"></v-skeleton-loader>
|
||||||
</span>
|
</span>
|
||||||
<span class="ml-2" v-else-if="!loading">
|
<span class="ml-2" v-else-if="!loading">
|
||||||
{{ reconciliationStatements?.transactions.length ?? 0 }}
|
{{ formatNumberToLocalizedNumerals(reconciliationStatements?.transactions.length ?? 0) }}
|
||||||
</span>
|
</span>
|
||||||
<v-spacer/>
|
<v-spacer/>
|
||||||
<span v-if="reconciliationStatements && reconciliationStatements.transactions && reconciliationStatements.transactions.length > 10">
|
<span v-if="reconciliationStatements && reconciliationStatements.transactions && reconciliationStatements.transactions.length > 10">
|
||||||
@@ -319,7 +319,7 @@ const emit = defineEmits<{
|
|||||||
(e: 'error', message: string): void;
|
(e: 'error', message: string): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt } = useI18n();
|
const { tt, formatNumberToLocalizedNumerals } = useI18n();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
accountId,
|
accountId,
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
density="comfortable" variant="text"
|
density="comfortable" variant="text"
|
||||||
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
:class="{ 'd-none': loading, 'hover-display': !loading }"
|
||||||
v-if="exchangeRate.currencyCode !== baseCurrency"
|
v-if="exchangeRate.currencyCode !== baseCurrency"
|
||||||
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate))">
|
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false))">
|
||||||
{{ tt('Set as Base') }}
|
{{ tt('Set as Base') }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn class="px-2" color="default"
|
<v-btn class="px-2" color="default"
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ tt('Delete') }}
|
{{ tt('Delete') }}
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<span class="ml-3">{{ getFinalConvertedAmount(exchangeRate) }}</span>
|
<span class="ml-3">{{ getFinalConvertedAmount(exchangeRate, true) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -168,6 +168,8 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
|
|||||||
|
|
||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
|
|
||||||
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
||||||
|
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
@@ -184,7 +186,7 @@ type UpdateDialogType = InstanceType<typeof UpdateDialog>;
|
|||||||
|
|
||||||
const { mdAndUp } = useDisplay();
|
const { mdAndUp } = useDisplay();
|
||||||
|
|
||||||
const { tt, formatExchangeRateAmount } = useI18n();
|
const { tt, getCurrentNumeralSystemType, formatExchangeRateAmountToWesternArabicNumerals } = useI18n();
|
||||||
const {
|
const {
|
||||||
baseCurrency,
|
baseCurrency,
|
||||||
baseAmount,
|
baseAmount,
|
||||||
@@ -283,9 +285,15 @@ function remove(currency: string): void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate): string {
|
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate, displayLocalizedDigits: boolean): string {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
|
|
||||||
if (!baseCurrency.value) {
|
if (!baseCurrency.value) {
|
||||||
return '0';
|
if (displayLocalizedDigits) {
|
||||||
|
return numeralSystem.digitZero;
|
||||||
|
} else {
|
||||||
|
return NumeralSystem.WesternArabicNumerals.digitZero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
|
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
|
||||||
@@ -299,10 +307,20 @@ function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate): s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!exchangeRateAmount) {
|
if (!exchangeRateAmount) {
|
||||||
return '0';
|
if (displayLocalizedDigits) {
|
||||||
|
return numeralSystem.digitZero;
|
||||||
|
} else {
|
||||||
|
return NumeralSystem.WesternArabicNumerals.digitZero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatExchangeRateAmount(exchangeRateAmount);
|
let ret = formatExchangeRateAmountToWesternArabicNumerals(exchangeRateAmount);
|
||||||
|
|
||||||
|
if (displayLocalizedDigits) {
|
||||||
|
ret = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(mdAndUp, (newValue) => {
|
watch(mdAndUp, (newValue) => {
|
||||||
|
|||||||
@@ -34,8 +34,12 @@ import { useI18n } from '@/locales/helpers.ts';
|
|||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
|
|
||||||
|
import type { HiddenAmount } from '@/core/numeral.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
|
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||||
|
|
||||||
import { type TransactionMonthlyIncomeAndExpenseData } from '@/models/transaction.ts';
|
import { type TransactionMonthlyIncomeAndExpenseData } from '@/models/transaction.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
parseDateFromUnixTime,
|
parseDateFromUnixTime,
|
||||||
getMonthName
|
getMonthName
|
||||||
@@ -59,7 +63,7 @@ const emit = defineEmits<{
|
|||||||
(e: 'click', event: MonthlyIncomeAndExpenseCardClickEvent): void;
|
(e: 'click', event: MonthlyIncomeAndExpenseCardClickEvent): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getMonthShortName, formatAmountWithCurrency } = useI18n();
|
const { tt, getMonthShortName, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
@@ -275,16 +279,16 @@ const chartOptions = computed<object>(() => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function getDisplayCurrency(value: number | string, currencyCode: string): string {
|
function getDisplayCurrency(value: number | HiddenAmount, currencyCode: string): string {
|
||||||
return formatAmountWithCurrency(value, currencyCode);
|
return formatAmountToLocalizedNumeralsWithCurrency(value, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayAmount(amount: number, incomplete: boolean): string {
|
function getDisplayAmount(amount: number, incomplete: boolean): string {
|
||||||
if (!showAmountInHomePage.value) {
|
if (!showAmountInHomePage.value) {
|
||||||
return getDisplayCurrency('***', defaultCurrency.value);
|
return getDisplayCurrency(DISPLAY_HIDDEN_AMOUNT, defaultCurrency.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getDisplayCurrency(amount, defaultCurrency.value) + (incomplete ? '+' : '');
|
return getDisplayCurrency(amount, defaultCurrency.value) + (incomplete ? INCOMPLETE_AMOUNT_SUFFIX : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayIncomeAmount(data: TransactionMonthlyIncomeAndExpenseData): string {
|
function getDisplayIncomeAmount(data: TransactionMonthlyIncomeAndExpenseData): string {
|
||||||
|
|||||||
@@ -238,7 +238,7 @@
|
|||||||
<div class="d-flex flex-column ml-2">
|
<div class="d-flex flex-column ml-2">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<small class="statistics-percent" v-if="item.percent >= 0">{{ formatPercent(item.percent, 2, '<0.01') }}</small>
|
<small class="statistics-percent" v-if="item.percent >= 0">{{ formatPercentToLocalizedNumerals(item.percent, 2, '<0.01') }}</small>
|
||||||
<v-spacer/>
|
<v-spacer/>
|
||||||
<span class="statistics-amount">{{ getDisplayAmount(item.totalAmount, defaultCurrency) }}</span>
|
<span class="statistics-amount">{{ getDisplayAmount(item.totalAmount, defaultCurrency) }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -374,9 +374,6 @@ import {
|
|||||||
isNumber,
|
isNumber,
|
||||||
arrayItemToObjectField
|
arrayItemToObjectField
|
||||||
} from '@/lib/common.ts';
|
} from '@/lib/common.ts';
|
||||||
import {
|
|
||||||
formatAmount
|
|
||||||
} from '@/lib/numeral.ts';
|
|
||||||
import {
|
import {
|
||||||
getYearAndMonthFromUnixTime,
|
getYearAndMonthFromUnixTime,
|
||||||
getYearMonthFirstUnixTime,
|
getYearMonthFirstUnixTime,
|
||||||
@@ -426,7 +423,14 @@ const props = defineProps<TransactionStatisticsProps>();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const display = useDisplay();
|
const display = useDisplay();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { tt, getAllCategoricalChartTypes, getAllTrendChartTypes, formatPercent } = useI18n();
|
|
||||||
|
const {
|
||||||
|
tt,
|
||||||
|
getAllCategoricalChartTypes,
|
||||||
|
getAllTrendChartTypes,
|
||||||
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping,
|
||||||
|
formatPercentToLocalizedNumerals
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
@@ -956,7 +960,7 @@ function exportResults(): void {
|
|||||||
.filter(item => !item.hidden)
|
.filter(item => !item.hidden)
|
||||||
.map(item => [
|
.map(item => [
|
||||||
item.name,
|
item.name,
|
||||||
formatAmount(item.totalAmount, {}),
|
formatAmountToWesternArabicNumeralsWithoutDigitGrouping(item.totalAmount),
|
||||||
item.percent.toFixed(4)
|
item.percent.toFixed(4)
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -824,7 +824,7 @@
|
|||||||
<v-btn color="teal" :disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0"
|
<v-btn color="teal" :disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0"
|
||||||
:append-icon="!submitting ? mdiArrowRight : undefined" @click="submit"
|
:append-icon="!submitting ? mdiArrowRight : undefined" @click="submit"
|
||||||
v-if="currentStep === 'checkData'">
|
v-if="currentStep === 'checkData'">
|
||||||
{{ (submitting && importProcess > 0 ? tt('format.misc.importingTransactions', { process: formatNumber(importProcess, 2) }) : tt('Import')) }}
|
{{ (submitting && importProcess > 0 ? tt('format.misc.importingTransactions', { process: formatNumberToLocalizedNumerals(importProcess, 2) }) : tt('Import')) }}
|
||||||
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
|
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn color="secondary" variant="tonal"
|
<v-btn color="secondary" variant="tonal"
|
||||||
@@ -998,8 +998,8 @@ const {
|
|||||||
getAllImportTransactionColumnTypes,
|
getAllImportTransactionColumnTypes,
|
||||||
getAllSupportedImportFileTypes,
|
getAllSupportedImportFileTypes,
|
||||||
formatUnixTimeToLongDateTime,
|
formatUnixTimeToLongDateTime,
|
||||||
formatAmountWithCurrency,
|
formatAmountToLocalizedNumeralsWithCurrency,
|
||||||
formatNumber,
|
formatNumberToLocalizedNumerals,
|
||||||
getCategorizedAccountsWithDisplayBalance
|
getCategorizedAccountsWithDisplayBalance
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
@@ -1680,7 +1680,7 @@ function getDisplayTimezone(transaction: ImportTransaction): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayCurrency(value: number, currencyCode: string): string {
|
function getDisplayCurrency(value: number, currencyCode: string): string {
|
||||||
return formatAmountWithCurrency(value, currencyCode);
|
return formatAmountToLocalizedNumeralsWithCurrency(value, currencyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransactionDisplayAmount(transaction: ImportTransaction): string {
|
function getTransactionDisplayAmount(transaction: ImportTransaction): string {
|
||||||
|
|||||||
@@ -243,6 +243,19 @@
|
|||||||
/>
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="12" md="6">
|
||||||
|
<v-select
|
||||||
|
item-title="displayName"
|
||||||
|
item-value="type"
|
||||||
|
persistent-placeholder
|
||||||
|
:disabled="loading || saving"
|
||||||
|
:label="tt('Numeral System')"
|
||||||
|
:placeholder="tt('Numeral System')"
|
||||||
|
:items="allNumeralSystemTypes"
|
||||||
|
v-model="newProfile.numeralSystem"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
<v-col cols="12" md="6">
|
<v-col cols="12" md="6">
|
||||||
<v-select
|
<v-select
|
||||||
item-title="displayName"
|
item-title="displayName"
|
||||||
@@ -401,10 +414,11 @@ const {
|
|||||||
allLongTimeFormats,
|
allLongTimeFormats,
|
||||||
allShortTimeFormats,
|
allShortTimeFormats,
|
||||||
allFiscalYearFormats,
|
allFiscalYearFormats,
|
||||||
|
allCurrencyDisplayTypes,
|
||||||
|
allNumeralSystemTypes,
|
||||||
allDecimalSeparators,
|
allDecimalSeparators,
|
||||||
allDigitGroupingSymbols,
|
allDigitGroupingSymbols,
|
||||||
allDigitGroupingTypes,
|
allDigitGroupingTypes,
|
||||||
allCurrencyDisplayTypes,
|
|
||||||
allCoordinateDisplayTypes,
|
allCoordinateDisplayTypes,
|
||||||
allExpenseAmountColorTypes,
|
allExpenseAmountColorTypes,
|
||||||
allIncomeAmountColorTypes,
|
allIncomeAmountColorTypes,
|
||||||
|
|||||||
@@ -556,8 +556,17 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getAllCurrencies, getCurrencyName, formatUnixTimeToLongDate, formatUnixTimeToLongTime, formatAmountWithCurrency } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
getAllCurrencies,
|
||||||
|
getCurrencyName,
|
||||||
|
formatUnixTimeToLongDate,
|
||||||
|
formatUnixTimeToLongTime,
|
||||||
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
editAccountId,
|
editAccountId,
|
||||||
clientSessionId,
|
clientSessionId,
|
||||||
@@ -604,7 +613,7 @@ const allCurrencies = computed<LocalizedCurrencyInfo[]>(() => getAllCurrencies()
|
|||||||
|
|
||||||
function formatAccountDisplayBalance(selectedAccount: Account): string {
|
function formatAccountDisplayBalance(selectedAccount: Account): string {
|
||||||
const balance = account.value.isLiability ? -selectedAccount.balance : selectedAccount.balance;
|
const balance = account.value.isLiability ? -selectedAccount.balance : selectedAccount.balance;
|
||||||
return formatAmountWithCurrency(balance, selectedAccount.currency);
|
return formatAmountToLocalizedNumeralsWithCurrency(balance, selectedAccount.currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatAccountBalanceDate(account: Account): string {
|
function formatAccountBalanceDate(account: Account): string {
|
||||||
|
|||||||
@@ -76,8 +76,8 @@
|
|||||||
|
|
||||||
<f7-list strong inset dividers class="margin-vertical" v-if="finishQuery && !loading">
|
<f7-list strong inset dividers class="margin-vertical" v-if="finishQuery && !loading">
|
||||||
<f7-list-item :title="tt('Total Transactions')"
|
<f7-list-item :title="tt('Total Transactions')"
|
||||||
:after="reconciliationStatements?.transactions.length"
|
:after="formatNumberToLocalizedNumerals(reconciliationStatements.transactions.length)"
|
||||||
v-if="reconciliationStatements?.transactions.length"></f7-list-item>
|
v-if="reconciliationStatements && reconciliationStatements.transactions"></f7-list-item>
|
||||||
<f7-list-item :title="tt('Total Inflows')" :after="displayTotalInflows"></f7-list-item>
|
<f7-list-item :title="tt('Total Inflows')" :after="displayTotalInflows"></f7-list-item>
|
||||||
<f7-list-item :title="tt('Total Outflows')" :after="displayTotalOutflows"></f7-list-item>
|
<f7-list-item :title="tt('Total Outflows')" :after="displayTotalOutflows"></f7-list-item>
|
||||||
<f7-list-item :title="tt('Net Cash Flow')" :after="displayTotalBalance"></f7-list-item>
|
<f7-list-item :title="tt('Net Cash Flow')" :after="displayTotalBalance"></f7-list-item>
|
||||||
@@ -386,7 +386,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime } = useI18n();
|
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime, formatNumberToLocalizedNumerals } = useI18n();
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
<f7-list strong inset dividers class="margin-vertical" v-if="exchangeRatesData && exchangeRatesData.exchangeRates && exchangeRatesData.exchangeRates.length">
|
<f7-list strong inset dividers class="margin-vertical" v-if="exchangeRatesData && exchangeRatesData.exchangeRates && exchangeRatesData.exchangeRates.length">
|
||||||
<f7-list-item swipeout
|
<f7-list-item swipeout
|
||||||
:id="getExchangeRateDomId(exchangeRate)"
|
:id="getExchangeRateDomId(exchangeRate)"
|
||||||
:after="getFinalConvertedAmount(exchangeRate)"
|
:after="getFinalConvertedAmount(exchangeRate, true)"
|
||||||
:key="baseCurrencyChangedTime + '_' + exchangeRate.currencyCode" v-for="exchangeRate in availableExchangeRates"
|
:key="baseCurrencyChangedTime + '_' + exchangeRate.currencyCode" v-for="exchangeRate in availableExchangeRates"
|
||||||
@swipeout:closed="onExchangeRateSwipeoutClosed()">
|
@swipeout:closed="onExchangeRateSwipeoutClosed()">
|
||||||
<template #title>
|
<template #title>
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<f7-swipeout-button color="primary" close
|
<f7-swipeout-button color="primary" close
|
||||||
:text="tt('Set as Base')"
|
:text="tt('Set as Base')"
|
||||||
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
|
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
|
||||||
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate)); settingBaseLine = true"
|
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false)); settingBaseLine = true"
|
||||||
v-if="settingBaseLine || exchangeRate.currencyCode !== baseCurrency"></f7-swipeout-button>
|
v-if="settingBaseLine || exchangeRate.currencyCode !== baseCurrency"></f7-swipeout-button>
|
||||||
<f7-swipeout-button color="red" class="padding-left padding-right"
|
<f7-swipeout-button color="red" class="padding-left padding-right"
|
||||||
@click="remove(exchangeRate, false)"
|
@click="remove(exchangeRate, false)"
|
||||||
@@ -134,6 +134,7 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
|
|||||||
|
|
||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||||
|
|
||||||
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
import type { LocalizedLatestExchangeRate } from '@/models/exchange_rate.ts';
|
||||||
@@ -146,8 +147,16 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getCurrencyName, formatAmount, formatExchangeRateAmount } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
getCurrentNumeralSystemType,
|
||||||
|
getCurrencyName,
|
||||||
|
formatAmountToLocalizedNumerals,
|
||||||
|
formatExchangeRateAmountToWesternArabicNumerals
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { showAlert, showToast } = useI18nUIComponents();
|
const { showAlert, showToast } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
baseCurrency,
|
baseCurrency,
|
||||||
baseAmount,
|
baseAmount,
|
||||||
@@ -171,7 +180,7 @@ const showBaseAmountSheet = ref<boolean>(false);
|
|||||||
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
|
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
|
||||||
const showDeleteActionSheet = ref<boolean>(false);
|
const showDeleteActionSheet = ref<boolean>(false);
|
||||||
|
|
||||||
const displayBaseAmount = computed<string>(() => formatAmount(baseAmount.value, baseCurrency.value));
|
const displayBaseAmount = computed<string>(() => formatAmountToLocalizedNumerals(baseAmount.value, baseCurrency.value));
|
||||||
const baseAmountFontSizeClass = computed<string>(() => {
|
const baseAmountFontSizeClass = computed<string>(() => {
|
||||||
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
|
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
|
||||||
return 'ebk-small-amount';
|
return 'ebk-small-amount';
|
||||||
@@ -260,15 +269,26 @@ function remove(customExchangeRate: LocalizedLatestExchangeRate | null, confirm:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate): string {
|
function getFinalConvertedAmount(toExchangeRate: LocalizedLatestExchangeRate, displayLocalizedDigits: boolean): string {
|
||||||
|
const numeralSystem = getCurrentNumeralSystemType();
|
||||||
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
|
const fromExchangeRate = exchangeRatesStore.latestExchangeRateMap[baseCurrency.value];
|
||||||
const exchangeRateAmount = getConvertedAmount(baseAmount.value / 100, fromExchangeRate, toExchangeRate);
|
const exchangeRateAmount = getConvertedAmount(baseAmount.value / 100, fromExchangeRate, toExchangeRate);
|
||||||
|
|
||||||
if (!exchangeRateAmount) {
|
if (!exchangeRateAmount) {
|
||||||
return '0';
|
if (displayLocalizedDigits) {
|
||||||
|
return numeralSystem.digitZero;
|
||||||
|
} else {
|
||||||
|
return NumeralSystem.WesternArabicNumerals.digitZero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatExchangeRateAmount(exchangeRateAmount);
|
let ret = formatExchangeRateAmountToWesternArabicNumerals(exchangeRateAmount);
|
||||||
|
|
||||||
|
if (displayLocalizedDigits) {
|
||||||
|
ret = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onExchangeRateSwipeoutClosed(): void {
|
function onExchangeRateSwipeoutClosed(): void {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<small>{{ currentLongYearMonth }}</small>
|
<small>{{ currentLongYearMonth }}</small>
|
||||||
<small class="transaction-amount-statistics">
|
<small class="transaction-amount-statistics">
|
||||||
<span class="text-income">{{ `+${formatAmountWithCurrency('12345')}` }}</span>
|
<span class="text-income">{{ `+${formatAmountToLocalizedNumeralsWithCurrency(12345)}` }}</span>
|
||||||
<span class="text-expense">{{ `-${formatAmountWithCurrency('67890')}` }}</span>
|
<span class="text-expense">{{ `-${formatAmountToLocalizedNumeralsWithCurrency(67890)}` }}</span>
|
||||||
</small>
|
</small>
|
||||||
<f7-icon class="combination-list-chevron-icon" f7="chevron_up"></f7-icon>
|
<f7-icon class="combination-list-chevron-icon" f7="chevron_up"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="item-after">
|
<div class="item-after">
|
||||||
<div class="transaction-amount">
|
<div class="transaction-amount">
|
||||||
<span>{{ formatAmountWithCurrency('12345') }}</span>
|
<span>{{ formatAmountToLocalizedNumeralsWithCurrency(12345) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -128,7 +128,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getWeekdayShortName, formatUnixTimeToLongYearMonth, formatUnixTimeToShortTime, formatAmountWithCurrency } = useI18n();
|
const { tt, getWeekdayShortName, formatUnixTimeToLongYearMonth, formatUnixTimeToShortTime, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<div class="statistics-list-item-text">
|
<div class="statistics-list-item-text">
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<small class="statistics-percent" v-if="item.percent >= 0">{{ formatPercent(item.percent, 2, '<0.01') }}</small>
|
<small class="statistics-percent" v-if="item.percent >= 0">{{ formatPercentToLocalizedNumerals(item.percent, 2, '<0.01') }}</small>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -367,7 +367,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getAllCategoricalChartTypes, formatPercent } = useI18n();
|
const { tt, getAllCategoricalChartTypes, formatPercentToLocalizedNumerals } = useI18n();
|
||||||
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
class="ebk-small-amount"
|
class="ebk-small-amount"
|
||||||
link="#" no-chevron
|
link="#" no-chevron
|
||||||
:header="amount1Header"
|
:header="amount1Header"
|
||||||
:title="formatAmountWithCurrency(amount1)"
|
:title="formatAmountToLocalizedNumeralsWithCurrency(amount1)"
|
||||||
@click="showAmount1Sheet = true"
|
@click="showAmount1Sheet = true"
|
||||||
>
|
>
|
||||||
<number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
|
<number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
class="ebk-small-amount"
|
class="ebk-small-amount"
|
||||||
link="#" no-chevron
|
link="#" no-chevron
|
||||||
:header="amount2Header"
|
:header="amount2Header"
|
||||||
:title="formatAmountWithCurrency(amount2)"
|
:title="formatAmountToLocalizedNumeralsWithCurrency(amount2)"
|
||||||
@click="showAmount2Sheet = true"
|
@click="showAmount2Sheet = true"
|
||||||
v-if="amountCount === 2"
|
v-if="amountCount === 2"
|
||||||
>
|
>
|
||||||
@@ -76,7 +76,7 @@ const amount2 = ref<number>(0);
|
|||||||
const showAmount1Sheet = ref<boolean>(false);
|
const showAmount1Sheet = ref<boolean>(false);
|
||||||
const showAmount2Sheet = ref<boolean>(false);
|
const showAmount2Sheet = ref<boolean>(false);
|
||||||
|
|
||||||
const { tt, formatAmountWithCurrency } = useI18n();
|
const { tt, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||||
const { showToast } = useI18nUIComponents();
|
const { showToast } = useI18nUIComponents();
|
||||||
|
|
||||||
const transactionsStore = useTransactionsStore();
|
const transactionsStore = useTransactionsStore();
|
||||||
|
|||||||
@@ -343,6 +343,26 @@
|
|||||||
</list-item-selection-popup>
|
</list-item-selection-popup>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
|
|
||||||
|
<f7-list-item
|
||||||
|
link="#"
|
||||||
|
class="list-item-with-header-and-title list-item-no-item-after"
|
||||||
|
:header="tt('Numeral System')"
|
||||||
|
:title="findDisplayNameByType(allNumeralSystemTypes, newProfile.numeralSystem)"
|
||||||
|
@click="showNumberSystemPopup = true"
|
||||||
|
>
|
||||||
|
<list-item-selection-popup value-type="item"
|
||||||
|
key-field="type" value-field="type"
|
||||||
|
title-field="displayName"
|
||||||
|
:title="tt('Numeral System')"
|
||||||
|
:enable-filter="true"
|
||||||
|
:filter-placeholder="tt('Numeral System')"
|
||||||
|
:filter-no-items-text="tt('No results')"
|
||||||
|
:items="allNumeralSystemTypes"
|
||||||
|
v-model:show="showNumberSystemPopup"
|
||||||
|
v-model="newProfile.numeralSystem">
|
||||||
|
</list-item-selection-popup>
|
||||||
|
</f7-list-item>
|
||||||
|
|
||||||
<f7-list-item
|
<f7-list-item
|
||||||
link="#"
|
link="#"
|
||||||
class="list-item-with-header-and-title list-item-no-item-after"
|
class="list-item-with-header-and-title list-item-no-item-after"
|
||||||
@@ -536,10 +556,11 @@ const {
|
|||||||
allLongTimeFormats,
|
allLongTimeFormats,
|
||||||
allShortTimeFormats,
|
allShortTimeFormats,
|
||||||
allFiscalYearFormats,
|
allFiscalYearFormats,
|
||||||
|
allCurrencyDisplayTypes,
|
||||||
|
allNumeralSystemTypes,
|
||||||
allDecimalSeparators,
|
allDecimalSeparators,
|
||||||
allDigitGroupingSymbols,
|
allDigitGroupingSymbols,
|
||||||
allDigitGroupingTypes,
|
allDigitGroupingTypes,
|
||||||
allCurrencyDisplayTypes,
|
|
||||||
allCoordinateDisplayTypes,
|
allCoordinateDisplayTypes,
|
||||||
allExpenseAmountColorTypes,
|
allExpenseAmountColorTypes,
|
||||||
allIncomeAmountColorTypes,
|
allIncomeAmountColorTypes,
|
||||||
@@ -577,6 +598,7 @@ const showLongTimeFormatPopup = ref<boolean>(false);
|
|||||||
const showShortTimeFormatPopup = ref<boolean>(false);
|
const showShortTimeFormatPopup = ref<boolean>(false);
|
||||||
const showFiscalYearFormatPopup = ref<boolean>(false);
|
const showFiscalYearFormatPopup = ref<boolean>(false);
|
||||||
const showCurrencyDisplayTypePopup = ref<boolean>(false);
|
const showCurrencyDisplayTypePopup = ref<boolean>(false);
|
||||||
|
const showNumberSystemPopup = ref<boolean>(false);
|
||||||
const showDigitGroupingPopup = ref<boolean>(false);
|
const showDigitGroupingPopup = ref<boolean>(false);
|
||||||
const showDigitGroupingSymbolPopup = ref<boolean>(false);
|
const showDigitGroupingSymbolPopup = ref<boolean>(false);
|
||||||
const showDecimalSeparatorPopup = ref<boolean>(false);
|
const showDecimalSeparatorPopup = ref<boolean>(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user