WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 44dc45d

Browse files
committed
transaction reconciliation statement supports sorting by account name and category name on desktop version
1 parent 83bd68e commit 44dc45d

File tree

4 files changed

+97
-65
lines changed

4 files changed

+97
-65
lines changed

src/models/transaction.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,22 @@ export interface TransactionReconciliationStatementResponse {
690690
readonly closingBalance: number;
691691
}
692692

693+
export interface TransactionReconciliationStatementResponseItemWithInfo extends TransactionReconciliationStatementResponseItem {
694+
readonly sourceAccount?: Account;
695+
readonly sourceAccountName: string;
696+
readonly destinationAccount?: Account;
697+
readonly category?: TransactionCategory;
698+
readonly categoryName: string;
699+
}
700+
701+
export interface TransactionReconciliationStatementResponseWithInfo {
702+
readonly transactions: TransactionReconciliationStatementResponseItemWithInfo[];
703+
readonly totalInflows: number;
704+
readonly totalOutflows: number;
705+
readonly openingBalance: number;
706+
readonly closingBalance: number;
707+
}
708+
693709
export interface TransactionPageWrapper {
694710
readonly items: Transaction[];
695711
readonly totalCount?: number;

src/views/base/accounts/ReconciliationStatementPageBase.ts

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import type { Account } from '@/models/account.ts';
1616
import type { TransactionCategory } from '@/models/transaction_category.ts';
1717
import type {
1818
TransactionReconciliationStatementResponse,
19-
TransactionReconciliationStatementResponseItem
19+
TransactionReconciliationStatementResponseItemWithInfo,
20+
TransactionReconciliationStatementResponseWithInfo
2021
} from '@/models/transaction.ts';
2122

2223
import { replaceAll } from '@/lib/common.ts';
@@ -48,7 +49,7 @@ export function useReconciliationStatementPageBase() {
4849
const accountId = ref<string>('');
4950
const startTime = ref<number>(0);
5051
const endTime = ref<number>(0);
51-
const reconciliationStatements = ref<TransactionReconciliationStatementResponse | undefined>(undefined);
52+
const reconciliationStatements = ref<TransactionReconciliationStatementResponseWithInfo | undefined>(undefined);
5253

5354
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
5455
const fiscalYearStart = computed<number>(() => userStore.currentUserFiscalYearStart);
@@ -113,7 +114,34 @@ export function useReconciliationStatementPageBase() {
113114
}
114115
});
115116

