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