use for-of statements to replace for and for-in
This commit is contained in:
@@ -151,14 +151,8 @@ function updateFrequencyValue(value: number, selected: boolean | null): void {
|
||||
frequencyValue.value = sortNumbersArray(newFrequencyValues);
|
||||
}
|
||||
|
||||
function isFrequencyValueSelected(value: number): boolean {
|
||||
for (let i = 0; i < frequencyValue.value.length; i++) {
|
||||
if (frequencyValue.value[i] === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
function isFrequencyValueSelected(currentValue: number): boolean {
|
||||
return frequencyValue.value.indexOf(currentValue) >= 0;
|
||||
}
|
||||
|
||||
function onMenuStateChanged(state: boolean): void {
|
||||
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
useAccountBalanceTrendsChartBase
|
||||
} from '@/components/base/AccountBalanceTrendsChartBase.ts'
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import type { ColorStyleValue } from '@/core/color.ts';
|
||||
import { DEFAULT_CHART_COLORS } from '@/consts/color.ts';
|
||||
|
||||
@@ -88,15 +89,13 @@ const allVirtualListItems = computed<MobileAccountBalanceTrendsChartItem[]>(() =
|
||||
const ret: MobileAccountBalanceTrendsChartItem[] = [];
|
||||
let maxClosingBalance = 0;
|
||||
|
||||
for (let i = 0; i < allDataItems.value.length; i++) {
|
||||
const dataItem = allDataItems.value[i];
|
||||
|
||||
for (const [dataItem, index] of itemAndIndex(allDataItems.value)) {
|
||||
if (dataItem.closingBalance > maxClosingBalance) {
|
||||
maxClosingBalance = dataItem.closingBalance;
|
||||
}
|
||||
|
||||
const finalDataItem: MobileAccountBalanceTrendsChartItem = {
|
||||
index: i,
|
||||
index: index,
|
||||
displayDate: dataItem.displayDate,
|
||||
openingBalance: dataItem.openingBalance,
|
||||
closingBalance: dataItem.closingBalance,
|
||||
@@ -104,18 +103,18 @@ const allVirtualListItems = computed<MobileAccountBalanceTrendsChartItem[]>(() =
|
||||
averageBalance: dataItem.averageBalance,
|
||||
minimumBalance: dataItem.minimumBalance,
|
||||
maximumBalance: dataItem.maximumBalance,
|
||||
color: `#${DEFAULT_CHART_COLORS[0]}`,
|
||||
color: `#${DEFAULT_CHART_COLORS[0] as string}`,
|
||||
percent: 0.0
|
||||
};
|
||||
|
||||
ret.push(finalDataItem);
|
||||
}
|
||||
|
||||
for (let i = 0; i < ret.length; i++) {
|
||||
if (maxClosingBalance > 0 && ret[i].closingBalance > 0) {
|
||||
ret[i].percent = 100.0 * ret[i].closingBalance / maxClosingBalance;
|
||||
for (const item of ret) {
|
||||
if (maxClosingBalance > 0 && item.closingBalance > 0) {
|
||||
item.percent = 100.0 * item.closingBalance / maxClosingBalance;
|
||||
} else {
|
||||
ret[i].percent = 0.0;
|
||||
item.percent = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ import { type CommonScheduleFrequencySelectionProps, useScheduleFrequencySelecti
|
||||
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import { type WeekDayValue } from '@/core/datetime.ts';
|
||||
import { ScheduledTemplateFrequencyType } from '@/core/template.ts';
|
||||
import { sortNumbersArray } from '@/lib/common.ts';
|
||||
@@ -117,20 +118,20 @@ function changeFrequencyType(value: number): void {
|
||||
}
|
||||
|
||||
function changeFrequencyValue(e: Event): void {
|
||||
const value = parseInt((e.target as HTMLInputElement).value);
|
||||
const currentValue = parseInt((e.target as HTMLInputElement).value);
|
||||
|
||||
if ((e.target as HTMLInputElement).checked) {
|
||||
for (let i = 0; i < currentFrequencyValue.value.length; i++) {
|
||||
if (currentFrequencyValue.value[i] === value) {
|
||||
for (const value of currentFrequencyValue.value) {
|
||||
if (value === currentValue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
currentFrequencyValue.value.push(value);
|
||||
currentFrequencyValue.value.push(currentValue);
|
||||
} else {
|
||||
for (let i = 0; i < currentFrequencyValue.value.length; i++) {
|
||||
if (currentFrequencyValue.value[i] === value) {
|
||||
currentFrequencyValue.value.splice(i, 1);
|
||||
for (const [value, index] of itemAndIndex(currentFrequencyValue.value)) {
|
||||
if (value === currentValue) {
|
||||
currentFrequencyValue.value.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,9 +103,7 @@ function isPrimaryItemHasSecondaryValue(primaryItem: Record<string, unknown>): b
|
||||
|
||||
const lowerCaseFilterContent = filterContent.value?.toLowerCase() ?? '';
|
||||
|
||||
for (let i = 0; i < subItems.length; i++) {
|
||||
const secondaryItem = subItems[i];
|
||||
|
||||
for (const secondaryItem of subItems) {
|
||||
if (props.secondaryHiddenField && (secondaryItem as Record<string, unknown>)[props.secondaryHiddenField]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { TypeAndName, TypeAndDisplayName } from './base.ts';
|
||||
import { type TypeAndName, type TypeAndDisplayName, entries, keys } from './base.ts';
|
||||
import { KnownAmountFormat } from './numeral.ts';
|
||||
import { KnownDateTimeFormat } from './datetime.ts';
|
||||
import { KnownDateTimezoneFormat } from './timezone.ts';
|
||||
@@ -92,9 +92,9 @@ export class ImportTransactionDataMapping {
|
||||
this.dataColumnMapping[columnType] = columnIndex;
|
||||
}
|
||||
|
||||
for (const otherColumnType in this.dataColumnMapping) {
|
||||
if (otherColumnType !== columnType.toString() && this.dataColumnMapping[otherColumnType] === columnIndex) {
|
||||
delete this.dataColumnMapping[otherColumnType];
|
||||
for (const otherColumnType of keys(this.dataColumnMapping)) {
|
||||
if (otherColumnType !== columnType.toString() && this.dataColumnMapping[parseInt(otherColumnType)] === columnIndex) {
|
||||
delete this.dataColumnMapping[parseInt(otherColumnType)];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,16 +119,22 @@ export class ImportTransactionDataMapping {
|
||||
|
||||
const allTypeMap: Record<string, boolean> = {};
|
||||
const allTypes: string[] = [];
|
||||
const typeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionType.type];
|
||||
const typeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionType.type] as number;
|
||||
|
||||
const startIndex = this.includeHeader ? 1 : 0;
|
||||
|
||||
for (let i = startIndex; i < fileData.length; i++) {
|
||||
if (fileData[i].length <= typeColumnIndex) {
|
||||
const items = fileData[i];
|
||||
|
||||
if (!items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const type = fileData[i][typeColumnIndex];
|
||||
if (items.length <= typeColumnIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const type = items[typeColumnIndex];
|
||||
|
||||
if (type && !allTypeMap[type]) {
|
||||
allTypes.push(type);
|
||||
@@ -150,13 +156,7 @@ export class ImportTransactionDataMapping {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const name in this.transactionTypeMapping) {
|
||||
if (!Object.prototype.hasOwnProperty.call(this.transactionTypeMapping, name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const type = this.transactionTypeMapping[name];
|
||||
|
||||
for (const [name, type] of entries(this.transactionTypeMapping)) {
|
||||
if (TransactionType.ModifyBalance <= type && type <= TransactionType.Transfer) {
|
||||
result[name] = type;
|
||||
}
|
||||
@@ -171,16 +171,22 @@ export class ImportTransactionDataMapping {
|
||||
}
|
||||
|
||||
const allDateTimes: string[] = [];
|
||||
const dateTimeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTime.type];
|
||||
const dateTimeColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTime.type] as number;
|
||||
|
||||
const startIndex = this.includeHeader ? 1 : 0;
|
||||
|
||||
for (let i = startIndex; i < fileData.length; i++) {
|
||||
if (fileData[i].length <= dateTimeColumnIndex) {
|
||||
const items = fileData[i];
|
||||
|
||||
if (!items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dateTime = fileData[i][dateTimeColumnIndex];
|
||||
if (items.length <= dateTimeColumnIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dateTime = items[dateTimeColumnIndex];
|
||||
|
||||
if (dateTime) {
|
||||
allDateTimes.push(dateTime);
|
||||
@@ -193,7 +199,7 @@ export class ImportTransactionDataMapping {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return detectedFormats[0].format;
|
||||
return detectedFormats[0]!.format;
|
||||
}
|
||||
|
||||
public parseFileAutoDetectedTimezoneFormat(fileData: string[][] | undefined): string | undefined {
|
||||
@@ -202,16 +208,22 @@ export class ImportTransactionDataMapping {
|
||||
}
|
||||
|
||||
const allTimezones: string[] = [];
|
||||
const timezoneColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTimezone.type];
|
||||
const timezoneColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.TransactionTimezone.type] as number;
|
||||
|
||||
const startIndex = this.includeHeader ? 1 : 0;
|
||||
|
||||
for (let i = startIndex; i < fileData.length; i++) {
|
||||
if (fileData[i].length <= timezoneColumnIndex) {
|
||||
const items = fileData[i];
|
||||
|
||||
if (!items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const timezone = fileData[i][timezoneColumnIndex];
|
||||
if (items.length <= timezoneColumnIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const timezone = items[timezoneColumnIndex];
|
||||
|
||||
if (timezone) {
|
||||
allTimezones.push(timezone);
|
||||
@@ -224,7 +236,7 @@ export class ImportTransactionDataMapping {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return detectedFormats[0].value;
|
||||
return detectedFormats[0]!.value;
|
||||
}
|
||||
|
||||
public parseFileAutoDetectedAmountFormat(fileData: string[][] | undefined): string | undefined {
|
||||
@@ -233,16 +245,22 @@ export class ImportTransactionDataMapping {
|
||||
}
|
||||
|
||||
const allAmounts: string[] = [];
|
||||
const amountColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.Amount.type];
|
||||
const amountColumnIndex = this.dataColumnMapping[ImportTransactionColumnType.Amount.type] as number;
|
||||
|
||||
const startIndex = this.includeHeader ? 1 : 0;
|
||||
|
||||
for (let i = startIndex; i < fileData.length; i++) {
|
||||
if (fileData[i].length <= amountColumnIndex) {
|
||||
const items = fileData[i];
|
||||
|
||||
if (!items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const amount = fileData[i][amountColumnIndex];
|
||||
if (items.length <= amountColumnIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const amount = items[amountColumnIndex];
|
||||
|
||||
if (amount) {
|
||||
allAmounts.push(amount);
|
||||
@@ -255,7 +273,7 @@ export class ImportTransactionDataMapping {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return detectedFormats[0].type;
|
||||
return detectedFormats[0]!.type;
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
@@ -382,8 +400,7 @@ export class ImportTransactionReplaceRules {
|
||||
public toJson(): string {
|
||||
const result: unknown[] = [];
|
||||
|
||||
for (let i = 0; i < this.rules.length; i++) {
|
||||
const rule = this.rules[i];
|
||||
for (const rule of this.rules) {
|
||||
result.push(rule.toJsonObject());
|
||||
}
|
||||
|
||||
@@ -407,8 +424,7 @@ export class ImportTransactionReplaceRules {
|
||||
|
||||
const result = new ImportTransactionReplaceRules([]);
|
||||
|
||||
for (let i = 0; i < root.length; i++) {
|
||||
const rule = root[i];
|
||||
for (const rule of root) {
|
||||
const replaceRule = ImportTransactionReplaceRule.parse(rule);
|
||||
|
||||
if (replaceRule) {
|
||||
|
||||
@@ -3,6 +3,8 @@ import path from 'path';
|
||||
import { describe, expect, test } from '@jest/globals';
|
||||
|
||||
import { DEFAULT_CONTENT } from '@/locales/calendar/chinese/index.ts';
|
||||
|
||||
import { itemAndIndex, entries } from '@/core/base.ts';
|
||||
import type { ChineseCalendarLocaleData } from '@/core/calendar.ts';
|
||||
import {
|
||||
type ChineseYearMonthDayInfo,
|
||||
@@ -90,12 +92,12 @@ describe('getChineseYearMonthAllDayInfos', () => {
|
||||
allMonthChineseDays[`${currentYear}-${currentMonth}`] = currentMonthChineseDays;
|
||||
allMonthSolarTermNames[`${currentYear}-${currentMonth}`] = currentMonthSolarTermNames;
|
||||
|
||||
for (const yearMonth in allMonthChineseDays) {
|
||||
for (const [yearMonth, monthChineseDays] of entries(allMonthChineseDays)) {
|
||||
test(`returns correct chinese all dates in month for ${yearMonth}`, () => {
|
||||
const [yearStr, monthStr] = yearMonth.split('-');
|
||||
const year = parseInt(yearStr as string);
|
||||
const month = parseInt(monthStr as string);
|
||||
const expectedChineseMonthOrDays = allMonthChineseDays[yearMonth] as string[];
|
||||
const expectedChineseMonthOrDays = monthChineseDays;
|
||||
const expectedSolarTermNames = allMonthSolarTermNames[yearMonth] as string[];
|
||||
|
||||
const actualChineseDates: ChineseYearMonthDayInfo[] | undefined = getChineseYearMonthAllDayInfos({
|
||||
@@ -106,13 +108,12 @@ describe('getChineseYearMonthAllDayInfos', () => {
|
||||
expect(actualChineseDates).toBeDefined();
|
||||
|
||||
if (actualChineseDates) {
|
||||
for (let i = 0; i < actualChineseDates.length; i++) {
|
||||
const actualChineseDate = actualChineseDates[i];
|
||||
for (const [actualChineseDate, index] of itemAndIndex(actualChineseDates)) {
|
||||
const chineseMonthOrDay: string | undefined = actualChineseDate?.day === 1 ? `${actualChineseDate?.month}${ordinalSuffix[actualChineseDate?.month - 1] ?? 'th'} Lunar Month`.toLowerCase() : actualChineseDate?.day.toString();
|
||||
|
||||
expect(actualChineseDate).toBeDefined();
|
||||
expect(chineseMonthOrDay).toBe(expectedChineseMonthOrDays[i]);
|
||||
expect(actualChineseDate?.solarTermName).toBe(expectedSolarTermNames[i]);
|
||||
expect(chineseMonthOrDay).toBe(expectedChineseMonthOrDays[index]);
|
||||
expect(actualChineseDate?.solarTermName).toBe(expectedSolarTermNames[index]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+2
-2
@@ -71,7 +71,7 @@ export function localizedPresetCategoriesToTransactionCategoryCreateWithSubCateg
|
||||
return categories;
|
||||
}
|
||||
|
||||
export function getSecondaryTransactionMapByName(allCategories: TransactionCategory[]): Record<string, TransactionCategory> {
|
||||
export function getSecondaryTransactionMapByName(allCategories?: TransactionCategory[]): Record<string, TransactionCategory> {
|
||||
const ret: Record<string, TransactionCategory> = {};
|
||||
|
||||
if (!allCategories) {
|
||||
@@ -274,7 +274,7 @@ export function isSubCategoryIdAvailable(categories: TransactionCategory[], cate
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getFirstAvailableCategoryId(categories: TransactionCategory[]): string {
|
||||
export function getFirstAvailableCategoryId(categories?: TransactionCategory[]): string {
|
||||
if (!categories || !categories.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
+11
-15
@@ -431,8 +431,8 @@ export function countSplitItems(str: string | undefined | null, separator: strin
|
||||
const items = str.split(separator);
|
||||
let count = 0;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i]) {
|
||||
for (const item of items) {
|
||||
if (item) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -483,9 +483,13 @@ export function selectInvert(filterItemIds: Record<string, boolean>, allItemsMap
|
||||
}
|
||||
|
||||
export function isPrimaryItemHasSecondaryValue(primaryItem: Record<string, Record<string, unknown>[]>, primarySubItemsField: string, secondaryValueField: string | undefined, secondaryHiddenField: string | undefined, secondaryValue: unknown): boolean {
|
||||
for (let i = 0; i < primaryItem[primarySubItemsField].length; i++) {
|
||||
const secondaryItem = primaryItem[primarySubItemsField][i];
|
||||
const secondaryItems = primaryItem[primarySubItemsField];
|
||||
|
||||
if (!secondaryItems || secondaryItems.length < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const secondaryItem of secondaryItems) {
|
||||
if (secondaryHiddenField && secondaryItem[secondaryHiddenField]) {
|
||||
continue;
|
||||
}
|
||||
@@ -500,14 +504,12 @@ export function isPrimaryItemHasSecondaryValue(primaryItem: Record<string, Recor
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getPrimaryValueBySecondaryValue<T>(items: Record<string, Record<string, T>[]>[] | Record<string, Record<string, Record<string, T>[]>>, primarySubItemsField: string | undefined, primaryValueField: string | undefined, primaryHiddenField: string | undefined, secondaryValueField: string | undefined, secondaryHiddenField: string | undefined, secondaryValue: T): Record<string, T>[] | Record<string, Record<string, T>[]> | null {
|
||||
export function getPrimaryValueBySecondaryValue<T>(items: Record<string, Record<string, T>[]>[] | Record<string, Record<string, Record<string, T>[]>>, primarySubItemsField: string | undefined, primaryValueField: string | undefined, primaryHiddenField: string | undefined, secondaryValueField: string | undefined, secondaryHiddenField: string | undefined, secondaryValue: T): Record<string, T>[] | Record<string, Record<string, T>[]> | null | undefined {
|
||||
if (primarySubItemsField) {
|
||||
if (isArray(items)) {
|
||||
const arr = items as Record<string, Record<string, T>[]>[];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const primaryItem = arr[i];
|
||||
|
||||
for (const primaryItem of arr) {
|
||||
if (primaryHiddenField && primaryItem[primaryHiddenField]) {
|
||||
continue;
|
||||
}
|
||||
@@ -523,13 +525,7 @@ export function getPrimaryValueBySecondaryValue<T>(items: Record<string, Record<
|
||||
} else {
|
||||
const obj = items as Record<string, Record<string, Record<string, T>[]>>;
|
||||
|
||||
for (const field in obj) {
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, field)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const primaryItem = obj[field];
|
||||
|
||||
for (const primaryItem of values(obj)) {
|
||||
if (primaryHiddenField && primaryItem[primaryHiddenField]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -224,9 +224,7 @@ export class LeafletMapInstance implements MapInstance {
|
||||
private getFinalUrlFormat(urlFormat: string, urlExtraParams: LeafletTileSourceExtraParam[], options: MapInstanceInitOptions) {
|
||||
const params: string[] = [];
|
||||
|
||||
for (let i = 0; i < urlExtraParams.length; i++) {
|
||||
const param = urlExtraParams[i];
|
||||
|
||||
for (const param of urlExtraParams) {
|
||||
if (param.paramValueType === 'tomtom_key') {
|
||||
params.push(param.paramName + '=' + getTomTomMapAPIKey());
|
||||
} else if (param.paramValueType === 'tianditu_key') {
|
||||
|
||||
@@ -221,7 +221,7 @@ export class Account implements AccountInfoResponse {
|
||||
};
|
||||
}
|
||||
|
||||
public getAccountOrSubAccountId(subAccountId: string): string | null {
|
||||
public getAccountOrSubAccountId(subAccountId?: string): string | null {
|
||||
if (this.type === AccountType.SingleAccount.type) {
|
||||
return this.id;
|
||||
} else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||
@@ -243,7 +243,7 @@ export class Account implements AccountInfoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
public isAccountOrSubAccountHidden(subAccountId: string): boolean {
|
||||
public isAccountOrSubAccountHidden(subAccountId?: string): boolean {
|
||||
if (this.type === AccountType.SingleAccount.type) {
|
||||
return this.hidden;
|
||||
} else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||
@@ -265,7 +265,7 @@ export class Account implements AccountInfoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
public getAccountOrSubAccountComment(subAccountId: string): string | null {
|
||||
public getAccountOrSubAccountComment(subAccountId?: string): string | null {
|
||||
if (this.type === AccountType.SingleAccount.type) {
|
||||
return this.comment;
|
||||
} else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||
@@ -287,7 +287,7 @@ export class Account implements AccountInfoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
public getAccountOrSubAccount(subAccountId: string): Account | null {
|
||||
public getAccountOrSubAccount(subAccountId?: string): Account | null {
|
||||
if (this.type === AccountType.SingleAccount.type) {
|
||||
return this;
|
||||
} else if (this.type === AccountType.MultiSubAccounts.type && !subAccountId) {
|
||||
@@ -309,7 +309,7 @@ export class Account implements AccountInfoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
public getSubAccount(subAccountId: string): Account | null {
|
||||
public getSubAccount(subAccountId?: string): Account | null {
|
||||
if (!this.subAccounts || !this.subAccounts.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -323,7 +323,7 @@ export class Account implements AccountInfoResponse {
|
||||
return null;
|
||||
}
|
||||
|
||||
public getSubAccountCurrencies(showHidden: boolean, subAccountId: string): string[] {
|
||||
public getSubAccountCurrencies(showHidden: boolean, subAccountId?: string): string[] {
|
||||
if (!this.subAccounts || !this.subAccounts.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -140,15 +140,15 @@ export class Transaction implements TransactionInfoResponse {
|
||||
}
|
||||
}
|
||||
|
||||
public setCategory(category: TransactionCategory): void {
|
||||
public setCategory(category?: TransactionCategory): void {
|
||||
this._category = category;
|
||||
}
|
||||
|
||||
public setSourceAccount(sourceAccount: Account): void {
|
||||
public setSourceAccount(sourceAccount?: Account): void {
|
||||
this._sourceAccount = sourceAccount;
|
||||
}
|
||||
|
||||
public setDestinationAccount(destinationAccount: Account): void {
|
||||
public setDestinationAccount(destinationAccount?: Account): void {
|
||||
this._destinationAccount = destinationAccount;
|
||||
}
|
||||
|
||||
|
||||
+132
-180
@@ -5,7 +5,7 @@ import { useSettingsStore } from './setting.ts';
|
||||
import { useUserStore } from './user.ts';
|
||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
import { type BeforeResolveFunction, itemAndIndex, reversed, entries, values } from '@/core/base.ts';
|
||||
import type { HiddenAmount, NumberWithSuffix } from '@/core/numeral.ts';
|
||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||
import { DISPLAY_HIDDEN_AMOUNT, INCOMPLETE_AMOUNT_SUFFIX } from '@/consts/numeral.ts';
|
||||
@@ -36,15 +36,12 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const allPlainAccounts = computed<Account[]>(() => {
|
||||
const allAccountsList: Account[] = [];
|
||||
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
const account = allAccounts.value[i];
|
||||
|
||||
for (const account of allAccounts.value) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
allAccountsList.push(account);
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type) {
|
||||
if (account.subAccounts) {
|
||||
for (let j = 0; j < account.subAccounts.length; j++) {
|
||||
const subAccount = account.subAccounts[j];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
allAccountsList.push(subAccount);
|
||||
}
|
||||
}
|
||||
@@ -57,17 +54,14 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const allMixedPlainAccounts = computed<Account[]>(() => {
|
||||
const allAccountsList: Account[] = [];
|
||||
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
const account = allAccounts.value[i];
|
||||
|
||||
for (const account of allAccounts.value) {
|
||||
if (account.type === AccountType.SingleAccount.type) {
|
||||
allAccountsList.push(account);
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type) {
|
||||
allAccountsList.push(account);
|
||||
|
||||
if (account.subAccounts) {
|
||||
for (let j = 0; j < account.subAccounts.length; j++) {
|
||||
const subAccount = account.subAccounts[j];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
allAccountsList.push(subAccount);
|
||||
}
|
||||
}
|
||||
@@ -80,9 +74,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const allVisiblePlainAccounts = computed<Account[]>(() => {
|
||||
const allVisibleAccounts: Account[] = [];
|
||||
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
const account = allAccounts.value[i];
|
||||
|
||||
for (const account of allAccounts.value) {
|
||||
if (account.hidden) {
|
||||
continue;
|
||||
}
|
||||
@@ -91,8 +83,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
allVisibleAccounts.push(account);
|
||||
} else if (account.type === AccountType.MultiSubAccounts.type) {
|
||||
if (account.subAccounts) {
|
||||
for (let j = 0; j < account.subAccounts.length; j++) {
|
||||
const subAccount = account.subAccounts[j];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
|
||||
if (subAccount.hidden) {
|
||||
continue;
|
||||
@@ -110,12 +101,8 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const allAvailableAccountsCount = computed<number>(() => {
|
||||
let allAccountCount = 0;
|
||||
|
||||
for (const category in allCategorizedAccountsMap.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allAccountCount += allCategorizedAccountsMap.value[category].accounts.length;
|
||||
for (const categorizedAccounts of values(allCategorizedAccountsMap.value)) {
|
||||
allAccountCount += categorizedAccounts.accounts.length;
|
||||
}
|
||||
|
||||
return allAccountCount;
|
||||
@@ -124,15 +111,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const allVisibleAccountsCount = computed<number>(() => {
|
||||
let shownAccountCount = 0;
|
||||
|
||||
for (const category in allCategorizedAccountsMap.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) {
|
||||
continue;
|
||||
}
|
||||
for (const categorizedAccounts of values(allCategorizedAccountsMap.value)) {
|
||||
const accountList = categorizedAccounts.accounts;
|
||||
|
||||
const accountList = allCategorizedAccountsMap.value[category].accounts;
|
||||
|
||||
for (let i = 0; i < accountList.length; i++) {
|
||||
if (!accountList[i].hidden) {
|
||||
for (const account of accountList) {
|
||||
if (!account.hidden) {
|
||||
shownAccountCount++;
|
||||
}
|
||||
}
|
||||
@@ -145,13 +128,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
allAccounts.value = accounts;
|
||||
allAccountsMap.value = {};
|
||||
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
const account = accounts[i];
|
||||
for (const account of accounts) {
|
||||
allAccountsMap.value[account.id] = account;
|
||||
|
||||
if (account.subAccounts) {
|
||||
for (let j = 0; j < account.subAccounts.length; j++) {
|
||||
const subAccount = account.subAccounts[j];
|
||||
for (const subAccount of account.subAccounts) {
|
||||
allAccountsMap.value[subAccount.id] = subAccount;
|
||||
}
|
||||
}
|
||||
@@ -160,51 +141,49 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
allCategorizedAccountsMap.value = getCategorizedAccountsMap(accounts);
|
||||
}
|
||||
|
||||
function addAccountToAccountList(account: Account): void {
|
||||
const newAccountCategory = AccountCategory.valueOf(account.category);
|
||||
function addAccountToAccountList(currentAccount: Account): void {
|
||||
const newAccountCategory = AccountCategory.valueOf(currentAccount.category);
|
||||
let insertIndexToAllList = allAccounts.value.length;
|
||||
|
||||
if (newAccountCategory) {
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
const accountCategory = AccountCategory.valueOf(allAccounts.value[i].category);
|
||||
for (const [account, index] of itemAndIndex(allAccounts.value)) {
|
||||
const accountCategory = AccountCategory.valueOf(account.category);
|
||||
|
||||
if (accountCategory && accountCategory.displayOrder > newAccountCategory.displayOrder) {
|
||||
insertIndexToAllList = i;
|
||||
insertIndexToAllList = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allAccounts.value.splice(insertIndexToAllList, 0, account);
|
||||
allAccounts.value.splice(insertIndexToAllList, 0, currentAccount);
|
||||
|
||||
allAccountsMap.value[account.id] = account;
|
||||
allAccountsMap.value[currentAccount.id] = currentAccount;
|
||||
|
||||
if (account.subAccounts) {
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
if (currentAccount.subAccounts) {
|
||||
for (const subAccount of currentAccount.subAccounts) {
|
||||
allAccountsMap.value[subAccount.id] = subAccount;
|
||||
}
|
||||
}
|
||||
|
||||
if (allCategorizedAccountsMap.value[account.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[account.category].accounts;
|
||||
accountList.push(account);
|
||||
if (allCategorizedAccountsMap.value[currentAccount.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[currentAccount.category]!.accounts;
|
||||
accountList.push(currentAccount);
|
||||
} else {
|
||||
allCategorizedAccountsMap.value = getCategorizedAccountsMap(allAccounts.value);
|
||||
}
|
||||
}
|
||||
|
||||
function updateAccountToAccountList(oldAccount: Account, newAccount: Account): void {
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
if (allAccounts.value[i].id === newAccount.id) {
|
||||
allAccounts.value.splice(i, 1, newAccount);
|
||||
for (const [account, index] of itemAndIndex(allAccounts.value)) {
|
||||
if (account.id === newAccount.id) {
|
||||
allAccounts.value.splice(index, 1, newAccount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldAccount.subAccounts) {
|
||||
for (let i = 0; i < oldAccount.subAccounts.length; i++) {
|
||||
const subAccount = oldAccount.subAccounts[i];
|
||||
for (const subAccount of oldAccount.subAccounts) {
|
||||
if (allAccountsMap.value[subAccount.id]) {
|
||||
delete allAccountsMap.value[subAccount.id];
|
||||
}
|
||||
@@ -214,18 +193,17 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
allAccountsMap.value[newAccount.id] = newAccount;
|
||||
|
||||
if (newAccount.subAccounts) {
|
||||
for (let i = 0; i < newAccount.subAccounts.length; i++) {
|
||||
const subAccount = newAccount.subAccounts[i];
|
||||
for (const subAccount of newAccount.subAccounts) {
|
||||
allAccountsMap.value[subAccount.id] = subAccount;
|
||||
}
|
||||
}
|
||||
|
||||
if (allCategorizedAccountsMap.value[newAccount.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[newAccount.category].accounts;
|
||||
const accountList = allCategorizedAccountsMap.value[newAccount.category]!.accounts;
|
||||
|
||||
for (let i = 0; i < accountList.length; i++) {
|
||||
if (accountList[i].id === newAccount.id) {
|
||||
accountList.splice(i, 1, newAccount);
|
||||
for (const [account, index] of itemAndIndex(accountList)) {
|
||||
if (account.id === newAccount.id) {
|
||||
accountList.splice(index, 1, newAccount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -237,12 +215,12 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
let toAccount = null;
|
||||
|
||||
if (allCategorizedAccountsMap.value[account.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[account.category].accounts;
|
||||
const accountList = allCategorizedAccountsMap.value[account.category]!.accounts;
|
||||
|
||||
if (updateListOrder) {
|
||||
fromAccount = accountList[from];
|
||||
toAccount = accountList[to];
|
||||
accountList.splice(to, 0, accountList.splice(from, 1)[0]);
|
||||
accountList.splice(to, 0, accountList.splice(from, 1)[0] as Account);
|
||||
} else {
|
||||
fromAccount = accountList[to];
|
||||
|
||||
@@ -258,94 +236,93 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
let globalFromIndex = -1;
|
||||
let globalToIndex = -1;
|
||||
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
if (allAccounts.value[i].id === fromAccount.id) {
|
||||
globalFromIndex = i;
|
||||
} else if (allAccounts.value[i].id === toAccount.id) {
|
||||
globalToIndex = i;
|
||||
for (const [account, index] of itemAndIndex(allAccounts.value)) {
|
||||
if (account.id === fromAccount.id) {
|
||||
globalFromIndex = index;
|
||||
} else if (account.id === toAccount.id) {
|
||||
globalToIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (globalFromIndex >= 0 && globalToIndex >= 0) {
|
||||
allAccounts.value.splice(globalToIndex, 0, allAccounts.value.splice(globalFromIndex, 1)[0]);
|
||||
allAccounts.value.splice(globalToIndex, 0, allAccounts.value.splice(globalFromIndex, 1)[0] as Account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateAccountVisibilityInAccountList({ account, hidden }: { account: Account, hidden: boolean }): void {
|
||||
if (allAccountsMap.value[account.id]) {
|
||||
allAccountsMap.value[account.id].visible = !hidden;
|
||||
allAccountsMap.value[account.id]!.visible = !hidden;
|
||||
}
|
||||
}
|
||||
|
||||
function removeAccountFromAccountList(account: Account): void {
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
if (allAccounts.value[i].id === account.id) {
|
||||
allAccounts.value.splice(i, 1);
|
||||
function removeAccountFromAccountList(currentAccount: Account): void {
|
||||
for (const [account, index] of itemAndIndex(allAccounts.value)) {
|
||||
if (account.id === currentAccount.id) {
|
||||
allAccounts.value.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allAccountsMap.value[account.id] && allAccountsMap.value[account.id].subAccounts) {
|
||||
const subAccounts = allAccountsMap.value[account.id].subAccounts as Account[];
|
||||
if (allAccountsMap.value[currentAccount.id] && allAccountsMap.value[currentAccount.id]!.subAccounts) {
|
||||
const subAccounts = allAccountsMap.value[currentAccount.id]!.subAccounts as Account[];
|
||||
|
||||
for (let i = 0; i < subAccounts.length; i++) {
|
||||
const subAccount = subAccounts[i];
|
||||
for (const subAccount of subAccounts) {
|
||||
if (allAccountsMap.value[subAccount.id]) {
|
||||
delete allAccountsMap.value[subAccount.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allAccountsMap.value[account.id]) {
|
||||
delete allAccountsMap.value[account.id];
|
||||
if (allAccountsMap.value[currentAccount.id]) {
|
||||
delete allAccountsMap.value[currentAccount.id];
|
||||
}
|
||||
|
||||
if (allCategorizedAccountsMap.value[account.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[account.category].accounts;
|
||||
if (allCategorizedAccountsMap.value[currentAccount.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[currentAccount.category]!.accounts;
|
||||
|
||||
for (let i = 0; i < accountList.length; i++) {
|
||||
if (accountList[i].id === account.id) {
|
||||
accountList.splice(i, 1);
|
||||
for (const [account, index] of itemAndIndex(accountList)) {
|
||||
if (account.id === currentAccount.id) {
|
||||
accountList.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeSubAccountFromAccountList(subAccount: Account): void {
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
if (allAccounts.value[i].type !== AccountType.MultiSubAccounts.type || !allAccounts.value[i].subAccounts) {
|
||||
function removeSubAccountFromAccountList(currentSubAccount: Account): void {
|
||||
for (const account of allAccounts.value) {
|
||||
if (account.type !== AccountType.MultiSubAccounts.type || !account.subAccounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const subAccounts = allAccounts.value[i].subAccounts as Account[];
|
||||
const subAccounts = account.subAccounts as Account[];
|
||||
|
||||
for (let j = 0; j < subAccounts.length; j++) {
|
||||
if (subAccounts[j].id === subAccount.id) {
|
||||
subAccounts.splice(j, 1);
|
||||
for (const [subAccount, index] of itemAndIndex(subAccounts)) {
|
||||
if (subAccount.id === currentSubAccount.id) {
|
||||
subAccounts.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allAccountsMap.value[subAccount.id]) {
|
||||
delete allAccountsMap.value[subAccount.id];
|
||||
if (allAccountsMap.value[currentSubAccount.id]) {
|
||||
delete allAccountsMap.value[currentSubAccount.id];
|
||||
}
|
||||
|
||||
if (allCategorizedAccountsMap.value[subAccount.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[subAccount.category].accounts;
|
||||
if (allCategorizedAccountsMap.value[currentSubAccount.category]) {
|
||||
const accountList = allCategorizedAccountsMap.value[currentSubAccount.category]!.accounts;
|
||||
|
||||
for (let i = 0; i < accountList.length; i++) {
|
||||
if (accountList[i].type !== AccountType.MultiSubAccounts.type || !accountList[i].subAccounts) {
|
||||
for (const account of accountList) {
|
||||
if (account.type !== AccountType.MultiSubAccounts.type || !account.subAccounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const subAccounts = accountList[i].subAccounts as Account[];
|
||||
const subAccounts = account.subAccounts as Account[];
|
||||
|
||||
for (let j = 0; j < subAccounts.length; j++) {
|
||||
if (subAccounts[j].id === subAccount.id) {
|
||||
subAccounts.splice(j, 1);
|
||||
for (const [subAccount, index] of itemAndIndex(subAccounts)) {
|
||||
if (subAccount.id === currentSubAccount.id) {
|
||||
subAccounts.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -370,24 +347,16 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
subAccounts: {}
|
||||
};
|
||||
|
||||
for (const category in allCategorizedAccountsMap.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) {
|
||||
for (const [category, categorizedAccounts] of entries(allCategorizedAccountsMap.value)) {
|
||||
if (!categorizedAccounts || !categorizedAccounts.accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!allCategorizedAccountsMap.value[category] || !allCategorizedAccountsMap.value[category].accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accounts = allCategorizedAccountsMap.value[category].accounts;
|
||||
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
const account = accounts[i];
|
||||
const accounts = categorizedAccounts.accounts;
|
||||
|
||||
for (const account of accounts) {
|
||||
if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
|
||||
for (let j = 0; j < account.subAccounts.length; j++) {
|
||||
const subAccount = account.subAccounts[j];
|
||||
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (showHidden || !subAccount.hidden) {
|
||||
ret.subAccounts[account.id] = subAccount.id;
|
||||
break;
|
||||
@@ -396,7 +365,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
}
|
||||
|
||||
if (showHidden || !account.hidden) {
|
||||
ret.accounts[category] = account.id;
|
||||
ret.accounts[parseInt(category)] = account.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -411,24 +380,16 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
subAccounts: {}
|
||||
};
|
||||
|
||||
for (const category in allCategorizedAccountsMap.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) {
|
||||
for (const [category, categorizedAccounts] of entries(allCategorizedAccountsMap.value)) {
|
||||
if (!categorizedAccounts || !categorizedAccounts.accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!allCategorizedAccountsMap.value[category] || !allCategorizedAccountsMap.value[category].accounts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accounts = allCategorizedAccountsMap.value[category].accounts;
|
||||
|
||||
for (let i = accounts.length - 1; i >= 0; i--) {
|
||||
const account = accounts[i];
|
||||
const accounts = categorizedAccounts.accounts;
|
||||
|
||||
for (const account of reversed(accounts)) {
|
||||
if (account.type === AccountType.MultiSubAccounts.type && account.subAccounts) {
|
||||
for (let j = account.subAccounts.length - 1; j >= 0; j--) {
|
||||
const subAccount = account.subAccounts[j];
|
||||
|
||||
for (const subAccount of reversed(account.subAccounts)) {
|
||||
if (showHidden || !subAccount.hidden) {
|
||||
ret.subAccounts[account.id] = subAccount.id;
|
||||
break;
|
||||
@@ -437,7 +398,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
}
|
||||
|
||||
if (showHidden || !account.hidden) {
|
||||
ret.accounts[category] = account.id;
|
||||
ret.accounts[parseInt(category)] = account.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -454,9 +415,8 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const accountIds = accountId.split(',');
|
||||
let mainAccount = null;
|
||||
|
||||
for (let i = 0; i < accountIds.length; i++) {
|
||||
const id = accountIds[i];
|
||||
let account = allAccountsMap.value[id];
|
||||
for (const accountId of accountIds) {
|
||||
let account = allAccountsMap.value[accountId];
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
@@ -466,7 +426,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
account = allAccountsMap.value[account.parentId];
|
||||
}
|
||||
|
||||
if (mainAccount !== null) {
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mainAccount) {
|
||||
if (mainAccount.id !== account.id) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -499,11 +463,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
let netAssets = 0;
|
||||
let hasUnCalculatedAmount = false;
|
||||
|
||||
for (let i = 0; i < accountsBalance.length; i++) {
|
||||
if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) {
|
||||
netAssets += accountsBalance[i].balance;
|
||||
for (const accountBalance of accountsBalance) {
|
||||
if (accountBalance.currency === userStore.currentUserDefaultCurrency) {
|
||||
netAssets += accountBalance.balance;
|
||||
} else {
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency);
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency);
|
||||
|
||||
if (!isNumber(balance)) {
|
||||
hasUnCalculatedAmount = true;
|
||||
@@ -535,11 +499,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
let totalAssets = 0;
|
||||
let hasUnCalculatedAmount = false;
|
||||
|
||||
for (let i = 0; i < accountsBalance.length; i++) {
|
||||
if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) {
|
||||
totalAssets += accountsBalance[i].balance;
|
||||
for (const accountBalance of accountsBalance) {
|
||||
if (accountBalance.currency === userStore.currentUserDefaultCurrency) {
|
||||
totalAssets += accountBalance.balance;
|
||||
} else {
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency);
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency);
|
||||
|
||||
if (!isNumber(balance)) {
|
||||
hasUnCalculatedAmount = true;
|
||||
@@ -571,11 +535,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
let totalLiabilities = 0;
|
||||
let hasUnCalculatedAmount = false;
|
||||
|
||||
for (let i = 0; i < accountsBalance.length; i++) {
|
||||
if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) {
|
||||
totalLiabilities -= accountsBalance[i].balance;
|
||||
for (const accountBalance of accountsBalance) {
|
||||
if (accountBalance.currency === userStore.currentUserDefaultCurrency) {
|
||||
totalLiabilities -= accountBalance.balance;
|
||||
} else {
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency);
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency);
|
||||
|
||||
if (!isNumber(balance)) {
|
||||
hasUnCalculatedAmount = true;
|
||||
@@ -605,26 +569,26 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
let totalBalance = 0;
|
||||
let hasUnCalculatedAmount = false;
|
||||
|
||||
for (let i = 0; i < accountsBalance.length; i++) {
|
||||
if (accountsBalance[i].currency === userStore.currentUserDefaultCurrency) {
|
||||
if (accountsBalance[i].isAsset) {
|
||||
totalBalance += accountsBalance[i].balance;
|
||||
} else if (accountsBalance[i].isLiability) {
|
||||
totalBalance -= accountsBalance[i].balance;
|
||||
for (const accountBalance of accountsBalance) {
|
||||
if (accountBalance.currency === userStore.currentUserDefaultCurrency) {
|
||||
if (accountBalance.isAsset) {
|
||||
totalBalance += accountBalance.balance;
|
||||
} else if (accountBalance.isLiability) {
|
||||
totalBalance -= accountBalance.balance;
|
||||
} else {
|
||||
totalBalance += accountsBalance[i].balance;
|
||||
totalBalance += accountBalance.balance;
|
||||
}
|
||||
} else {
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountsBalance[i].balance, accountsBalance[i].currency, userStore.currentUserDefaultCurrency);
|
||||
const balance = exchangeRatesStore.getExchangedAmount(accountBalance.balance, accountBalance.currency, userStore.currentUserDefaultCurrency);
|
||||
|
||||
if (!isNumber(balance)) {
|
||||
hasUnCalculatedAmount = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (accountsBalance[i].isAsset) {
|
||||
if (accountBalance.isAsset) {
|
||||
totalBalance += Math.trunc(balance);
|
||||
} else if (accountsBalance[i].isLiability) {
|
||||
} else if (accountBalance.isLiability) {
|
||||
totalBalance -= Math.trunc(balance);
|
||||
} else {
|
||||
totalBalance += Math.trunc(balance);
|
||||
@@ -678,9 +642,7 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
const allSubAccountCurrencies: string[] = [];
|
||||
let totalBalance = 0;
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (!showHidden && subAccount.hidden) {
|
||||
continue;
|
||||
}
|
||||
@@ -699,14 +661,12 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
}
|
||||
|
||||
if (allSubAccountCurrencies.length === 1) {
|
||||
resultCurrency = allSubAccountCurrencies[0];
|
||||
resultCurrency = allSubAccountCurrencies[0] as string;
|
||||
}
|
||||
|
||||
let hasUnCalculatedAmount = false;
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (!showHidden && subAccount.hidden) {
|
||||
continue;
|
||||
}
|
||||
@@ -762,17 +722,15 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
}
|
||||
|
||||
function hasAccount(accountCategory: AccountCategory, visibleOnly: boolean): boolean {
|
||||
if (!allCategorizedAccountsMap.value[accountCategory.type] ||
|
||||
!allCategorizedAccountsMap.value[accountCategory.type].accounts ||
|
||||
!allCategorizedAccountsMap.value[accountCategory.type].accounts.length) {
|
||||
const categorizedAccounts = allCategorizedAccountsMap.value[accountCategory.type];
|
||||
|
||||
if (!categorizedAccounts || !categorizedAccounts.accounts || !categorizedAccounts.accounts.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let shownCount = 0;
|
||||
|
||||
for (let i = 0; i < allCategorizedAccountsMap.value[accountCategory.type].accounts.length; i++) {
|
||||
const account = allCategorizedAccountsMap.value[accountCategory.type].accounts[i];
|
||||
|
||||
for (const account of categorizedAccounts.accounts) {
|
||||
if (!visibleOnly || !account.hidden) {
|
||||
shownCount++;
|
||||
}
|
||||
@@ -786,8 +744,8 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
if (showHidden || !account.subAccounts[i].hidden) {
|
||||
for (const subAccount of account.subAccounts) {
|
||||
if (showHidden || !subAccount.hidden) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -934,8 +892,8 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!account ||
|
||||
!allCategorizedAccountsMap.value[account.category] ||
|
||||
!allCategorizedAccountsMap.value[account.category].accounts ||
|
||||
!allCategorizedAccountsMap.value[account.category].accounts[to]) {
|
||||
!allCategorizedAccountsMap.value[account.category]!.accounts ||
|
||||
!allCategorizedAccountsMap.value[account.category]!.accounts[to]) {
|
||||
reject({ message: 'Unable to move account' });
|
||||
return;
|
||||
}
|
||||
@@ -953,17 +911,11 @@ export const useAccountsStore = defineStore('accounts', () => {
|
||||
function updateAccountDisplayOrders(): Promise<boolean> {
|
||||
const newDisplayOrders: AccountNewDisplayOrderRequest[] = [];
|
||||
|
||||
for (const category in allCategorizedAccountsMap.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCategorizedAccountsMap.value, category)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const accountList = allCategorizedAccountsMap.value[category].accounts;
|
||||
|
||||
for (let i = 0; i < accountList.length; i++) {
|
||||
for (const categorizedAccounts of values(allCategorizedAccountsMap.value)) {
|
||||
for (const [account, index] of itemAndIndex(categorizedAccounts.accounts)) {
|
||||
newDisplayOrders.push({
|
||||
id: accountList[i].id,
|
||||
displayOrder: i + 1
|
||||
id: account.id,
|
||||
displayOrder: index + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useAccountsStore } from './account.ts';
|
||||
import { useTransactionCategoriesStore } from './transactionCategory.ts';
|
||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||
|
||||
import { entries, values } from '@/core/base.ts';
|
||||
import { type TextualYearMonth, type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
@@ -228,9 +229,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
let totalAmount = 0;
|
||||
let totalNonNegativeAmount = 0;
|
||||
|
||||
for (let i = 0; i < accountsStore.allPlainAccounts.length; i++) {
|
||||
const account = accountsStore.allPlainAccounts[i];
|
||||
|
||||
for (const account of accountsStore.allPlainAccounts) {
|
||||
if (transactionStatisticsFilter.value.chartDataType === ChartDataType.AccountTotalAssets.type) {
|
||||
if (!account.isAsset) {
|
||||
continue;
|
||||
@@ -312,12 +311,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
const allStatisticsItems: TransactionCategoricalAnalysisDataItem[] = [];
|
||||
|
||||
if (combinedData && combinedData.items) {
|
||||
for (const id in combinedData.items) {
|
||||
if (!Object.prototype.hasOwnProperty.call(combinedData.items, id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dataItem = combinedData.items[id];
|
||||
for (const dataItem of values(combinedData.items)) {
|
||||
let percent = 0;
|
||||
|
||||
if (dataItem.totalAmount > 0) {
|
||||
@@ -361,8 +355,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
const finalTrendsData: TransactionStatisticTrendsResponseItemWithInfo[] = [];
|
||||
|
||||
if (trendsData && trendsData.length) {
|
||||
for (let i = 0; i < trendsData.length; i++) {
|
||||
const trendItem = trendsData[i];
|
||||
for (const trendItem of trendsData) {
|
||||
const finalTrendItem: TransactionStatisticTrendsResponseItemWithInfo = {
|
||||
year: trendItem.year,
|
||||
month: trendItem.month,
|
||||
@@ -387,16 +380,10 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
|
||||
const combinedDataMap: Record<string, WritableTransactionTrendsAnalysisDataItem> = {};
|
||||
|
||||
for (let i = 0; i < transactionCategoryTrendsDataWithCategoryAndAccountInfo.value.length; i++) {
|
||||
const trendItem = transactionCategoryTrendsDataWithCategoryAndAccountInfo.value[i];
|
||||
for (const trendItem of transactionCategoryTrendsDataWithCategoryAndAccountInfo.value) {
|
||||
const totalAmountItems = getCategoryTotalAmountItems(trendItem.items, transactionStatisticsFilter.value);
|
||||
|
||||
for (const id in totalAmountItems.items) {
|
||||
if (!Object.prototype.hasOwnProperty.call(totalAmountItems.items, id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const item = totalAmountItems.items[id];
|
||||
for (const [id, item] of entries(totalAmountItems.items)) {
|
||||
let combinedData = combinedDataMap[id];
|
||||
|
||||
if (!combinedData) {
|
||||
@@ -426,12 +413,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
|
||||
const totalAmountsTrends: TransactionTrendsAnalysisDataItem[] = [];
|
||||
|
||||
for (const id in combinedDataMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(combinedDataMap, id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const trendData = combinedDataMap[id];
|
||||
for (const trendData of values(combinedDataMap)) {
|
||||
totalAmountsTrends.push(trendData);
|
||||
}
|
||||
|
||||
@@ -448,8 +430,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
const finalItems: TransactionStatisticResponseItemWithInfo[] = [];
|
||||
const defaultCurrency = userStore.currentUserDefaultCurrency;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const dataItem = items[i];
|
||||
for (const dataItem of items) {
|
||||
const item: TransactionStatisticResponseItemWithInfo = {
|
||||
categoryId: dataItem.categoryId,
|
||||
accountId: dataItem.accountId,
|
||||
@@ -500,9 +481,7 @@ export const useStatisticsStore = defineStore('statistics', () => {
|
||||
let totalAmount = 0;
|
||||
let totalNonNegativeAmount = 0;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
|
||||
for (const item of items) {
|
||||
if (!item.primaryAccount || !item.account || !item.primaryCategory || !item.category) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+42
-58
@@ -9,7 +9,7 @@ import { useOverviewStore } from './overview.ts';
|
||||
import { useStatisticsStore } from './statistics.ts';
|
||||
import { useExchangeRatesStore } from './exchangeRates.ts';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
import { type BeforeResolveFunction, itemAndIndex, entries, keys } from '@/core/base.ts';
|
||||
import { type TextualYearMonth, DateRange } from '@/core/datetime.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import { TransactionType, TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
@@ -165,8 +165,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
let currentMonthListIndex = -1;
|
||||
let currentMonthList: TransactionMonthList | null = null;
|
||||
|
||||
for (let i = 0; i < transactionPageWrapper.items.length; i++) {
|
||||
const item = transactionPageWrapper.items[i];
|
||||
for (const [item, index] of itemAndIndex(transactionPageWrapper.items)) {
|
||||
fillTransactionObject(item, currentUtcOffset);
|
||||
|
||||
const transactionTime = parseDateTimeFromUnixTime(item.time, item.utcOffset, currentUtcOffset);
|
||||
@@ -174,8 +173,8 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
const transactionMonth = transactionTime.getGregorianCalendarMonth();
|
||||
const transactionYearDashMonth = transactionTime.getGregorianCalendarYearDashMonth();
|
||||
|
||||
if (i === 0 && transactions.value.length > 0) {
|
||||
const lastMonthList = transactions.value[transactions.value.length - 1];
|
||||
if (index === 0 && transactions.value.length > 0) {
|
||||
const lastMonthList = transactions.value[transactions.value.length - 1] as TransactionMonthList;
|
||||
|
||||
if (lastMonthList.totalAmount.incompleteExpense || lastMonthList.totalAmount.incompleteIncome) {
|
||||
// calculate the total amount of last month which has incomplete total amount before starting to process a new request
|
||||
@@ -186,7 +185,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
if (currentMonthList && currentMonthList.year === transactionYear && currentMonthList.month === transactionMonth) {
|
||||
currentMonthList.items.push(Object.freeze(item));
|
||||
|
||||
if (i === transactionPageWrapper.items.length - 1) {
|
||||
if (index === transactionPageWrapper.items.length - 1) {
|
||||
// calculate the total amount of current month when processing the last transaction item of this request
|
||||
calculateMonthTotalAmount(currentMonthList, defaultCurrency, transactionsFilter.value.accountIds, true);
|
||||
}
|
||||
@@ -194,9 +193,9 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
}
|
||||
|
||||
for (let j = currentMonthListIndex + 1; j < transactions.value.length; j++) {
|
||||
if (transactions.value[j].year === transactionYear && transactions.value[j].month === transactionMonth) {
|
||||
if (transactions.value[j]!.year === transactionYear && transactions.value[j]!.month === transactionMonth) {
|
||||
currentMonthListIndex = j;
|
||||
currentMonthList = transactions.value[j];
|
||||
currentMonthList = transactions.value[j] as TransactionMonthList;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -223,7 +222,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
transactions.value.push(monthList);
|
||||
|
||||
currentMonthListIndex = transactions.value.length - 1;
|
||||
currentMonthList = transactions.value[transactions.value.length - 1];
|
||||
currentMonthList = transactions.value[transactions.value.length - 1] as TransactionMonthList;
|
||||
}
|
||||
|
||||
currentMonthList.items.push(Object.freeze(item));
|
||||
@@ -235,50 +234,48 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
if (nextTimeSequenceId) {
|
||||
transactionsNextTimeId.value = nextTimeSequenceId;
|
||||
} else {
|
||||
calculateMonthTotalAmount(transactions.value[transactions.value.length - 1], defaultCurrency, transactionsFilter.value.accountIds, false);
|
||||
calculateMonthTotalAmount(transactions.value[transactions.value.length - 1] as TransactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, false);
|
||||
transactionsNextTimeId.value = -1;
|
||||
}
|
||||
}
|
||||
|
||||
function updateTransactionInTransactionList({ transaction, defaultCurrency }: { transaction: Transaction, defaultCurrency: string }): void {
|
||||
function updateTransactionInTransactionList({ currentTransaction, defaultCurrency }: { currentTransaction: Transaction, defaultCurrency: string }): void {
|
||||
const currentUtcOffset = getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone);
|
||||
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentUtcOffset);
|
||||
const transactionTime = parseDateTimeFromUnixTime(currentTransaction.time, currentTransaction.utcOffset, currentUtcOffset);
|
||||
const transactionYear = transactionTime.getGregorianCalendarYear();
|
||||
const transactionMonth = transactionTime.getGregorianCalendarMonth();
|
||||
|
||||
for (let i = 0; i < transactions.value.length; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
|
||||
for (const [transactionMonthList, monthIndex] of itemAndIndex(transactions.value)) {
|
||||
if (!transactionMonthList.items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let j = 0; j < transactionMonthList.items.length; j++) {
|
||||
if (transactionMonthList.items[j].id === transaction.id) {
|
||||
fillTransactionObject(transaction, currentUtcOffset);
|
||||
for (const [transaction, transactionIndex] of itemAndIndex(transactionMonthList.items)) {
|
||||
if (transaction.id === currentTransaction.id) {
|
||||
fillTransactionObject(currentTransaction, currentUtcOffset);
|
||||
|
||||
if (transactionYear !== transactionMonthList.year ||
|
||||
transactionMonth !== transactionMonthList.month ||
|
||||
transaction.gregorianCalendarDayOfMonth !== transactionMonthList.items[j].gregorianCalendarDayOfMonth) {
|
||||
currentTransaction.gregorianCalendarDayOfMonth !== transaction.gregorianCalendarDayOfMonth) {
|
||||
transactionListStateInvalid.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((transactionsFilter.value.categoryIds && !allFilterCategoryIds.value[transaction.categoryId]) ||
|
||||
(transactionsFilter.value.accountIds && !allFilterAccountIds.value[transaction.sourceAccountId] && !allFilterAccountIds.value[transaction.destinationAccountId] &&
|
||||
(!transaction.sourceAccount || !allFilterAccountIds.value[transaction.sourceAccount.parentId]) &&
|
||||
(!transaction.destinationAccount || !allFilterAccountIds.value[transaction.destinationAccount.parentId])
|
||||
if ((transactionsFilter.value.categoryIds && !allFilterCategoryIds.value[currentTransaction.categoryId]) ||
|
||||
(transactionsFilter.value.accountIds && !allFilterAccountIds.value[currentTransaction.sourceAccountId] && !allFilterAccountIds.value[currentTransaction.destinationAccountId] &&
|
||||
(!currentTransaction.sourceAccount || !allFilterAccountIds.value[currentTransaction.sourceAccount.parentId]) &&
|
||||
(!currentTransaction.destinationAccount || !allFilterAccountIds.value[currentTransaction.destinationAccount.parentId])
|
||||
)
|
||||
) {
|
||||
transactionMonthList.items.splice(j, 1);
|
||||
transactionMonthList.items.splice(transactionIndex, 1);
|
||||
} else {
|
||||
transactionMonthList.items.splice(j, 1, transaction);
|
||||
transactionMonthList.items.splice(transactionIndex, 1, currentTransaction);
|
||||
}
|
||||
|
||||
if (transactionMonthList.items.length < 1) {
|
||||
transactions.value.splice(i, 1);
|
||||
transactions.value.splice(monthIndex, 1);
|
||||
} else {
|
||||
calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, i >= transactions.value.length - 1 && transactionsNextTimeId.value > 0);
|
||||
calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, monthIndex >= transactions.value.length - 1 && transactionsNextTimeId.value > 0);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -287,26 +284,24 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function removeTransactionFromTransactionList({ transaction, defaultCurrency }: { transaction: TransactionInfoResponse, defaultCurrency: string }): void {
|
||||
for (let i = 0; i <transactions.value.length; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
|
||||
function removeTransactionFromTransactionList({ currentTransaction, defaultCurrency }: { currentTransaction: TransactionInfoResponse, defaultCurrency: string }): void {
|
||||
for (const [transactionMonthList, monthIndex] of itemAndIndex(transactions.value)) {
|
||||
if (!transactionMonthList.items ||
|
||||
transactionMonthList.items[0].time < transaction.time ||
|
||||
transactionMonthList.items[transactionMonthList.items.length - 1].time > transaction.time) {
|
||||
transactionMonthList.items[0]!.time < currentTransaction.time ||
|
||||
transactionMonthList.items[transactionMonthList.items.length - 1]!.time > currentTransaction.time) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let j = 0; j < transactionMonthList.items.length; j++) {
|
||||
if (transactionMonthList.items[j].id === transaction.id) {
|
||||
transactionMonthList.items.splice(j, 1);
|
||||
for (const [transaction, transactionIndex] of itemAndIndex(transactionMonthList.items)) {
|
||||
if (transaction.id === currentTransaction.id) {
|
||||
transactionMonthList.items.splice(transactionIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (transactionMonthList.items.length < 1) {
|
||||
transactions.value.splice(i, 1);
|
||||
transactions.value.splice(monthIndex, 1);
|
||||
} else {
|
||||
calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, i >= transactions.value.length - 1 && transactionsNextTimeId.value > 0);
|
||||
calculateMonthTotalAmount(transactionMonthList, defaultCurrency, transactionsFilter.value.accountIds, monthIndex >= transactions.value.length - 1 && transactionsNextTimeId.value > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,16 +323,15 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
if (accountIds && accountIds !== '0') {
|
||||
const allAccountIdsArray = accountIds.split(',');
|
||||
|
||||
for (let i = 0; i < allAccountIdsArray.length; i++) {
|
||||
if (allAccountIdsArray[i]) {
|
||||
allAccountIdsMap[allAccountIdsArray[i]] = true;
|
||||
for (const accountId of allAccountIdsArray) {
|
||||
if (accountId) {
|
||||
allAccountIdsMap[accountId] = true;
|
||||
totalAccountIdsCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < transactionMonthList.items.length; i++) {
|
||||
const transaction = transactionMonthList.items[i];
|
||||
for (const transaction of transactionMonthList.items) {
|
||||
const transactionDay = isNumber(transaction.gregorianCalendarDayOfMonth) ? transaction.gregorianCalendarDayOfMonth.toString() : '0';
|
||||
let dailyTotalAmount = dailyTotalAmounts[transactionDay];
|
||||
|
||||
@@ -413,21 +407,11 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
transactionMonthList.totalAmount.income = Math.trunc(totalIncome);
|
||||
transactionMonthList.totalAmount.incompleteIncome = incomplete || hasUnCalculatedTotalIncome;
|
||||
|
||||
for (const day in transactionMonthList.dailyTotalAmounts) {
|
||||
if (!Object.prototype.hasOwnProperty.call(transactionMonthList.dailyTotalAmounts, day)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const day of keys(transactionMonthList.dailyTotalAmounts)) {
|
||||
delete transactionMonthList.dailyTotalAmounts[day];
|
||||
}
|
||||
|
||||
for (const day in dailyTotalAmounts) {
|
||||
if (!Object.prototype.hasOwnProperty.call(dailyTotalAmounts, day)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dailyTotalAmount = dailyTotalAmounts[day];
|
||||
|
||||
for (const [day, dailyTotalAmount] of entries(dailyTotalAmounts)) {
|
||||
transactionMonthList.dailyTotalAmounts[day] = {
|
||||
expense: Math.trunc(dailyTotalAmount.expense),
|
||||
incompleteExpense: incomplete || dailyTotalAmount.incompleteExpense,
|
||||
@@ -1076,7 +1060,7 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
}
|
||||
} else {
|
||||
updateTransactionInTransactionList({
|
||||
transaction: transaction,
|
||||
currentTransaction: transaction,
|
||||
defaultCurrency: defaultCurrency
|
||||
});
|
||||
}
|
||||
@@ -1131,13 +1115,13 @@ export const useTransactionsStore = defineStore('transactions', () => {
|
||||
if (beforeResolve) {
|
||||
beforeResolve(() => {
|
||||
removeTransactionFromTransactionList({
|
||||
transaction: transaction,
|
||||
currentTransaction: transaction,
|
||||
defaultCurrency: defaultCurrency
|
||||
});
|
||||
});
|
||||
} else {
|
||||
removeTransactionFromTransactionList({
|
||||
transaction: transaction,
|
||||
currentTransaction: transaction,
|
||||
defaultCurrency: defaultCurrency
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { defineStore } from 'pinia';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
|
||||
import { itemAndIndex, values } from '@/core/base.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
|
||||
import {
|
||||
@@ -53,23 +54,15 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
allTransactionCategories.value = allCategories;
|
||||
allTransactionCategoriesMap.value = {};
|
||||
|
||||
for (const categoryType in allCategories) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allCategories, categoryType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const categories = allCategories[categoryType];
|
||||
|
||||
for (let i = 0; i < categories.length; i++) {
|
||||
const category = categories[i];
|
||||
for (const categories of values(allCategories)) {
|
||||
for (const category of categories) {
|
||||
allTransactionCategoriesMap.value[category.id] = category;
|
||||
|
||||
if (!category.subCategories) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let j = 0; j < category.subCategories.length; j++) {
|
||||
const subCategory = category.subCategories[j];
|
||||
for (const subCategory of category.subCategories) {
|
||||
allTransactionCategoriesMap.value[subCategory.id] = subCategory;
|
||||
}
|
||||
}
|
||||
@@ -82,7 +75,7 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
if (!category.parentId || category.parentId === '0') {
|
||||
categoryList = allTransactionCategories.value[category.type];
|
||||
} else if (allTransactionCategoriesMap.value[category.parentId]) {
|
||||
categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories;
|
||||
categoryList = allTransactionCategoriesMap.value[category.parentId]!.subCategories;
|
||||
}
|
||||
|
||||
if (categoryList) {
|
||||
@@ -92,33 +85,33 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
allTransactionCategoriesMap.value[category.id] = category;
|
||||
}
|
||||
|
||||
function updateCategoryInTransactionCategoryList(category: TransactionCategory, oldCategory: TransactionCategory): boolean {
|
||||
if (oldCategory && category.parentId !== oldCategory.parentId) {
|
||||
function updateCategoryInTransactionCategoryList(currentCategory: TransactionCategory, oldCategory?: TransactionCategory): boolean {
|
||||
if (oldCategory && currentCategory.parentId !== oldCategory.parentId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let categoryList: TransactionCategory[] | undefined = undefined;
|
||||
|
||||
if (!category.parentId || category.parentId === '0') {
|
||||
categoryList = allTransactionCategories.value[category.type];
|
||||
} else if (allTransactionCategoriesMap.value[category.parentId]) {
|
||||
categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories;
|
||||
if (!currentCategory.parentId || currentCategory.parentId === '0') {
|
||||
categoryList = allTransactionCategories.value[currentCategory.type];
|
||||
} else if (allTransactionCategoriesMap.value[currentCategory.parentId]) {
|
||||
categoryList = allTransactionCategoriesMap.value[currentCategory.parentId]!.subCategories;
|
||||
}
|
||||
|
||||
if (categoryList) {
|
||||
for (let i = 0; i < categoryList.length; i++) {
|
||||
if (categoryList[i].id === category.id) {
|
||||
if (!category.parentId || category.parentId === '0') {
|
||||
category.subCategories = categoryList[i].subCategories;
|
||||
for (const [category, index] of itemAndIndex(categoryList)) {
|
||||
if (category.id === currentCategory.id) {
|
||||
if (!currentCategory.parentId || currentCategory.parentId === '0') {
|
||||
currentCategory.subCategories = category.subCategories;
|
||||
}
|
||||
|
||||
categoryList.splice(i, 1, category);
|
||||
categoryList.splice(index, 1, currentCategory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allTransactionCategoriesMap.value[category.id] = category;
|
||||
allTransactionCategoriesMap.value[currentCategory.id] = currentCategory;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -128,44 +121,43 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
if (!category.parentId || category.parentId === '0') {
|
||||
categoryList = allTransactionCategories.value[category.type];
|
||||
} else if (allTransactionCategoriesMap.value[category.parentId]) {
|
||||
categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories;
|
||||
categoryList = allTransactionCategoriesMap.value[category.parentId]!.subCategories;
|
||||
}
|
||||
|
||||
if (categoryList) {
|
||||
categoryList.splice(to, 0, categoryList.splice(from, 1)[0]);
|
||||
categoryList.splice(to, 0, categoryList.splice(from, 1)[0] as TransactionCategory);
|
||||
}
|
||||
}
|
||||
|
||||
function updateCategoryVisibilityInTransactionCategoryList({ category, hidden }: { category: TransactionCategory, hidden: boolean }): void {
|
||||
if (allTransactionCategoriesMap.value[category.id]) {
|
||||
allTransactionCategoriesMap.value[category.id].visible = !hidden;
|
||||
allTransactionCategoriesMap.value[category.id]!.visible = !hidden;
|
||||
}
|
||||
}
|
||||
|
||||
function removeCategoryFromTransactionCategoryList(category: TransactionCategory): void {
|
||||
function removeCategoryFromTransactionCategoryList(currentCategory: TransactionCategory): void {
|
||||
let categoryList: TransactionCategory[] | undefined = undefined;
|
||||
|
||||
if (!category.parentId || category.parentId === '0') {
|
||||
categoryList = allTransactionCategories.value[category.type];
|
||||
} else if (allTransactionCategoriesMap.value[category.parentId]) {
|
||||
categoryList = allTransactionCategoriesMap.value[category.parentId].subCategories;
|
||||
if (!currentCategory.parentId || currentCategory.parentId === '0') {
|
||||
categoryList = allTransactionCategories.value[currentCategory.type];
|
||||
} else if (allTransactionCategoriesMap.value[currentCategory.parentId]) {
|
||||
categoryList = allTransactionCategoriesMap.value[currentCategory.parentId]!.subCategories;
|
||||
}
|
||||
|
||||
if (categoryList) {
|
||||
for (let i = 0; i < categoryList.length; i++) {
|
||||
if (categoryList[i].id === category.id) {
|
||||
categoryList.splice(i, 1);
|
||||
for (const [category, index] of itemAndIndex(categoryList)) {
|
||||
if (category.id === currentCategory.id) {
|
||||
categoryList.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allTransactionCategoriesMap.value[category.id] && allTransactionCategoriesMap.value[category.id].subCategories) {
|
||||
const subCategoryList = allTransactionCategoriesMap.value[category.id].subCategories;
|
||||
if (allTransactionCategoriesMap.value[currentCategory.id] && allTransactionCategoriesMap.value[currentCategory.id]!.subCategories) {
|
||||
const subCategoryList = allTransactionCategoriesMap.value[currentCategory.id]!.subCategories;
|
||||
|
||||
if (subCategoryList) {
|
||||
for (let i = 0; i < subCategoryList.length; i++) {
|
||||
const subCategory = subCategoryList[i];
|
||||
for (const subCategory of subCategoryList) {
|
||||
if (allTransactionCategoriesMap.value[subCategory.id]) {
|
||||
delete allTransactionCategoriesMap.value[subCategory.id];
|
||||
}
|
||||
@@ -173,8 +165,8 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
}
|
||||
}
|
||||
|
||||
if (allTransactionCategoriesMap.value[category.id]) {
|
||||
delete allTransactionCategoriesMap.value[category.id];
|
||||
if (allTransactionCategoriesMap.value[currentCategory.id]) {
|
||||
delete allTransactionCategoriesMap.value[currentCategory.id];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,12 +395,12 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
|
||||
if (!category.parentId || category.parentId === '0') {
|
||||
if (!allTransactionCategories.value[category.type] ||
|
||||
!allTransactionCategories.value[category.type][to]) {
|
||||
!allTransactionCategories.value[category.type]![to]) {
|
||||
reject({ message: 'Unable to move category' });
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const subCategoryList = allTransactionCategoriesMap.value[category.parentId].subCategories;
|
||||
const subCategoryList = allTransactionCategoriesMap.value[category.parentId]?.subCategories;
|
||||
|
||||
if (!subCategoryList || !subCategoryList[to]) {
|
||||
reject({ message: 'Unable to move category' });
|
||||
@@ -438,10 +430,10 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
|
||||
}
|
||||
|
||||
if (categoryList) {
|
||||
for (let i = 0; i < categoryList.length; i++) {
|
||||
for (const [category, index] of itemAndIndex(categoryList)) {
|
||||
newDisplayOrders.push({
|
||||
id: categoryList[i].id,
|
||||
displayOrder: i + 1
|
||||
id: category.id,
|
||||
displayOrder: index + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ref, computed } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import type { BeforeResolveFunction } from '@/core/base.ts';
|
||||
import { type BeforeResolveFunction, itemAndIndex, entries } from '@/core/base.ts';
|
||||
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
|
||||
@@ -24,23 +24,16 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
const allVisibleTemplates = computed<Record<number, TransactionTemplate[]>>(() => {
|
||||
const allVisibleTemplates: Record<number, TransactionTemplate[]> = {};
|
||||
|
||||
for (const templateType in allTransactionTemplates.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allTransactionTemplates.value, templateType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const allTemplates = allTransactionTemplates.value[templateType];
|
||||
for (const [templateType, allTemplates] of entries(allTransactionTemplates.value)) {
|
||||
const visibleTemplates: TransactionTemplate[] = [];
|
||||
|
||||
for (let i = 0; i < allTemplates.length; i++) {
|
||||
const template = allTemplates[i];
|
||||
|
||||
for (const template of allTemplates) {
|
||||
if (!template.hidden) {
|
||||
visibleTemplates.push(template);
|
||||
}
|
||||
}
|
||||
|
||||
allVisibleTemplates[templateType] = visibleTemplates;
|
||||
allVisibleTemplates[parseInt(templateType)] = visibleTemplates;
|
||||
}
|
||||
|
||||
return allVisibleTemplates;
|
||||
@@ -49,12 +42,8 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
const allAvailableTemplatesCount = computed<Record<number, number>>(() => {
|
||||
const allAvailableTemplateCounts: Record<number, number> = {};
|
||||
|
||||
for (const templateType in allTransactionTemplates.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allTransactionTemplates.value, templateType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allAvailableTemplateCounts[templateType] = allTransactionTemplates.value[templateType].length;
|
||||
for (const [templateType, allTemplates] of entries(allTransactionTemplates.value)) {
|
||||
allAvailableTemplateCounts[parseInt(templateType)] = allTemplates.length;
|
||||
}
|
||||
|
||||
return allAvailableTemplateCounts;
|
||||
@@ -63,12 +52,8 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
const allVisibleTemplatesCount = computed<Record<number, number>>(() => {
|
||||
const allVisibleTemplateCounts: Record<number, number> = {};
|
||||
|
||||
for (const templateType in allVisibleTemplates.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(allVisibleTemplates.value, templateType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
allVisibleTemplateCounts[templateType] = allVisibleTemplates.value[templateType].length;
|
||||
for (const [templateType, allTemplates] of entries(allVisibleTemplates.value)) {
|
||||
allVisibleTemplateCounts[parseInt(templateType)] = allTemplates.length;
|
||||
}
|
||||
|
||||
return allVisibleTemplateCounts;
|
||||
@@ -78,8 +63,7 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
allTransactionTemplates.value[templateType] = templates;
|
||||
allTransactionTemplatesMap.value[templateType] = {};
|
||||
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
const template = templates[i];
|
||||
for (const template of templates) {
|
||||
allTransactionTemplatesMap.value[templateType][template.id] = template;
|
||||
}
|
||||
}
|
||||
@@ -102,9 +86,9 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
const templateMap = allTransactionTemplatesMap.value[templateType];
|
||||
|
||||
if (isArray(templates)) {
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
if (templates[i].id === template.id) {
|
||||
templates.splice(i, 1, template);
|
||||
for (const [template, index] of itemAndIndex(templates)) {
|
||||
if (template.id === template.id) {
|
||||
templates.splice(index, 1, template);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -119,7 +103,7 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
const templates = allTransactionTemplates.value[templateType];
|
||||
|
||||
if (isArray(templates)) {
|
||||
templates.splice(to, 0, templates.splice(from, 1)[0]);
|
||||
templates.splice(to, 0, templates.splice(from, 1)[0] as TransactionTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,27 +112,27 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
|
||||
if (isObject(templateMap)) {
|
||||
if (templateMap[template.id]) {
|
||||
templateMap[template.id].hidden = hidden;
|
||||
templateMap[template.id]!.hidden = hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeTemplateFromTransactionTemplateList(templateType: number, template: TransactionTemplate): void {
|
||||
function removeTemplateFromTransactionTemplateList(templateType: number, currentTemplate: TransactionTemplate): void {
|
||||
const templates = allTransactionTemplates.value[templateType];
|
||||
const templateMap = allTransactionTemplatesMap.value[templateType];
|
||||
|
||||
if (isArray(templates)) {
|
||||
for (let i = 0; i < templates.length; i++) {
|
||||
if (templates[i].id === template.id) {
|
||||
templates.splice(i, 1);
|
||||
for (const [template, index] of itemAndIndex(templates)) {
|
||||
if (template.id === currentTemplate.id) {
|
||||
templates.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isObject(templateMap)) {
|
||||
if (templateMap[template.id]) {
|
||||
delete templateMap[template.id];
|
||||
if (templateMap[currentTemplate.id]) {
|
||||
delete templateMap[currentTemplate.id];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,21 +282,21 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
|
||||
function changeTemplateDisplayOrder({ templateType, templateId, from, to }: { templateType: number, templateId: string, from: number, to: number }): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let template: TransactionTemplate | null = null;
|
||||
let currentTemplate: TransactionTemplate | null = null;
|
||||
|
||||
if (!isArray(allTransactionTemplates.value[templateType])) {
|
||||
reject({ message: 'Unable to move template' });
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < allTransactionTemplates.value[templateType].length; i++) {
|
||||
if (allTransactionTemplates.value[templateType][i].id === templateId) {
|
||||
template = allTransactionTemplates.value[templateType][i];
|
||||
for (const template of allTransactionTemplates.value[templateType]) {
|
||||
if (template.id === templateId) {
|
||||
currentTemplate = template;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!template || !allTransactionTemplates.value[templateType][to]) {
|
||||
if (!currentTemplate || !allTransactionTemplates.value[templateType][to]) {
|
||||
reject({ message: 'Unable to move template' });
|
||||
return;
|
||||
}
|
||||
@@ -331,10 +315,10 @@ export const useTransactionTemplatesStore = defineStore('transactionTemplates',
|
||||
const newDisplayOrders: TransactionTemplateNewDisplayOrderRequest[] = [];
|
||||
|
||||
if (isArray(allTransactionTemplates.value[templateType])) {
|
||||
for (let i = 0; i < allTransactionTemplates.value[templateType].length; i++) {
|
||||
for (const [template, index] of itemAndIndex(allTransactionTemplates.value[templateType])) {
|
||||
newDisplayOrders.push({
|
||||
id: allTransactionTemplates.value[templateType][i].id,
|
||||
displayOrder: i + 1
|
||||
id: template.id,
|
||||
displayOrder: index + 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,8 +175,7 @@ export function useAppCloudSyncBase() {
|
||||
if (settings && settings.length > 0) {
|
||||
settingsStore.setApplicationSettingsFromCloudSettings(settings);
|
||||
|
||||
for (let i = 0; i < settings.length; i++) {
|
||||
const setting = settings[i];
|
||||
for (const setting of settings) {
|
||||
if (setting && setting.settingKey) {
|
||||
enabledApplicationCloudSettings.value[setting.settingKey] = true;
|
||||
}
|
||||
|
||||
@@ -150,8 +150,8 @@
|
||||
handle=".drag-handle"
|
||||
ghost-class="dragging-item"
|
||||
:disabled="activeAccountCategoryVisibleAccountCount <= 1"
|
||||
:list="allCategorizedAccountsMap[activeAccountCategory.type].accounts"
|
||||
v-if="activeAccountCategory && allCategorizedAccountsMap[activeAccountCategory.type] && allCategorizedAccountsMap[activeAccountCategory.type].accounts && allCategorizedAccountsMap[activeAccountCategory.type].accounts.length"
|
||||
:list="allCategorizedAccountsMap[activeAccountCategory.type]!.accounts"
|
||||
v-if="activeAccountCategory && allCategorizedAccountsMap[activeAccountCategory.type] && allCategorizedAccountsMap[activeAccountCategory.type]!.accounts && allCategorizedAccountsMap[activeAccountCategory.type]!.accounts.length"
|
||||
@change="onMove"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
@@ -376,20 +376,24 @@ const activeAccountCategory = computed<AccountCategory | undefined>(() => Accoun
|
||||
const activeAccountCategoryTotalBalance = computed<string>(() => accountCategoryTotalBalance(activeAccountCategory.value));
|
||||
|
||||
const activeAccountCategoryVisibleAccountCount = computed<number>(() => {
|
||||
if (!activeAccountCategory.value || !allCategorizedAccountsMap.value[activeAccountCategory.value.type] || !allCategorizedAccountsMap.value[activeAccountCategory.value.type].accounts) {
|
||||
if (!activeAccountCategory.value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const accounts = allCategorizedAccountsMap.value[activeAccountCategory.value.type].accounts;
|
||||
const categorizedAccounts = allCategorizedAccountsMap.value[activeAccountCategory.value.type];
|
||||
|
||||
if (!categorizedAccounts || !categorizedAccounts.accounts || !categorizedAccounts.accounts.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (showHidden.value) {
|
||||
return accounts.length;
|
||||
return categorizedAccounts.accounts.length;
|
||||
}
|
||||
|
||||
let visibleCount = 0;
|
||||
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
if (!accounts[i].hidden) {
|
||||
for (const account of categorizedAccounts.accounts) {
|
||||
if (!account.hidden) {
|
||||
visibleCount++;
|
||||
}
|
||||
}
|
||||
@@ -407,9 +411,7 @@ function reload(force: boolean): void {
|
||||
displayOrderModified.value = false;
|
||||
|
||||
if (allAccounts.value) {
|
||||
for (let i = 0; i < allAccounts.value.length; i++) {
|
||||
const account = allAccounts.value[i];
|
||||
|
||||
for (const account of allAccounts.value) {
|
||||
if (account.type === AccountType.MultiSubAccounts.type && !activeSubAccount.value[account.id]) {
|
||||
activeSubAccount.value[account.id] = '';
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ import { useAccountEditPageBaseBase } from '@/views/base/accounts/AccountEditPag
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { ALL_ACCOUNT_ICONS } from '@/consts/icon.ts';
|
||||
import { ALL_ACCOUNT_COLORS } from '@/consts/color.ts';
|
||||
@@ -365,11 +366,11 @@ function save(): void {
|
||||
});
|
||||
}
|
||||
|
||||
function removeSubAccount(subAccount: Account): void {
|
||||
function removeSubAccount(currentSubAccount: Account): void {
|
||||
confirmDialog.value?.open('Are you sure you want to remove this sub-account?').then(() => {
|
||||
for (let i = 0; i < subAccounts.value.length; i++) {
|
||||
if (subAccounts.value[i] === subAccount) {
|
||||
subAccounts.value.splice(i, 1);
|
||||
for (const [subAccount, index] of itemAndIndex(subAccounts.value)) {
|
||||
if (subAccount === currentSubAccount) {
|
||||
subAccounts.value.splice(index, 1);
|
||||
|
||||
if (currentAccountIndex.value >= subAccounts.value.length) {
|
||||
currentAccountIndex.value = subAccounts.value.length - 1;
|
||||
|
||||
@@ -162,15 +162,15 @@
|
||||
<template #item.categoryId="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<ItemIcon size="24px" icon-type="category"
|
||||
:icon-id="allCategoriesMap[item.categoryId].icon"
|
||||
:color="allCategoriesMap[item.categoryId].color"
|
||||
:icon-id="allCategoriesMap[item.categoryId]?.icon ?? ''"
|
||||
:color="allCategoriesMap[item.categoryId]?.color ?? ''"
|
||||
v-if="allCategoriesMap[item.categoryId] && allCategoriesMap[item.categoryId]?.color"></ItemIcon>
|
||||
<v-icon size="24" :icon="mdiPencilBoxOutline" v-else-if="!allCategoriesMap[item.categoryId] || !allCategoriesMap[item.categoryId]?.color" />
|
||||
<span class="ms-2" v-if="item.type === TransactionType.ModifyBalance">
|
||||
{{ tt('Modify Balance') }}
|
||||
</span>
|
||||
<span class="ms-2" v-else-if="item.type !== TransactionType.ModifyBalance && allCategoriesMap[item.categoryId]">
|
||||
{{ allCategoriesMap[item.categoryId].name }}
|
||||
{{ allCategoriesMap[item.categoryId]?.name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -181,9 +181,9 @@
|
||||
</template>
|
||||
<template #item.sourceAccountId="{ item }">
|
||||
<div class="d-flex align-center">
|
||||
<span v-if="item.sourceAccountId && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId].name }}</span>
|
||||
<span v-if="item.sourceAccountId && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId]?.name }}</span>
|
||||
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && allAccountsMap[item.destinationAccountId]">{{ allAccountsMap[item.destinationAccountId].name }}</span>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && allAccountsMap[item.destinationAccountId]">{{ allAccountsMap[item.destinationAccountId]?.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #item.accountBalance="{ item }">
|
||||
@@ -388,12 +388,7 @@ const totalPageCount = computed<number>(() => {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
|
||||
for (let i = 0; i < reconciliationStatements.value.transactions.length; i++) {
|
||||
count++;
|
||||
}
|
||||
|
||||
const count = reconciliationStatements.value.transactions.length;
|
||||
return Math.ceil(count / countPerPage.value);
|
||||
});
|
||||
|
||||
@@ -422,9 +417,7 @@ function getTablePageOptions(linesCount?: number): NameNumeralValue[] {
|
||||
|
||||
const availableCountPerPage = [ 5, 10, 15, 20, 25, 30, 50 ];
|
||||
|
||||
for (let i = 0; i < availableCountPerPage.length; i++) {
|
||||
const count = availableCountPerPage[i];
|
||||
|
||||
for (const count of availableCountPerPage) {
|
||||
if (linesCount < count) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ const primaryCategories = computed<TransactionCategory[]>(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategories[activeCategoryType.value];
|
||||
return transactionCategoriesStore.allTransactionCategories[activeCategoryType.value] ?? [];
|
||||
});
|
||||
|
||||
const secondaryCategories = computed<TransactionCategory[]>(() => {
|
||||
@@ -267,7 +267,7 @@ const secondaryCategories = computed<TransactionCategory[]>(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value].subCategories || [];
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value]?.subCategories ?? [];
|
||||
});
|
||||
|
||||
const hasSubCategories = computed<boolean>(() => {
|
||||
|
||||
@@ -78,9 +78,7 @@ const hasAnyData = computed<boolean>(() => {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < props.data.length; i++) {
|
||||
const item = props.data[i];
|
||||
|
||||
for (const item of props.data) {
|
||||
if (item.incomeAmount > 0 || item.incomeAmount < 0 || item.expenseAmount > 0 || item.expenseAmount < 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -99,8 +97,7 @@ const chartOptions = computed<object>(() => {
|
||||
const expenseIncomeAmountColor = getExpenseAndIncomeAmountColor(userStore.currentUserExpenseAmountColor, userStore.currentUserIncomeAmountColor, props.isDarkMode);
|
||||
|
||||
if (props.data) {
|
||||
for (let i = 0; i < props.data.length; i++) {
|
||||
const item = props.data[i];
|
||||
for (const item of props.data) {
|
||||
const monthShortName = formatUnixTimeToGregorianLikeShortMonth(item.monthStartTime);
|
||||
|
||||
monthNames.push(monthShortName);
|
||||
@@ -145,10 +142,9 @@ const chartOptions = computed<object>(() => {
|
||||
let incomeAmount: string | null = null;
|
||||
let expenseAmount: string | null = null;
|
||||
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const param = params[i];
|
||||
for (const param of params) {
|
||||
const dataIndex = param.dataIndex;
|
||||
const data = props.data[dataIndex];
|
||||
const data = props.data[dataIndex] as TransactionMonthlyIncomeAndExpenseData;
|
||||
|
||||
if (param.seriesId === 'seriesIncome') {
|
||||
incomeAmount = getDisplayIncomeAmount(data);
|
||||
@@ -160,7 +156,7 @@ const chartOptions = computed<object>(() => {
|
||||
return `<table>` +
|
||||
`<thead>` +
|
||||
`<tr>` +
|
||||
`<td colspan="2" class="text-start">${params[0].name}</td>` +
|
||||
`<td colspan="2" class="text-start">${params[0]?.name}</td>` +
|
||||
`</tr>` +
|
||||
`</thead>` +
|
||||
`<tbody>` +
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
</v-list-item>
|
||||
|
||||
<v-list-group :key="category.id" v-for="category in categories">
|
||||
<template #activator="{ props }" v-if="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds].parentId === category.id)">
|
||||
<template #activator="{ props }" v-if="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds]!.parentId === category.id)">
|
||||
<v-divider />
|
||||
<v-list-item class="text-sm" density="compact"
|
||||
:class="getCategoryListItemCheckedClass(category, queryAllFilterCategoryIds)"
|
||||
@@ -402,12 +402,12 @@
|
||||
</v-list-item>
|
||||
<template :key="account.id"
|
||||
v-for="account in allAccounts">
|
||||
<v-divider v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId].hidden)) || query.accountIds === account.id" />
|
||||
<v-divider v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId]!.hidden)) || query.accountIds === account.id" />
|
||||
<v-list-item class="text-sm" density="compact"
|
||||
:value="account.id"
|
||||
:class="{ 'list-item-selected': query.accountIds === account.id, 'item-in-multiple-selection': queryAllFilterAccountIdsCount > 1 && queryAllFilterAccountIds[account.id] }"
|
||||
:append-icon="(query.accountIds === account.id ? mdiCheck : undefined)"
|
||||
v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId].hidden)) || query.accountIds === account.id">
|
||||
v-if="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId]!.hidden)) || query.accountIds === account.id">
|
||||
<v-list-item-title class="cursor-pointer"
|
||||
@click="changeAccountFilter(account.id)">
|
||||
<div class="d-flex align-center">
|
||||
@@ -527,7 +527,7 @@
|
||||
:class="{ 'disabled': loading, 'has-bottom-border': idx < transactions.length - 1 }"
|
||||
v-for="(transaction, idx) in transactions">
|
||||
<tr class="transaction-list-row-date no-hover text-sm"
|
||||
v-if="pageType === TransactionListPageType.List.type && (idx === 0 || (idx > 0 && (transaction.gregorianCalendarYearDashMonthDashDay !== transactions[idx - 1].gregorianCalendarYearDashMonthDashDay)))">
|
||||
v-if="pageType === TransactionListPageType.List.type && (idx === 0 || (idx > 0 && (transaction.gregorianCalendarYearDashMonthDashDay !== transactions[idx - 1]!.gregorianCalendarYearDashMonthDashDay)))">
|
||||
<td :colspan="showTagInTransactionListPage ? 6 : 5" class="font-weight-bold">
|
||||
<div class="d-flex align-center">
|
||||
<span>{{ getDisplayLongDate(transaction) }}</span>
|
||||
@@ -579,7 +579,7 @@
|
||||
</td>
|
||||
<td class="transaction-table-column-tags" v-if="showTagInTransactionListPage">
|
||||
<v-chip class="transaction-tag" size="small" :prepend-icon="mdiPound"
|
||||
:text="allTransactionTags[tagId].name"
|
||||
:text="allTransactionTags[tagId]?.name"
|
||||
:key="tagId"
|
||||
v-for="tagId in transaction.tagIds"/>
|
||||
<v-chip class="transaction-tag" size="small"
|
||||
@@ -669,7 +669,11 @@ import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||
import { useDesktopPageStore } from '@/stores/desktopPage.ts';
|
||||
|
||||
import type { NameNumeralValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import {
|
||||
type NameNumeralValue,
|
||||
type TypeAndDisplayName,
|
||||
keys
|
||||
} from '@/core/base.ts';
|
||||
import {
|
||||
type Year0BasedMonth,
|
||||
type LocalizedRecentMonthDateRange,
|
||||
@@ -884,8 +888,7 @@ const allPageCounts = computed<NameNumeralValue[]>(() => {
|
||||
const pageCounts: NameNumeralValue[] = [];
|
||||
const availableCountPerPage: number[] = [ 5, 10, 15, 20, 25, 30, 50 ];
|
||||
|
||||
for (let i = 0; i < availableCountPerPage.length; i++) {
|
||||
const count = availableCountPerPage[i];
|
||||
for (const count of availableCountPerPage) {
|
||||
pageCounts.push({ value: count, name: numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(count.toString()) });
|
||||
}
|
||||
|
||||
@@ -903,11 +906,11 @@ const allTransactionTagFilterTypes = computed<TransactionTemplateWithIcon[]>(()
|
||||
const allTagFilterTypes: TypeAndDisplayName[] = getAllTransactionTagFilterTypes();
|
||||
const allTagFilterTypesWithIcon: TransactionTemplateWithIcon[] = [];
|
||||
|
||||
for (let i = 0; i < allTagFilterTypes.length; i++) {
|
||||
for (const tagFilterType of allTagFilterTypes) {
|
||||
allTagFilterTypesWithIcon.push({
|
||||
type: allTagFilterTypes[i].type,
|
||||
displayName: allTagFilterTypes[i].displayName,
|
||||
icon: tagFilterIconMap[allTagFilterTypes[i].type]
|
||||
type: tagFilterType.type,
|
||||
displayName: tagFilterType.displayName,
|
||||
icon: tagFilterIconMap[tagFilterType.type] ?? ''
|
||||
});
|
||||
}
|
||||
|
||||
@@ -948,9 +951,7 @@ const transactions = computed<Transaction[]>(() => {
|
||||
|
||||
const transactions :Transaction[] = [];
|
||||
|
||||
for (let i = 0; i < transactionData.items.length; i++) {
|
||||
const transaction = transactionData.items[i];
|
||||
|
||||
for (const transaction of transactionData.items) {
|
||||
if (transaction.gregorianCalendarYearDashMonthDashDay === currentCalendarDate.value) {
|
||||
transactions.push(transaction);
|
||||
}
|
||||
@@ -972,7 +973,7 @@ const recentDateRangeIndex = computed<number>({
|
||||
value = 0;
|
||||
}
|
||||
|
||||
changeDateFilter(recentMonthDateRanges.value[value]);
|
||||
changeDateFilter(recentMonthDateRanges.value[value] as LocalizedRecentMonthDateRange);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1089,8 +1090,8 @@ function getCategoryListItemCheckedClass(category: TransactionCategory, queryCat
|
||||
}
|
||||
|
||||
if (category.subCategories) {
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
if (queryCategoryIds && queryCategoryIds[category.subCategories[i].id]) {
|
||||
for (const subCategory of category.subCategories) {
|
||||
if (queryCategoryIds && queryCategoryIds[subCategory.id]) {
|
||||
return {
|
||||
'list-item-selected': true,
|
||||
'has-children-item-selected': true
|
||||
@@ -1382,7 +1383,7 @@ function changeCustomMonthDateFilter(yearMonth: Year0BasedMonth): void {
|
||||
}
|
||||
|
||||
function shiftDateRange(startTime: number, endTime: number, scale: number): void {
|
||||
if (recentMonthDateRanges.value[recentDateRangeIndex.value].dateType === DateRange.All.type) {
|
||||
if (recentMonthDateRanges.value[recentDateRangeIndex.value]?.dateType === DateRange.All.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1421,11 +1422,7 @@ function changeTypeFilter(type: number): void {
|
||||
if (type && query.value.categoryIds) {
|
||||
newCategoryFilter = '';
|
||||
|
||||
for (const categoryId in queryAllFilterCategoryIds.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(queryAllFilterCategoryIds.value, categoryId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const categoryId of keys(queryAllFilterCategoryIds.value)) {
|
||||
const category = allCategories.value[categoryId];
|
||||
|
||||
if (category && category.type === transactionTypeToCategoryType(type)) {
|
||||
@@ -1680,13 +1677,13 @@ function scrollAmountMenuToSelectedItem(opened: boolean): void {
|
||||
if (isString(query.value.amountFilter)) {
|
||||
try {
|
||||
const filterItems = query.value.amountFilter.split(':');
|
||||
const amountCount = getAmountFilterParameterCount(filterItems[0]);
|
||||
const amountCount = getAmountFilterParameterCount(filterItems[0] as string);
|
||||
|
||||
if (filterItems.length === 2 && amountCount === 1) {
|
||||
amount1 = parseInt(filterItems[1]);
|
||||
amount1 = parseInt(filterItems[1] as string);
|
||||
} else if (filterItems.length === 3 && amountCount === 2) {
|
||||
amount1 = parseInt(filterItems[1]);
|
||||
amount2 = parseInt(filterItems[2]);
|
||||
amount1 = parseInt(filterItems[1] as string);
|
||||
amount2 = parseInt(filterItems[2] as string);
|
||||
}
|
||||
} catch (ex) {
|
||||
logger.warn('cannot parse amount from filter value, original value is ' + query.value.amountFilter, ex);
|
||||
|
||||
@@ -93,11 +93,11 @@
|
||||
<div class="d-flex align-center" v-if="editingTransaction !== item || item.type === TransactionType.ModifyBalance">
|
||||
<span v-if="item.type === TransactionType.ModifyBalance">-</span>
|
||||
<ItemIcon size="24px" icon-type="category"
|
||||
:icon-id="allCategoriesMap[item.categoryId].icon"
|
||||
:color="allCategoriesMap[item.categoryId].color"
|
||||
:icon-id="allCategoriesMap[item.categoryId]?.icon ?? ''"
|
||||
:color="allCategoriesMap[item.categoryId]?.color ?? ''"
|
||||
v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]"></ItemIcon>
|
||||
<span class="ms-2" v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]">
|
||||
{{ allCategoriesMap[item.categoryId].name }}
|
||||
{{ allCategoriesMap[item.categoryId]?.name }}
|
||||
</span>
|
||||
<div class="text-error font-italic" v-else-if="item.type !== TransactionType.ModifyBalance && (!item.categoryId || item.categoryId === '0' || !allCategoriesMap[item.categoryId])">
|
||||
<v-icon class="me-1" :icon="mdiAlertOutline"/>
|
||||
@@ -166,13 +166,13 @@
|
||||
</template>
|
||||
<template #item.actualSourceAccountName="{ item }">
|
||||
<div class="d-flex align-center" v-if="editingTransaction !== item">
|
||||
<span v-if="item.sourceAccountId && item.sourceAccountId !== '0' && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId].name }}</span>
|
||||
<span v-if="item.sourceAccountId && item.sourceAccountId !== '0' && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId]?.name }}</span>
|
||||
<div class="text-error font-italic" v-else>
|
||||
<v-icon class="me-1" :icon="mdiAlertOutline"/>
|
||||
<span>{{ item.originalSourceAccountName }}</span>
|
||||
</div>
|
||||
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && item.destinationAccountId !== '0' && allAccountsMap[item.destinationAccountId]">{{allAccountsMap[item.destinationAccountId].name }}</span>
|
||||
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && item.destinationAccountId !== '0' && allAccountsMap[item.destinationAccountId]">{{allAccountsMap[item.destinationAccountId]?.name }}</span>
|
||||
<div class="text-error font-italic" v-else-if="item.type === TransactionType.Transfer && (!item.destinationAccountId || item.destinationAccountId === '0' || !allAccountsMap[item.destinationAccountId])">
|
||||
<v-icon class="me-1" :icon="mdiAlertOutline"/>
|
||||
<span>{{ item.originalDestinationAccountName }}</span>
|
||||
@@ -252,7 +252,7 @@
|
||||
<v-chip :class="{ 'font-italic': !isTagValid(editingTags, index) }"
|
||||
:prepend-icon="isTagValid(editingTags, index) ? mdiPound : mdiAlertOutline"
|
||||
:color="isTagValid(editingTags, index) ? 'default' : 'error'"
|
||||
:text="isTagValid(editingTags, index) ? allTagsMap[editingTags[index]].name : item.originalTagNames[index]"
|
||||
:text="isTagValid(editingTags, index) ? allTagsMap[editingTags[index] as string]?.name : item.originalTagNames[index]"
|
||||
v-bind="props"/>
|
||||
</template>
|
||||
|
||||
@@ -1153,7 +1153,7 @@ function getTransactionDisplayAmount(transaction: ImportTransaction): string {
|
||||
let currency = transaction.originalSourceAccountCurrency || defaultCurrency.value;
|
||||
|
||||
if (transaction.sourceAccountId && transaction.sourceAccountId !== '0' && allAccountsMap.value[transaction.sourceAccountId]) {
|
||||
currency = allAccountsMap.value[transaction.sourceAccountId].currency;
|
||||
currency = allAccountsMap.value[transaction.sourceAccountId]!.currency;
|
||||
}
|
||||
|
||||
return getDisplayCurrency(transaction.sourceAmount, currency);
|
||||
@@ -1167,7 +1167,7 @@ function getTransactionDisplayDestinationAmount(transaction: ImportTransaction):
|
||||
let currency = transaction.originalDestinationAccountCurrency || defaultCurrency.value;
|
||||
|
||||
if (transaction.destinationAccountId && transaction.destinationAccountId !== '0' && allAccountsMap.value[transaction.destinationAccountId]) {
|
||||
currency = allAccountsMap.value[transaction.destinationAccountId].currency;
|
||||
currency = allAccountsMap.value[transaction.destinationAccountId]!.currency;
|
||||
}
|
||||
|
||||
return getDisplayCurrency(transaction.destinationAmount, currency);
|
||||
@@ -1425,15 +1425,15 @@ function updateTransactionData(transaction: ImportTransaction): void {
|
||||
transaction.valid = transaction.isTransactionValid();
|
||||
|
||||
if (transaction.categoryId && allCategoriesMap.value[transaction.categoryId]) {
|
||||
transaction.actualCategoryName = allCategoriesMap.value[transaction.categoryId].name;
|
||||
transaction.actualCategoryName = allCategoriesMap.value[transaction.categoryId]!.name;
|
||||
}
|
||||
|
||||
if (transaction.sourceAccountId && allAccountsMap.value[transaction.sourceAccountId]) {
|
||||
transaction.actualSourceAccountName = allAccountsMap.value[transaction.sourceAccountId].name;
|
||||
transaction.actualSourceAccountName = allAccountsMap.value[transaction.sourceAccountId]!.name;
|
||||
}
|
||||
|
||||
if (transaction.destinationAccountId && allAccountsMap.value[transaction.destinationAccountId]) {
|
||||
transaction.actualDestinationAccountName = allAccountsMap.value[transaction.destinationAccountId].name;
|
||||
transaction.actualDestinationAccountName = allAccountsMap.value[transaction.destinationAccountId]!.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -358,15 +358,16 @@ const parsedFileLinesHeaders = computed<object[]>(() => {
|
||||
}
|
||||
}
|
||||
|
||||
const headers: object[] = [];
|
||||
const firstLine: string[] = props.parsedFileData && props.parsedFileData.length > 0 ? (props.parsedFileData[0] as string[]) : [];
|
||||
|
||||
const headers: object[] = [];
|
||||
headers.push({ key: 'index', value: 'index', title: '#', sortable: true, nowrap: true });
|
||||
|
||||
for (let i = 0; i < maxColumnCount; i++) {
|
||||
let title = `#${i + 1}`;
|
||||
|
||||
if (parsedFileDataColumnMapping.value.includeHeader && props.parsedFileData && props.parsedFileData[0][i]) {
|
||||
title = props.parsedFileData[0][i] as string;
|
||||
if (parsedFileDataColumnMapping.value.includeHeader && firstLine && firstLine[i]) {
|
||||
title = firstLine[i] as string;
|
||||
}
|
||||
|
||||
headers.push({ key: i.toString(), value: `column${i + 1}`, title: title, sortable: true, nowrap: true });
|
||||
|
||||
@@ -370,7 +370,7 @@
|
||||
<template #default>
|
||||
<div class="grid grid-cols-2">
|
||||
<div class="list-item-subitem no-chevron">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx].showIconSelectionSheet = true">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx]!.showIconSelectionSheet = true">
|
||||
<div class="item-content">
|
||||
<div class="item-inner">
|
||||
<div class="item-header">
|
||||
@@ -387,12 +387,12 @@
|
||||
|
||||
<icon-selection-sheet :all-icon-infos="ALL_ACCOUNT_ICONS"
|
||||
:color="subAccount.color"
|
||||
v-model:show="subAccountContexts[idx].showIconSelectionSheet"
|
||||
v-model:show="subAccountContexts[idx]!.showIconSelectionSheet"
|
||||
v-model="subAccount.icon"
|
||||
></icon-selection-sheet>
|
||||
</div>
|
||||
<div class="list-item-subitem no-chevron">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx].showColorSelectionSheet = true">
|
||||
<a class="item-link" href="#" @click="subAccountContexts[idx]!.showColorSelectionSheet = true">
|
||||
<div class="item-content">
|
||||
<div class="item-inner">
|
||||
<div class="item-header">
|
||||
@@ -408,7 +408,7 @@
|
||||
</a>
|
||||
|
||||
<color-selection-sheet :all-color-infos="ALL_ACCOUNT_COLORS"
|
||||
v-model:show="subAccountContexts[idx].showColorSelectionSheet"
|
||||
v-model:show="subAccountContexts[idx]!.showColorSelectionSheet"
|
||||
v-model="subAccount.color"
|
||||
></color-selection-sheet>
|
||||
</div>
|
||||
@@ -422,7 +422,7 @@
|
||||
:class="{ 'disabled': editAccountId && !isNewAccount(subAccount) }"
|
||||
:header="tt('Currency')"
|
||||
:no-chevron="!!editAccountId && !isNewAccount(subAccount)"
|
||||
@click="subAccountContexts[idx].showCurrencyPopup = true"
|
||||
@click="subAccountContexts[idx]!.showCurrencyPopup = true"
|
||||
>
|
||||
<template #title>
|
||||
<div class="no-padding no-margin">
|
||||
@@ -438,7 +438,7 @@
|
||||
:filter-placeholder="tt('Currency')"
|
||||
:filter-no-items-text="tt('No results')"
|
||||
:items="allCurrencies"
|
||||
v-model:show="subAccountContexts[idx].showCurrencyPopup"
|
||||
v-model:show="subAccountContexts[idx]!.showCurrencyPopup"
|
||||
v-model="subAccount.currency">
|
||||
</list-item-selection-popup>
|
||||
</f7-list-item>
|
||||
@@ -449,13 +449,13 @@
|
||||
:class="{ 'disabled': editAccountId && !isNewAccount(subAccount) }"
|
||||
:header="account.isLiability ? tt('Sub-account Outstanding Balance') : tt('Sub-account Balance')"
|
||||
:title="formatAccountDisplayBalance(subAccount)"
|
||||
@click="subAccountContexts[idx].showBalanceSheet = true"
|
||||
@click="subAccountContexts[idx]!.showBalanceSheet = true"
|
||||
>
|
||||
<number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
|
||||
:max-value="TRANSACTION_MAX_AMOUNT"
|
||||
:currency="subAccount.currency"
|
||||
:flip-negative="account.isLiability"
|
||||
v-model:show="subAccountContexts[idx].showBalanceSheet"
|
||||
v-model:show="subAccountContexts[idx]!.showBalanceSheet"
|
||||
v-model="subAccount.balance"
|
||||
></number-pad-sheet>
|
||||
</f7-list-item>
|
||||
@@ -467,15 +467,15 @@
|
||||
v-if="!editAccountId || isNewAccount(subAccount)"
|
||||
>
|
||||
<template #header>
|
||||
<div class="account-edit-balancetime-header" @click="showDateTimeDialog(subAccountContexts[idx], 'time')">{{ tt('Sub-account Balance Time') }}</div>
|
||||
<div class="account-edit-balancetime-header" @click="showDateTimeDialog(subAccountContexts[idx] as AccountContext, 'time')">{{ tt('Sub-account Balance Time') }}</div>
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="account-edit-balancetime-title">
|
||||
<div @click="showDateTimeDialog(subAccountContexts[idx], 'date')">{{ formatAccountBalanceDate(subAccount) }}</div> <div class="account-edit-balancetime-time" @click="showDateTimeDialog(subAccountContexts[idx], 'time')">{{ formatAccountBalanceTime(subAccount) }}</div>
|
||||
<div @click="showDateTimeDialog(subAccountContexts[idx] as AccountContext, 'date')">{{ formatAccountBalanceDate(subAccount) }}</div> <div class="account-edit-balancetime-time" @click="showDateTimeDialog(subAccountContexts[idx] as AccountContext, 'time')">{{ formatAccountBalanceTime(subAccount) }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<date-time-selection-sheet :init-mode="subAccountContexts[idx].balanceDateTimeSheetMode"
|
||||
v-model:show="subAccountContexts[idx].showBalanceDateTimeSheet"
|
||||
<date-time-selection-sheet :init-mode="subAccountContexts[idx]!.balanceDateTimeSheetMode"
|
||||
v-model:show="subAccountContexts[idx]!.showBalanceDateTimeSheet"
|
||||
v-model="subAccount.balanceTime">
|
||||
</date-time-selection-sheet>
|
||||
</f7-list-item>
|
||||
@@ -526,6 +526,7 @@ import { useAccountEditPageBaseBase } from '@/views/base/accounts/AccountEditPag
|
||||
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
|
||||
import { itemAndIndex } from '@/core/base.ts';
|
||||
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { ALL_ACCOUNT_ICONS } from '@/consts/icon.ts';
|
||||
@@ -709,14 +710,14 @@ function addSubAccountAndContext(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function removeSubAccount(subAccount: Account | null, confirm: boolean): void {
|
||||
if (!subAccount) {
|
||||
function removeSubAccount(currentSubAccount: Account | null, confirm: boolean): void {
|
||||
if (!currentSubAccount) {
|
||||
showAlert('An error occurred');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm) {
|
||||
subAccountToDelete.value = subAccount;
|
||||
subAccountToDelete.value = currentSubAccount;
|
||||
showDeleteActionSheet.value = true;
|
||||
return;
|
||||
}
|
||||
@@ -724,10 +725,10 @@ function removeSubAccount(subAccount: Account | null, confirm: boolean): void {
|
||||
showDeleteActionSheet.value = false;
|
||||
subAccountToDelete.value = null;
|
||||
|
||||
for (let i = 0; i < subAccounts.value.length; i++) {
|
||||
if (subAccounts.value[i] === subAccount) {
|
||||
subAccounts.value.splice(i, 1);
|
||||
subAccountContexts.value.splice(i, 1);
|
||||
for (const [subAccount, index] of itemAndIndex(subAccounts.value)) {
|
||||
if (subAccount === currentSubAccount) {
|
||||
subAccounts.value.splice(index, 1);
|
||||
subAccountContexts.value.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,13 +140,13 @@ const categories = computed<TransactionCategory[]>(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategories[categoryType.value];
|
||||
return transactionCategoriesStore.allTransactionCategories[categoryType.value] ?? [];
|
||||
} else if (primaryCategoryId.value && primaryCategoryId.value !== '' && primaryCategoryId.value !== '0') {
|
||||
if (!transactionCategoriesStore.allTransactionCategoriesMap || !transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value]) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value].subCategories || [];
|
||||
return transactionCategoriesStore.allTransactionCategoriesMap[primaryCategoryId.value]?.subCategories ?? [];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -684,9 +684,9 @@ const transactionPictures = computed<Record<string, string | undefined>[]>(() =>
|
||||
return thumbs;
|
||||
}
|
||||
|
||||
for (let i = 0; i < transaction.value.pictures.length; i++) {
|
||||
for (const picture of transaction.value.pictures) {
|
||||
thumbs.push({
|
||||
url: getTransactionPictureUrl(transaction.value.pictures[i])
|
||||
url: getTransactionPictureUrl(picture)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -700,8 +700,8 @@ const transactionThumbs = computed<(string | undefined)[]>(() => {
|
||||
return thumbs;
|
||||
}
|
||||
|
||||
for (let i = 0; i < transaction.value.pictures.length; i++) {
|
||||
thumbs.push(getTransactionPictureUrl(transaction.value.pictures[i]));
|
||||
for (const picture of transaction.value.pictures) {
|
||||
thumbs.push(getTransactionPictureUrl(picture));
|
||||
}
|
||||
|
||||
return thumbs;
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
v-for="(transaction, idx) in transactionMonthList.items"
|
||||
>
|
||||
<template #media>
|
||||
<div class="display-flex flex-direction-column transaction-date" :style="getTransactionDateStyle(transaction, idx > 0 ? transactionMonthList.items[idx - 1] : null)">
|
||||
<div class="display-flex flex-direction-column transaction-date" :style="getTransactionDateStyle(transaction, idx > 0 ? transactionMonthList.items[idx - 1] : undefined)">
|
||||
<span class="transaction-day full-line flex-direction-column">
|
||||
{{ getCalendarDisplayDayOfMonthFromUnixTime(transaction.time) }}
|
||||
</span>
|
||||
@@ -252,7 +252,7 @@
|
||||
<div class="item-footer">
|
||||
<div class="transaction-tags" v-if="showTagInTransactionListPage && transaction.tagIds && transaction.tagIds.length">
|
||||
<f7-chip media-text-color="var(--f7-chip-text-color)" class="transaction-tag"
|
||||
:text="allTransactionTags[tagId].name"
|
||||
:text="allTransactionTags[tagId]?.name"
|
||||
:key="tagId"
|
||||
v-for="tagId in transaction.tagIds">
|
||||
<template #media>
|
||||
@@ -373,7 +373,7 @@
|
||||
:class="getCategoryListItemCheckedClass(category, queryAllFilterCategoryIds)"
|
||||
:key="category.id"
|
||||
v-for="category in categories"
|
||||
v-show="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds].parentId === category.id)"
|
||||
v-show="!category.hidden || query.categoryIds === category.id || (allCategories[query.categoryIds] && allCategories[query.categoryIds]?.parentId === category.id)"
|
||||
>
|
||||
<template #media>
|
||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||
@@ -439,7 +439,7 @@
|
||||
:class="{ 'list-item-selected': query.accountIds === account.id, 'item-in-multiple-selection': queryAllFilterAccountIdsCount > 1 && queryAllFilterAccountIds[account.id] }"
|
||||
:key="account.id"
|
||||
v-for="account in allAccounts"
|
||||
v-show="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId].hidden)) || query.accountIds === account.id"
|
||||
v-show="(!account.hidden && (!allAccountsMap[account.parentId] || !allAccountsMap[account.parentId]!.hidden)) || query.accountIds === account.id"
|
||||
@click="changeAccountFilter(account.id)"
|
||||
>
|
||||
<template #media>
|
||||
@@ -597,7 +597,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type TypeAndDisplayName, keys } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import {
|
||||
type TextualYearMonth,
|
||||
@@ -742,9 +742,7 @@ const transactions = computed<TransactionMonthList[]>(() => {
|
||||
|
||||
const transactions :Transaction[] = [];
|
||||
|
||||
for (let i = 0; i < transactionData.items.length; i++) {
|
||||
const transaction = transactionData.items[i];
|
||||
|
||||
for (const transaction of transactionData.items) {
|
||||
if (transaction.gregorianCalendarYearDashMonthDashDay === currentCalendarDate.value) {
|
||||
transactions.push(transaction);
|
||||
}
|
||||
@@ -778,7 +776,7 @@ const noTransaction = computed<boolean>(() => {
|
||||
if (pageType.value === TransactionListPageType.List.type) {
|
||||
return transactionsStore.noTransaction;
|
||||
} else if (pageType.value === TransactionListPageType.Calendar.type) {
|
||||
return !transactions.value || !transactions.value.length || !transactions.value[0].items || !transactions.value[0].items.length;
|
||||
return !transactions.value || !transactions.value.length || !transactions.value[0]!.items || !transactions.value[0]!.items.length;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -832,8 +830,7 @@ function setTransactionMonthListHeights(reset: boolean): Promise<unknown> {
|
||||
if (transactions.value && transactions.value.length) {
|
||||
const heights: Record<string, number> = getElementActualHeights('.transaction-month-list');
|
||||
|
||||
for (let i = 0; i < transactions.value.length - 1; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
for (const transactionMonthList of transactions.value) {
|
||||
const yearDashMonth = transactionMonthList.yearDashMonth;
|
||||
const domId = getTransactionMonthListDomId(yearDashMonth);
|
||||
const height = heights[domId];
|
||||
@@ -851,8 +848,7 @@ function setTransactionInvisibleYearMonthList(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < transactions.value.length - 1; i++) {
|
||||
const transactionMonthList = transactions.value[i];
|
||||
for (const transactionMonthList of transactions.value) {
|
||||
const yearDashMonth = transactionMonthList.yearDashMonth;
|
||||
|
||||
const titleDomId = getTransactionMonthTitleDomId(yearDashMonth);
|
||||
@@ -875,7 +871,7 @@ function setTransactionInvisibleYearMonthList(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getTransactionDateStyle(transaction: Transaction, previousTransaction: Transaction | null): Record<string, string> {
|
||||
function getTransactionDateStyle(transaction: Transaction, previousTransaction: Transaction | undefined): Record<string, string> {
|
||||
if (!previousTransaction || transaction.gregorianCalendarDayOfMonth !== previousTransaction.gregorianCalendarDayOfMonth) {
|
||||
return {};
|
||||
}
|
||||
@@ -893,8 +889,8 @@ function getCategoryListItemCheckedClass(category: TransactionCategory, queryCat
|
||||
}
|
||||
|
||||
if (category.subCategories) {
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
if (queryCategoryIds && queryCategoryIds[category.subCategories[i].id]) {
|
||||
for (const subCategory of category.subCategories) {
|
||||
if (queryCategoryIds && queryCategoryIds[subCategory.id]) {
|
||||
return {
|
||||
'list-item-checked': true
|
||||
};
|
||||
@@ -1208,11 +1204,7 @@ function changeTypeFilter(type: number): void {
|
||||
if (type && query.value.categoryIds) {
|
||||
newCategoryFilter = '';
|
||||
|
||||
for (const categoryId in queryAllFilterCategoryIds.value) {
|
||||
if (!Object.prototype.hasOwnProperty.call(queryAllFilterCategoryIds.value, categoryId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const categoryId of keys(queryAllFilterCategoryIds.value)) {
|
||||
const category = allCategories.value[categoryId];
|
||||
|
||||
if (category && category.type === transactionTypeToCategoryType(type)) {
|
||||
|
||||
Reference in New Issue
Block a user