116-
function getDisplayTransactionType(transaction: TransactionReconciliationStatementResponseItem): string {
117+
function setReconciliationStatements(response: TransactionReconciliationStatementResponse | undefined) {
118+
if (!response) {
119+
reconciliationStatements.value = undefined;
120+
return;
121+
}
122+
123+
const responseWithInfo: TransactionReconciliationStatementResponseWithInfo = {
124+
transactions: response.transactions.map(transaction => {
125+
const transactionWithInfo: TransactionReconciliationStatementResponseItemWithInfo = {
126+
...transaction,
127+
sourceAccount: allAccountsMap.value[transaction.sourceAccountId],
128+
sourceAccountName: allAccountsMap.value[transaction.sourceAccountId]?.name || '',
129+
destinationAccount: transaction.destinationAccountId && transaction.destinationAccountId !== '0' ? allAccountsMap.value[transaction.destinationAccountId] : undefined,
130+
category: allCategoriesMap.value[transaction.categoryId],
131+
categoryName: allCategoriesMap.value[transaction.categoryId]?.name || ''
132+
};
133+
return transactionWithInfo;
134+
}),
135+
totalInflows: response.totalInflows,
136+
totalOutflows: response.totalOutflows,
137+
openingBalance: response.openingBalance,
138+
closingBalance: response.closingBalance
139+
};
140+
141+
reconciliationStatements.value = responseWithInfo;
142+
}
143+
144+
function getDisplayTransactionType(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
117145
if (transaction.type === TransactionType.ModifyBalance) {
118146
return tt('Modify Balance');
119147
} else if (transaction.type === TransactionType.Income) {
@@ -131,54 +159,44 @@ export function useReconciliationStatementPageBase() {
131159
}
132160
}
133161

134-
function getDisplayDateTime(transaction: TransactionReconciliationStatementResponseItem): string {
162+
function getDisplayDateTime(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
135163
return formatUnixTimeToLongDateTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
136164
}
137165

138-
function getDisplayDate(transaction: TransactionReconciliationStatementResponseItem): string {
166+
function getDisplayDate(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
139167
return formatUnixTimeToLongDate(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
140168
}
141169

142-
function getDisplayTime(transaction: TransactionReconciliationStatementResponseItem): string {
170+
function getDisplayTime(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
143171
return formatUnixTimeToShortTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
144172
}
145173

146-
function getDisplayTimezone(transaction: TransactionReconciliationStatementResponseItem): string {
174+
function getDisplayTimezone(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
147175
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)}`;
148176
}
149177

150-
function getDisplaySourceAmount(transaction: TransactionReconciliationStatementResponseItem): string {
151-
let currency = defaultCurrency.value;
152-
153-
if (allAccountsMap.value[transaction.sourceAccountId]) {
154-
currency = allAccountsMap.value[transaction.sourceAccountId]!.currency;
155-
}
156-
178+
function getDisplaySourceAmount(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
179+
const currency = transaction.sourceAccount?.currency ?? defaultCurrency.value;
157180
return formatAmountToLocalizedNumeralsWithCurrency(transaction.sourceAmount, currency);
158181
}
159182

160-
function getDisplayDestinationAmount(transaction: TransactionReconciliationStatementResponseItem): string {
161-
let currency = defaultCurrency.value;
162-
163-
if (allAccountsMap.value[transaction.destinationAccountId]) {
164-
currency = allAccountsMap.value[transaction.destinationAccountId]!.currency;
165-
}
166-
183+
function getDisplayDestinationAmount(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
184+
const currency = transaction.destinationAccount?.currency ?? defaultCurrency.value;
167185
return formatAmountToLocalizedNumeralsWithCurrency(transaction.destinationAmount, currency);
168186
}
169187

170-
function getDisplayAccountBalance(transaction: TransactionReconciliationStatementResponseItem): string {
188+
function getDisplayAccountBalance(transaction: TransactionReconciliationStatementResponseItemWithInfo): string {
171189
let currency = defaultCurrency.value;
172190
let isLiabilityAccount = false;
173191

174192
if (transaction.type === TransactionType.Transfer && transaction.destinationAccountId === accountId.value) {
175-
if (allAccountsMap.value[transaction.destinationAccountId]) {
176-
currency = allAccountsMap.value[transaction.destinationAccountId]!.currency;
177-
isLiabilityAccount = allAccountsMap.value[transaction.destinationAccountId]!.isLiability;
193+
if (transaction.destinationAccount) {
194+
currency = transaction.destinationAccount.currency;
195+
isLiabilityAccount = transaction.destinationAccount.isLiability;
178196
}
179-
} else if (allAccountsMap.value[transaction.sourceAccountId]) {
180-
currency = allAccountsMap.value[transaction.sourceAccountId]!.currency;
181-
isLiabilityAccount = allAccountsMap.value[transaction.sourceAccountId]!.isLiability;
197+
} else if (transaction.sourceAccount) {
198+
currency = transaction.sourceAccount.currency;
199+
isLiabilityAccount = transaction.sourceAccount.isLiability;
182200
}
183201

184202
if (isLiabilityAccount) {
@@ -211,18 +229,18 @@ export function useReconciliationStatementPageBase() {
211229
const rows = transactions.map(transaction => {
212230
const transactionTime = parseDateTimeFromUnixTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value).getUnixTime();
213231
const type = getDisplayTransactionType(transaction);
214-
let categoryName = allCategoriesMap.value[transaction.categoryId]?.name || '';
232+
let categoryName = transaction.categoryName;
215233
let displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.sourceAmount);
216-
let displayAccountName = allAccountsMap.value[transaction.sourceAccountId]?.name || '';
234+
let displayAccountName = transaction.sourceAccountName;
217235

218236
if (transaction.type === TransactionType.ModifyBalance) {
219237
categoryName = tt('Modify Balance');
220238
} else if (transaction.type === TransactionType.Transfer && transaction.destinationAccountId === accountId.value) {
221239
displayAmount = formatAmountToWesternArabicNumeralsWithoutDigitGrouping(transaction.destinationAmount);
222240
}
223241

224-
if (transaction.type === TransactionType.Transfer && allAccountsMap.value[transaction.destinationAccountId]) {
225-
displayAccountName = displayAccountName + ' → ' + (allAccountsMap.value[transaction.destinationAccountId]?.name || '');
242+
if (transaction.type === TransactionType.Transfer && transaction.destinationAccount) {
243+
displayAccountName = displayAccountName + ' → ' + (transaction.destinationAccount?.name || '');
226244
}
227245

228246
let displayAccountBalance = '';
@@ -272,8 +290,6 @@ export function useReconciliationStatementPageBase() {
272290
currentAccountCurrency,
273291
isCurrentLiabilityAccount,
274292
exportFileName,
275-
allAccountsMap,
276-
allCategoriesMap,
277293
displayStartDateTime,
278294
displayEndDateTime,
279295
displayTotalInflows,
@@ -282,6 +298,7 @@ export function useReconciliationStatementPageBase() {
282298
displayOpeningBalance,
283299
displayClosingBalance,
284300
// functions
301+
setReconciliationStatements,
285302
getDisplayTransactionType,
286303
getDisplayDateTime,
287304
getDisplayDate,

src/views/desktop/accounts/list/dialogs/ReconciliationStatementDialog.vue

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,18 @@
155155
:class="{ 'text-income' : item.type === TransactionType.Income, 'text-expense': item.type === TransactionType.Expense }"
156156
:color="getTransactionTypeColor(item)">{{ getDisplayTransactionType(item) }}</v-chip>
157157
</template>
158-
<template #item.categoryId="{ item }">
158+
<template #item.categoryName="{ item }">
159159
<div class="d-flex align-center">
160160
<ItemIcon size="24px" icon-type="category"
161-
:icon-id="allCategoriesMap[item.categoryId]?.icon ?? ''"
162-
:color="allCategoriesMap[item.categoryId]?.color ?? ''"
163-
v-if="allCategoriesMap[item.categoryId] && allCategoriesMap[item.categoryId]?.color"></ItemIcon>
164-
<v-icon size="24" :icon="mdiPencilBoxOutline" v-else-if="!allCategoriesMap[item.categoryId] || !allCategoriesMap[item.categoryId]?.color" />
161+
:icon-id="item.category?.icon ?? ''"
162+
:color="item.category?.color ?? ''"
163+
v-if="item.category && item.category?.color"></ItemIcon>
164+
<v-icon size="24" :icon="mdiPencilBoxOutline" v-else-if="!item.category || !item.category?.color" />
165165
<span class="ms-2" v-if="item.type === TransactionType.ModifyBalance">
166166
{{ tt('Modify Balance') }}
167167
</span>
168-
<span class="ms-2" v-else-if="item.type !== TransactionType.ModifyBalance && allCategoriesMap[item.categoryId]">
169-
{{ allCategoriesMap[item.categoryId]?.name }}
168+
<span class="ms-2" v-else-if="item.type !== TransactionType.ModifyBalance && item.category">
169+
{{ item.category?.name }}
170170
</span>
171171
</div>
172172
</template>
@@ -175,11 +175,11 @@
175175
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer && item.sourceAccountId !== item.destinationAccountId && getDisplaySourceAmount(item) !== getDisplayDestinationAmount(item)"></v-icon>
176176
<span v-if="item.type === TransactionType.Transfer && item.sourceAccountId !== item.destinationAccountId && getDisplaySourceAmount(item) !== getDisplayDestinationAmount(item)">{{ getDisplayDestinationAmount(item) }}</span>
177177
</template>
178-
<template #item.sourceAccountId="{ item }">
178+
<template #item.sourceAccountName="{ item }">
179179
<div class="d-flex align-center">
180-
<span v-if="item.sourceAccountId && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId]?.name }}</span>
180+
<span v-if="item.sourceAccount">{{ item.sourceAccount?.name }}</span>
181181
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
182-
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && allAccountsMap[item.destinationAccountId]">{{ allAccountsMap[item.destinationAccountId]?.name }}</span>
182+
<span v-if="item.type === TransactionType.Transfer && item.destinationAccount">{{ item.destinationAccount?.name }}</span>
183183
</div>
184184
</template>
185185
<template #item.accountBalance="{ item }">
@@ -326,8 +326,6 @@ const {
326326
currentAccount,
327327
currentAccountCurrency,
328328
isCurrentLiabilityAccount,
329-
allAccountsMap,
330-
allCategoriesMap,
331329
exportFileName,
332330
displayStartDateTime,
333331
displayEndDateTime,
@@ -336,6 +334,7 @@ const {
336334
displayTotalBalance,
337335
displayOpeningBalance,
338336
displayClosingBalance,
337+
setReconciliationStatements,
339338
getDisplayTransactionType,
340339
getDisplayDateTime,
341340
getDisplayTimezone,
@@ -395,9 +394,9 @@ const dataTableHeaders = computed<object[]>(() => {
395394
396395
headers.push({ key: 'time', value: 'time', title: tt('Transaction Time'), sortable: true, nowrap: true });
397396
headers.push({ key: 'type', value: 'type', title: tt('Type'), sortable: true, nowrap: true });
398-
headers.push({ key: 'categoryId', value: 'categoryId', title: tt('Category'), sortable: true, nowrap: true });
397+
headers.push({ key: 'categoryName', value: 'categoryName', title: tt('Category'), sortable: true, nowrap: true });
399398
headers.push({ key: 'sourceAmount', value: 'sourceAmount', title: tt('Amount'), sortable: true, nowrap: true });
400-
headers.push({ key: 'sourceAccountId', value: 'sourceAccountId', title: tt('Account'), sortable: true, nowrap: true });
399+
headers.push({ key: 'sourceAccountName', value: 'sourceAccountName', title: tt('Account'), sortable: true, nowrap: true });
401400
headers.push({ key: 'accountBalance', value: 'accountBalance', title: tt(accountBalanceName), sortable: true, nowrap: true });
402401
headers.push({ key: 'comment', value: 'comment', title: tt('Description'), sortable: true, nowrap: true });
403402
headers.push({ key: 'operation', title: tt('Operation'), sortable: false, nowrap: true, align: 'end' });
@@ -464,7 +463,7 @@ function open(options: { accountId: string, startTime: number, endTime: number }
464463
endTime: options.endTime
465464
});
466465
}).then(result => {
467-
reconciliationStatements.value = result;
466+
setReconciliationStatements(result);
468467
loading.value = false;
469468
}).catch(error => {
470469
loading.value = false;
@@ -496,7 +495,7 @@ function reload(force: boolean): void {
496495
}
497496
}
498497
499-
reconciliationStatements.value = result;
498+
setReconciliationStatements(result);
500499
loading.value = false;
501500
}).catch(error => {
502501
loading.value = false;

0 commit comments

Comments
 (0)