Feature - Add support for a fiscal year period defined in user settings.

* Add "This fiscal year", "Last fiscal year" as date range options in Transaction Details to filter transactions to those periods
* Add fiscal year ranges to Statistics & Trend Analysis
* Add "fiscal year start date" to user profile settings, allowing the user to select any date of the calendar year as the start of the fiscal year
* Add "fiscal year format" to user profile settings, allowing the user to specify how financial year date labels should appear

Implementation notes:
* The default fiscal year start is January 1 and the default fiscal year display format is "FY 2025"
* Fiscal year start date (month number & day number) are stored together in db as a uint16, high byte & low byte respectively
* February 29 is disallowed as a fiscal year start date, since it is never used as a convention in any country
* Jest is added to the project as a dev dependency, for unit tests in frontend

Signed-off-by: Sebastian Reategui <seb.reategui@gmail.com>
This commit is contained in:
Sebastian Reategui
2025-06-05 12:36:46 +10:00
committed by mayswind
parent 70eea8ff33
commit b94dc8eb83
42 changed files with 3417 additions and 105 deletions
+15
View File
@@ -5,6 +5,7 @@ import { CoordinateDisplayType } from '@/core/coordinate.ts';
import { PresetAmountColor } from '@/core/color.ts';
import type { LocalizedPresetCategory } from '@/core/category.ts';
import { TransactionEditScopeType } from '@/core/transaction.ts';
import { FiscalYearFormat, FiscalYearStart } from '@/core/fiscalyear';
export class User {
public username: string = '';
@@ -18,6 +19,8 @@ export class User {
public defaultAccountId: string = '';
public transactionEditScope: number = 1;
public fiscalYearStart: number = 0;
public fiscalYearFormat: number = 0;
public longDateFormat: number = 0;
public shortDateFormat: number = 0;
public longTimeFormat: number = 0;
@@ -45,10 +48,12 @@ export class User {
this.firstDayOfWeek = user.firstDayOfWeek;
this.defaultAccountId = user.defaultAccountId;
this.transactionEditScope = user.transactionEditScope;
this.fiscalYearStart = user.fiscalYearStart;
this.longDateFormat = user.longDateFormat;
this.shortDateFormat = user.shortDateFormat;
this.longTimeFormat = user.longTimeFormat;
this.shortTimeFormat = user.shortTimeFormat;
this.fiscalYearFormat = user.fiscalYearFormat;
this.decimalSeparator = user.decimalSeparator;
this.digitGroupingSymbol = user.digitGroupingSymbol;
this.digitGrouping = user.digitGrouping;
@@ -82,10 +87,12 @@ export class User {
language: this.language,
defaultCurrency: this.defaultCurrency,
firstDayOfWeek: this.firstDayOfWeek,
fiscalYearStart: this.fiscalYearStart,
longDateFormat: this.longDateFormat,
shortDateFormat: this.shortDateFormat,
longTimeFormat: this.longTimeFormat,
shortTimeFormat: this.shortTimeFormat,
fiscalYearFormat: this.fiscalYearFormat,
decimalSeparator: this.decimalSeparator,
digitGroupingSymbol: this.digitGroupingSymbol,
digitGrouping: this.digitGrouping,
@@ -100,10 +107,12 @@ export class User {
const user = new User(userInfo.language, userInfo.defaultCurrency, userInfo.firstDayOfWeek);
user.defaultAccountId = userInfo.defaultAccountId;
user.transactionEditScope = userInfo.transactionEditScope;
user.fiscalYearStart = userInfo.fiscalYearStart;
user.longDateFormat = userInfo.longDateFormat;
user.shortDateFormat = userInfo.shortDateFormat;
user.longTimeFormat = userInfo.longTimeFormat;
user.shortTimeFormat = userInfo.shortTimeFormat;
user.fiscalYearFormat = userInfo.fiscalYearFormat;
user.decimalSeparator = userInfo.decimalSeparator;
user.digitGroupingSymbol = userInfo.digitGroupingSymbol;
user.digitGrouping = userInfo.digitGrouping;
@@ -130,11 +139,13 @@ export interface UserBasicInfo {
readonly transactionEditScope: number;
readonly language: string;
readonly defaultCurrency: string;
readonly fiscalYearStart: number;
readonly firstDayOfWeek: number;
readonly longDateFormat: number;
readonly shortDateFormat: number;
readonly longTimeFormat: number;
readonly shortTimeFormat: number;
readonly fiscalYearFormat: number;
readonly decimalSeparator: number;
readonly digitGroupingSymbol: number;
readonly digitGrouping: number;
@@ -182,10 +193,12 @@ export interface UserProfileUpdateRequest {
readonly language?: string;
readonly defaultCurrency?: string;
readonly firstDayOfWeek?: number;
readonly fiscalYearStart?: number;
readonly longDateFormat?: number;
readonly shortDateFormat?: number;
readonly longTimeFormat?: number;
readonly shortTimeFormat?: number;
readonly fiscalYearFormat?: number;
readonly decimalSeparator?: number;
readonly digitGroupingSymbol?: number;
readonly digitGrouping?: number;
@@ -215,10 +228,12 @@ export const EMPTY_USER_BASIC_INFO: UserBasicInfo = {
language: '',
defaultCurrency: '',
firstDayOfWeek: -1,
fiscalYearStart: FiscalYearStart.Default.value,
longDateFormat: LongDateFormat.Default.type,
shortDateFormat: ShortDateFormat.Default.type,
longTimeFormat: LongTimeFormat.Default.type,
shortTimeFormat: ShortTimeFormat.Default.type,
fiscalYearFormat: FiscalYearFormat.Default.type,
decimalSeparator: DecimalSeparator.LanguageDefaultType,
digitGroupingSymbol: DigitGroupingSymbol.LanguageDefaultType,
digitGrouping: DigitGroupingType.LanguageDefaultType,