mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-18 16:54:25 +08:00
add reconciliation statement page for mobile version
This commit is contained in:
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Sparkonto",
|
"Savings Account": "Sparkonto",
|
||||||
"Certificate of Deposit": "Einlagenzertifikat",
|
"Certificate of Deposit": "Einlagenzertifikat",
|
||||||
"Balance": "Saldo",
|
"Balance": "Saldo",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Kontoliste kann nicht abgerufen werden",
|
"Unable to retrieve account list": "Kontoliste kann nicht abgerufen werden",
|
||||||
"Account list is up to date": "Kontoliste ist aktuell",
|
"Account list is up to date": "Kontoliste ist aktuell",
|
||||||
"Account list has been updated": "Kontoliste wurde aktualisiert",
|
"Account list has been updated": "Kontoliste wurde aktualisiert",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Savings Account",
|
"Savings Account": "Savings Account",
|
||||||
"Certificate of Deposit": "Certificate of Deposit",
|
"Certificate of Deposit": "Certificate of Deposit",
|
||||||
"Balance": "Balance",
|
"Balance": "Balance",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Unable to retrieve account list",
|
"Unable to retrieve account list": "Unable to retrieve account list",
|
||||||
"Account list is up to date": "Account list is up to date",
|
"Account list is up to date": "Account list is up to date",
|
||||||
"Account list has been updated": "Account list has been updated",
|
"Account list has been updated": "Account list has been updated",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Cuenta de ahorros",
|
"Savings Account": "Cuenta de ahorros",
|
||||||
"Certificate of Deposit": "Certificado de Depósito",
|
"Certificate of Deposit": "Certificado de Depósito",
|
||||||
"Balance": "Balance",
|
"Balance": "Balance",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "No se puede recuperar la lista de cuentas",
|
"Unable to retrieve account list": "No se puede recuperar la lista de cuentas",
|
||||||
"Account list is up to date": "La lista de cuentas está actualizada.",
|
"Account list is up to date": "La lista de cuentas está actualizada.",
|
||||||
"Account list has been updated": "La lista de cuentas ha sido actualizada.",
|
"Account list has been updated": "La lista de cuentas ha sido actualizada.",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Conto di risparmio",
|
"Savings Account": "Conto di risparmio",
|
||||||
"Certificate of Deposit": "Certificato di deposito",
|
"Certificate of Deposit": "Certificato di deposito",
|
||||||
"Balance": "Saldo",
|
"Balance": "Saldo",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Impossibile recuperare l'elenco degli account",
|
"Unable to retrieve account list": "Impossibile recuperare l'elenco degli account",
|
||||||
"Account list is up to date": "Elenco account aggiornato",
|
"Account list is up to date": "Elenco account aggiornato",
|
||||||
"Account list has been updated": "Elenco account aggiornato",
|
"Account list has been updated": "Elenco account aggiornato",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "普通預金口座",
|
"Savings Account": "普通預金口座",
|
||||||
"Certificate of Deposit": "預金証書",
|
"Certificate of Deposit": "預金証書",
|
||||||
"Balance": "残高",
|
"Balance": "残高",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "口座リストを取得できません",
|
"Unable to retrieve account list": "口座リストを取得できません",
|
||||||
"Account list is up to date": "口座リストは最新です",
|
"Account list is up to date": "口座リストは最新です",
|
||||||
"Account list has been updated": "口座リストが更新されました",
|
"Account list has been updated": "口座リストが更新されました",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Conta Poupança",
|
"Savings Account": "Conta Poupança",
|
||||||
"Certificate of Deposit": "Certificado de Depósito",
|
"Certificate of Deposit": "Certificado de Depósito",
|
||||||
"Balance": "Saldo",
|
"Balance": "Saldo",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Não foi possível recuperar a lista de contas",
|
"Unable to retrieve account list": "Não foi possível recuperar a lista de contas",
|
||||||
"Account list is up to date": "A lista de contas está atualizada",
|
"Account list is up to date": "A lista de contas está atualizada",
|
||||||
"Account list has been updated": "A lista de contas foi atualizada",
|
"Account list has been updated": "A lista de contas foi atualizada",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Сберегательный счет",
|
"Savings Account": "Сберегательный счет",
|
||||||
"Certificate of Deposit": "Депозитный сертификат",
|
"Certificate of Deposit": "Депозитный сертификат",
|
||||||
"Balance": "Баланс",
|
"Balance": "Баланс",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Не удается получить список счетов",
|
"Unable to retrieve account list": "Не удается получить список счетов",
|
||||||
"Account list is up to date": "Список счетов актуален",
|
"Account list is up to date": "Список счетов актуален",
|
||||||
"Account list has been updated": "Список счетов обновлен",
|
"Account list has been updated": "Список счетов обновлен",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Ощадний рахунок",
|
"Savings Account": "Ощадний рахунок",
|
||||||
"Certificate of Deposit": "Депозитний сертифікат",
|
"Certificate of Deposit": "Депозитний сертифікат",
|
||||||
"Balance": "Баланс",
|
"Balance": "Баланс",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Не вдалося отримати список рахунків",
|
"Unable to retrieve account list": "Не вдалося отримати список рахунків",
|
||||||
"Account list is up to date": "Список рахунків актуальний",
|
"Account list is up to date": "Список рахунків актуальний",
|
||||||
"Account list has been updated": "Список рахунків оновлено",
|
"Account list has been updated": "Список рахунків оновлено",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "Tài khoản tiết kiệm",
|
"Savings Account": "Tài khoản tiết kiệm",
|
||||||
"Certificate of Deposit": "Giấy chứng nhận tiền gửi",
|
"Certificate of Deposit": "Giấy chứng nhận tiền gửi",
|
||||||
"Balance": "Số dư",
|
"Balance": "Số dư",
|
||||||
|
"Outstanding Balance": "Outstanding Balance",
|
||||||
"Unable to retrieve account list": "Không thể lấy danh sách tài khoản",
|
"Unable to retrieve account list": "Không thể lấy danh sách tài khoản",
|
||||||
"Account list is up to date": "Danh sách tài khoản đã được cập nhật",
|
"Account list is up to date": "Danh sách tài khoản đã được cập nhật",
|
||||||
"Account list has been updated": "Danh sách tài khoản đã được cập nhật",
|
"Account list has been updated": "Danh sách tài khoản đã được cập nhật",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "储蓄账户",
|
"Savings Account": "储蓄账户",
|
||||||
"Certificate of Deposit": "定期存款",
|
"Certificate of Deposit": "定期存款",
|
||||||
"Balance": "余额",
|
"Balance": "余额",
|
||||||
|
"Outstanding Balance": "未清余额",
|
||||||
"Unable to retrieve account list": "无法获取账户列表",
|
"Unable to retrieve account list": "无法获取账户列表",
|
||||||
"Account list is up to date": "账户列表已是最新",
|
"Account list is up to date": "账户列表已是最新",
|
||||||
"Account list has been updated": "账户列表已更新",
|
"Account list has been updated": "账户列表已更新",
|
||||||
|
|||||||
@@ -1577,6 +1577,7 @@
|
|||||||
"Savings Account": "儲蓄帳戶",
|
"Savings Account": "儲蓄帳戶",
|
||||||
"Certificate of Deposit": "定期存款",
|
"Certificate of Deposit": "定期存款",
|
||||||
"Balance": "餘額",
|
"Balance": "餘額",
|
||||||
|
"Outstanding Balance": "未清餘額",
|
||||||
"Unable to retrieve account list": "無法取得帳戶清單",
|
"Unable to retrieve account list": "無法取得帳戶清單",
|
||||||
"Account list is up to date": "帳戶清單已是最新",
|
"Account list is up to date": "帳戶清單已是最新",
|
||||||
"Account list has been updated": "帳戶清單已更新",
|
"Account list has been updated": "帳戶清單已更新",
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import Framework7Skeleton from 'framework7/components/skeleton';
|
|||||||
import Framework7Treeview from 'framework7/components/treeview';
|
import Framework7Treeview from 'framework7/components/treeview';
|
||||||
import Framework7Typography from 'framework7/components/typography';
|
import Framework7Typography from 'framework7/components/typography';
|
||||||
import Framework7Swiper from 'framework7/components/swiper';
|
import Framework7Swiper from 'framework7/components/swiper';
|
||||||
|
import Framework7VirtualList from 'framework7/components/virtual-list';
|
||||||
import Framework7PhotoBrowser from 'framework7/components/photo-browser';
|
import Framework7PhotoBrowser from 'framework7/components/photo-browser';
|
||||||
// @ts-expect-error there is a function called "registerComponents" in the framework7-vue package, but it is not declared in the type definition file
|
// @ts-expect-error there is a function called "registerComponents" in the framework7-vue package, but it is not declared in the type definition file
|
||||||
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
|
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
|
||||||
@@ -155,6 +156,7 @@ Framework7.use([
|
|||||||
Framework7Treeview,
|
Framework7Treeview,
|
||||||
Framework7Typography,
|
Framework7Typography,
|
||||||
Framework7Swiper,
|
Framework7Swiper,
|
||||||
|
Framework7VirtualList,
|
||||||
Framework7PhotoBrowser,
|
Framework7PhotoBrowser,
|
||||||
Framework7Vue
|
Framework7Vue
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import TransactionAmountFilterPage from '@/views/mobile/transactions/AmountFilte
|
|||||||
|
|
||||||
import AccountListPage from '@/views/mobile/accounts/ListPage.vue';
|
import AccountListPage from '@/views/mobile/accounts/ListPage.vue';
|
||||||
import AccountEditPage from '@/views/mobile/accounts/EditPage.vue';
|
import AccountEditPage from '@/views/mobile/accounts/EditPage.vue';
|
||||||
|
import AccountReconciliationStatementPage from '@/views/mobile/accounts/ReconciliationStatementPage.vue';
|
||||||
|
|
||||||
import StatisticsTransactionPage from '@/views/mobile/statistics/TransactionPage.vue';
|
import StatisticsTransactionPage from '@/views/mobile/statistics/TransactionPage.vue';
|
||||||
import StatisticsSettingsPage from '@/views/mobile/statistics/SettingsPage.vue';
|
import StatisticsSettingsPage from '@/views/mobile/statistics/SettingsPage.vue';
|
||||||
@@ -191,6 +192,11 @@ const routes: Router.RouteParameters[] = [
|
|||||||
async: asyncResolve(AccountEditPage),
|
async: asyncResolve(AccountEditPage),
|
||||||
beforeEnter: [checkLogin]
|
beforeEnter: [checkLogin]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/account/reconciliation_statements',
|
||||||
|
async: asyncResolve(AccountReconciliationStatementPage),
|
||||||
|
beforeEnter: [checkLogin]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/statistic/transaction',
|
path: '/statistic/transaction',
|
||||||
async: asyncResolve(StatisticsTransactionPage),
|
async: asyncResolve(StatisticsTransactionPage),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useUserStore } from '@/stores/user.ts';
|
|||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
|
|
||||||
import { KnownDateTimeFormat } from '@/core/datetime.ts';
|
import { type WeekDayValue, KnownDateTimeFormat } from '@/core/datetime.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
import { KnownFileType } from '@/core/file.ts';
|
import { KnownFileType } from '@/core/file.ts';
|
||||||
import type { Account } from '@/models/account.ts';
|
import type { Account } from '@/models/account.ts';
|
||||||
@@ -32,6 +32,8 @@ export function useReconciliationStatementPageBase() {
|
|||||||
tt,
|
tt,
|
||||||
getCurrentDigitGroupingSymbol,
|
getCurrentDigitGroupingSymbol,
|
||||||
formatUnixTimeToLongDateTime,
|
formatUnixTimeToLongDateTime,
|
||||||
|
formatUnixTimeToLongDate,
|
||||||
|
formatUnixTimeToShortTime,
|
||||||
formatAmount,
|
formatAmount,
|
||||||
formatAmountWithCurrency
|
formatAmountWithCurrency
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
@@ -48,6 +50,8 @@ export function useReconciliationStatementPageBase() {
|
|||||||
const openingBalance = ref<number>(0);
|
const openingBalance = ref<number>(0);
|
||||||
const closingBalance = ref<number>(0);
|
const closingBalance = ref<number>(0);
|
||||||
|
|
||||||
|
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||||
|
const fiscalYearStart = computed<number>(() => userStore.currentUserFiscalYearStart);
|
||||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||||
|
|
||||||
@@ -143,6 +147,14 @@ export function useReconciliationStatementPageBase() {
|
|||||||
return formatUnixTimeToLongDateTime(transactionTime);
|
return formatUnixTimeToLongDateTime(transactionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDisplayDate(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||||
|
return formatUnixTimeToLongDate(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplayTime(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||||
|
return formatUnixTimeToShortTime(transaction.time, transaction.utcOffset, currentTimezoneOffsetMinutes.value);
|
||||||
|
}
|
||||||
|
|
||||||
function getDisplayTimezone(transaction: TransactionReconciliationStatementResponseItem): string {
|
function getDisplayTimezone(transaction: TransactionReconciliationStatementResponseItem): string {
|
||||||
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)}`;
|
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)}`;
|
||||||
}
|
}
|
||||||
@@ -276,6 +288,8 @@ export function useReconciliationStatementPageBase() {
|
|||||||
openingBalance,
|
openingBalance,
|
||||||
closingBalance,
|
closingBalance,
|
||||||
// computed states
|
// computed states
|
||||||
|
firstDayOfWeek,
|
||||||
|
fiscalYearStart,
|
||||||
currentTimezoneOffsetMinutes,
|
currentTimezoneOffsetMinutes,
|
||||||
defaultCurrency,
|
defaultCurrency,
|
||||||
currentAccount,
|
currentAccount,
|
||||||
@@ -293,6 +307,8 @@ export function useReconciliationStatementPageBase() {
|
|||||||
displayClosingBalance,
|
displayClosingBalance,
|
||||||
// functions
|
// functions
|
||||||
getDisplayDateTime,
|
getDisplayDateTime,
|
||||||
|
getDisplayDate,
|
||||||
|
getDisplayTime,
|
||||||
getDisplayTimezone,
|
getDisplayTimezone,
|
||||||
getDisplaySourceAmount,
|
getDisplaySourceAmount,
|
||||||
getDisplayDestinationAmount,
|
getDisplayDestinationAmount,
|
||||||
|
|||||||
@@ -145,6 +145,7 @@
|
|||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
<f7-swipeout-actions right v-if="!sortable">
|
<f7-swipeout-actions right v-if="!sortable">
|
||||||
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(account)"></f7-swipeout-button>
|
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(account)"></f7-swipeout-button>
|
||||||
|
<f7-swipeout-button color="deeporange" close :text="tt('More')" @click="showMoreActionSheetForAccount(account)"></f7-swipeout-button>
|
||||||
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(account, false)">
|
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(account, false)">
|
||||||
<f7-icon f7="trash"></f7-icon>
|
<f7-icon f7="trash"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
@@ -153,6 +154,23 @@
|
|||||||
</f7-list>
|
</f7-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<f7-actions close-by-outside-click close-on-escape :opened="showAccountMoreActionSheet" @actions:closed="showAccountMoreActionSheet = false">
|
||||||
|
<f7-actions-group v-if="accountForMoreActionSheet && accountForMoreActionSheet.type === AccountType.SingleAccount.type">
|
||||||
|
<f7-actions-button @click="showReconciliationStatement(accountForMoreActionSheet)">{{ tt('Reconciliation Statement') }}</f7-actions-button>
|
||||||
|
</f7-actions-group>
|
||||||
|
<template v-if="accountForMoreActionSheet && accountForMoreActionSheet.type === AccountType.MultiSubAccounts.type">
|
||||||
|
<f7-actions-group :key="subAccount.id"
|
||||||
|
v-for="subAccount in accountForMoreActionSheet.subAccounts"
|
||||||
|
v-show="showHidden || !subAccount.hidden">
|
||||||
|
<f7-actions-label>{{ subAccount.name }}</f7-actions-label>
|
||||||
|
<f7-actions-button @click="showReconciliationStatement(subAccount)">{{ tt('Reconciliation Statement') }}</f7-actions-button>
|
||||||
|
</f7-actions-group>
|
||||||
|
</template>
|
||||||
|
<f7-actions-group>
|
||||||
|
<f7-actions-button bold close>{{ tt('Cancel') }}</f7-actions-button>
|
||||||
|
</f7-actions-group>
|
||||||
|
</f7-actions>
|
||||||
|
|
||||||
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
||||||
<f7-actions-group>
|
<f7-actions-group>
|
||||||
<f7-actions-button @click="setSortable()">{{ tt('Sort') }}</f7-actions-button>
|
<f7-actions-button @click="setSortable()">{{ tt('Sort') }}</f7-actions-button>
|
||||||
@@ -219,7 +237,9 @@ const accountsStore = useAccountsStore();
|
|||||||
|
|
||||||
const loadingError = ref<unknown | null>(null);
|
const loadingError = ref<unknown | null>(null);
|
||||||
const sortable = ref<boolean>(false);
|
const sortable = ref<boolean>(false);
|
||||||
|
const accountForMoreActionSheet = ref<Account | null>(null);
|
||||||
const accountToDelete = ref<Account | null>(null);
|
const accountToDelete = ref<Account | null>(null);
|
||||||
|
const showAccountMoreActionSheet = ref<boolean>(false);
|
||||||
const showMoreActionSheet = ref<boolean>(false);
|
const showMoreActionSheet = ref<boolean>(false);
|
||||||
const showDeleteActionSheet = ref<boolean>(false);
|
const showDeleteActionSheet = ref<boolean>(false);
|
||||||
const displayOrderSaving = ref<boolean>(false);
|
const displayOrderSaving = ref<boolean>(false);
|
||||||
@@ -301,6 +321,22 @@ function edit(account: Account): void {
|
|||||||
props.f7router.navigate('/account/edit?id=' + account.id);
|
props.f7router.navigate('/account/edit?id=' + account.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showMoreActionSheetForAccount(account: Account): void {
|
||||||
|
accountForMoreActionSheet.value = account;
|
||||||
|
showAccountMoreActionSheet.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showReconciliationStatement(account: Account | null): void {
|
||||||
|
if (!account) {
|
||||||
|
showAlert('An error occurred');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
props.f7router.navigate('/account/reconciliation_statements?accountId=' + account.id);
|
||||||
|
showAccountMoreActionSheet.value = false;
|
||||||
|
accountForMoreActionSheet.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
function hide(account: Account, hidden: boolean): void {
|
function hide(account: Account, hidden: boolean): void {
|
||||||
showLoading();
|
showLoading();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,491 @@
|
|||||||
|
<template>
|
||||||
|
<f7-page @page:afterin="onPageAfterIn">
|
||||||
|
<f7-navbar>
|
||||||
|
<f7-nav-left :back-link="tt('Back')"></f7-nav-left>
|
||||||
|
<f7-nav-title :title="tt('Reconciliation Statement')"></f7-nav-title>
|
||||||
|
<f7-nav-right>
|
||||||
|
<f7-link icon-f7="" v-if="!finishQuery"></f7-link>
|
||||||
|
<f7-link :class="{ 'disabled': !validQuery }" :text="tt('Next')" @click="reload(false)" v-if="!finishQuery"></f7-link>
|
||||||
|
<f7-link style="color: transparent" :text="tt('Next')" v-if="finishQuery"></f7-link>
|
||||||
|
<f7-link :class="{ 'disabled': loading }" icon-f7="ellipsis" v-if="finishQuery" @click="showMoreActionSheet = true"></f7-link>
|
||||||
|
</f7-nav-right>
|
||||||
|
</f7-navbar>
|
||||||
|
|
||||||
|
<f7-list form strong inset dividers class="margin-vertical" v-if="!finishQuery">
|
||||||
|
<f7-list-item :key="dateRange.type"
|
||||||
|
:title="dateRange.displayName"
|
||||||
|
:disabled="!validQuery"
|
||||||
|
v-for="dateRange in allAvailableDateRanges"
|
||||||
|
@click="changeDateFilter(dateRange.type)">
|
||||||
|
<template #after>
|
||||||
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="queryDateRangeType === dateRange.type"></f7-icon>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<div v-if="((dateRange.isBillingCycle || dateRange.type === DateRange.Custom.type) && queryDateRangeType === dateRange.type) && startTime && endTime">
|
||||||
|
<span>{{ displayStartTime }}</span>
|
||||||
|
<span> - </span>
|
||||||
|
<br/>
|
||||||
|
<span>{{ displayEndTime }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical" v-if="finishQuery && !startTime && !endTime">
|
||||||
|
<f7-list-item :title="tt('Date Range')" :after="tt('All')"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical" v-if="finishQuery && (startTime || endTime)">
|
||||||
|
<f7-list-item :title="tt('Start Date')" :after="displayStartDateTime"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('End Date')" :after="displayEndDateTime"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="finishQuery && loading">
|
||||||
|
<f7-list-item :title="tt('Opening Balance')" after="Count"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Closing Balance')" after="Count"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical skeleton-text" v-if="finishQuery && loading">
|
||||||
|
<f7-list-item :title="tt('Total Transactions')" after="Count"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Total Inflows')" after="Count"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Total Outflows')" after="Count"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Net Cash Flow')" after="Count"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical" v-if="finishQuery && !loading">
|
||||||
|
<f7-list-item :title="tt('Opening Balance')" :after="displayOpeningBalance"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Closing Balance')" :after="displayClosingBalance"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical" v-if="finishQuery && !loading">
|
||||||
|
<f7-list-item :title="tt('Total Transactions')" :after="reconciliationStatements.length || '0'"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Total Inflows')" :after="displayTotalInflows"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Total Outflows')" :after="displayTotalOutflows"></f7-list-item>
|
||||||
|
<f7-list-item :title="tt('Net Cash Flow')" :after="displayTotalBalance"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers media-list
|
||||||
|
class="skeleton-text margin-vertical transaction-info-list reconciliation-statement-list"
|
||||||
|
v-if="finishQuery && loading">
|
||||||
|
<ul>
|
||||||
|
<f7-list-item chevron-center media-item
|
||||||
|
:key="index"
|
||||||
|
:class="{ 'transaction-info': type === 't', 'last-transaction-of-day': index === 2, 'reconciliation-statement-transaction-date': type === 'd' }"
|
||||||
|
:link="type === 't' ? '#' : null"
|
||||||
|
v-for="(type, index) in [ 'd', 't', 't', 'd', 't', 't', 't' ]"
|
||||||
|
>
|
||||||
|
<div class="display-flex no-padding-horizontal" v-if="type === 'd'">
|
||||||
|
<div class="actual-item-inner">
|
||||||
|
<div class="item-title-row">
|
||||||
|
<div class="item-title">
|
||||||
|
<small>yyyy-MM-dd</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="display-flex no-padding-horizontal" v-if="type === 't'">
|
||||||
|
<div class="item-media">
|
||||||
|
<div class="transaction-icon display-flex align-items-center">
|
||||||
|
<f7-icon f7="app_fill"></f7-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="actual-item-inner">
|
||||||
|
<div class="item-title-row">
|
||||||
|
<div class="item-title">
|
||||||
|
<div class="transaction-category-name no-padding">
|
||||||
|
<span>Category</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-after">
|
||||||
|
<div class="transaction-amount">
|
||||||
|
<span>0.00 USD</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-text">
|
||||||
|
<div class="transaction-description">
|
||||||
|
<span>Transaction Description</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-footer">
|
||||||
|
<div class="transaction-footer display-flex justify-content-space-between">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<span>HH:mm</span>
|
||||||
|
</div>
|
||||||
|
<div class="account-balance flex-shrink-1">
|
||||||
|
<span>Balance</span>
|
||||||
|
<span style="margin-left: 4px">0.00 USD</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f7-list-item>
|
||||||
|
</ul>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers class="margin-vertical"
|
||||||
|
v-if="finishQuery && !loading && (!allReconciliationStatementVirtualListItems || !allReconciliationStatementVirtualListItems.length)">
|
||||||
|
<f7-list-item :title="tt('No transaction data')"></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<f7-list strong inset dividers media-list virtual-list
|
||||||
|
class="margin-vertical transaction-info-list reconciliation-statement-list"
|
||||||
|
:virtual-list-params="{ items: allReconciliationStatementVirtualListItems, renderExternal, height: 'auto' }"
|
||||||
|
v-if="finishQuery && !loading && allReconciliationStatementVirtualListItems && allReconciliationStatementVirtualListItems.length">
|
||||||
|
<ul>
|
||||||
|
<f7-list-item
|
||||||
|
chevron-center
|
||||||
|
media-item
|
||||||
|
:key="item.index"
|
||||||
|
:class="{ 'transaction-info': item.type == 'transaction', 'last-transaction-of-day': allReconciliationStatementVirtualListItems[item.index + 1] && allReconciliationStatementVirtualListItems[item.index + 1].type === 'date', 'reconciliation-statement-transaction-date': item.type == 'date' }"
|
||||||
|
:style="`top: ${virtualDataItems.topPosition}px`"
|
||||||
|
:virtual-list-index="item.index"
|
||||||
|
:link="item.type == 'transaction' && item.transaction && item.transaction.type !== TransactionType.ModifyBalance ? `/transaction/detail?id=${item.transaction?.id}&type=${item.transaction.type}` : null"
|
||||||
|
v-for="item in virtualDataItems.items"
|
||||||
|
>
|
||||||
|
<div class="display-flex no-padding-horizontal" v-if="item.type == 'date' && item.displayDate">
|
||||||
|
<div class="actual-item-inner">
|
||||||
|
<div class="item-title-row">
|
||||||
|
<div class="item-title">
|
||||||
|
<small>{{ item.displayDate }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="display-flex no-padding-horizontal" v-if="item.type == 'transaction' && item.transaction">
|
||||||
|
<div class="item-media">
|
||||||
|
<div class="transaction-icon display-flex align-items-center">
|
||||||
|
<ItemIcon icon-type="category"
|
||||||
|
:icon-id="allCategoriesMap[item.transaction.categoryId]?.icon"
|
||||||
|
:color="allCategoriesMap[item.transaction.categoryId]?.color"
|
||||||
|
v-if="allCategoriesMap[item.transaction.categoryId] && allCategoriesMap[item.transaction.categoryId]?.color"></ItemIcon>
|
||||||
|
<f7-icon v-else-if="!allCategoriesMap[item.transaction.categoryId] || !allCategoriesMap[item.transaction.categoryId]?.color"
|
||||||
|
f7="pencil_ellipsis_rectangle">
|
||||||
|
</f7-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="actual-item-inner">
|
||||||
|
<div class="item-title-row">
|
||||||
|
<div class="item-title">
|
||||||
|
<div class="transaction-category-name no-padding">
|
||||||
|
<span v-if="item.transaction.type === TransactionType.ModifyBalance">
|
||||||
|
{{ tt('Modify Balance') }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="item.transaction.type !== TransactionType.ModifyBalance && allCategoriesMap[item.transaction.categoryId]">
|
||||||
|
{{ allCategoriesMap[item.transaction.categoryId].name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-after">
|
||||||
|
<div class="transaction-amount"
|
||||||
|
:class="{ 'text-expense': item.transaction.type === TransactionType.Expense, 'text-income': item.transaction.type === TransactionType.Income }">
|
||||||
|
<span v-if="item.transaction.type === TransactionType.Transfer && item.transaction.destinationAccountId === accountId">{{ getDisplayDestinationAmount(item.transaction) }}</span>
|
||||||
|
<span v-else-if="item.transaction.type !== TransactionType.Transfer || item.transaction.destinationAccountId !== accountId">{{ getDisplaySourceAmount(item.transaction) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-text">
|
||||||
|
<div class="transaction-description" v-if="item.transaction.comment">
|
||||||
|
<span>{{ item.transaction.comment }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-footer">
|
||||||
|
<div class="transaction-footer display-flex justify-content-space-between">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<span>{{ getDisplayTime(item.transaction) }}</span>
|
||||||
|
<span v-if="item.transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(item.transaction)})` }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="account-balance flex-shrink-1">
|
||||||
|
<span>{{ isCurrentLiabilityAccount ? tt('Outstanding Balance') : tt('Balance') }}</span>
|
||||||
|
<span style="margin-left: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</f7-list-item>
|
||||||
|
</ul>
|
||||||
|
</f7-list>
|
||||||
|
|
||||||
|
<date-range-selection-sheet :title="tt('Custom Date Range')"
|
||||||
|
:min-time="startTime"
|
||||||
|
:max-time="endTime"
|
||||||
|
v-model:show="showCustomDateRangeSheet"
|
||||||
|
@dateRange:change="changeCustomDateFilter">
|
||||||
|
</date-range-selection-sheet>
|
||||||
|
|
||||||
|
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
||||||
|
<f7-actions-group>
|
||||||
|
<f7-actions-button :class="{ 'disabled': loading }" @click="addTransaction()">{{ tt('Add Transaction') }}</f7-actions-button>
|
||||||
|
</f7-actions-group>
|
||||||
|
<f7-actions-group>
|
||||||
|
<f7-actions-button :class="{ 'disabled': loading }" @click="reload(true)">{{ tt('Refresh') }}</f7-actions-button>
|
||||||
|
</f7-actions-group>
|
||||||
|
<f7-actions-group>
|
||||||
|
<f7-actions-button bold close>{{ tt('Cancel') }}</f7-actions-button>
|
||||||
|
</f7-actions-group>
|
||||||
|
</f7-actions>
|
||||||
|
</f7-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import type { Router } from 'framework7/types';
|
||||||
|
|
||||||
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
|
||||||
|
import { useReconciliationStatementPageBase } from '@/views/base/transactions/ReconciliationStatementPageBase.ts';
|
||||||
|
|
||||||
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
|
|
||||||
|
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||||
|
import { AccountType } from '@/core/account.ts';
|
||||||
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
|
import { type TransactionReconciliationStatementResponseItem } from '@/models/transaction.ts';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getDateTypeByDateRange,
|
||||||
|
getDateTypeByBillingCycleDateRange,
|
||||||
|
getDateRangeByDateType,
|
||||||
|
getDateRangeByBillingCycleDateType
|
||||||
|
} from '@/lib/datetime.ts';
|
||||||
|
|
||||||
|
interface ReconciliationStatementVirtualListData {
|
||||||
|
items: ReconciliationStatementVirtualListItem[],
|
||||||
|
topPosition: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReconciliationStatementVirtualListItem {
|
||||||
|
index: number;
|
||||||
|
type: ReconciliationStatementVirtualListItemType;
|
||||||
|
displayDate?: string;
|
||||||
|
transaction?: TransactionReconciliationStatementResponseItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReconciliationStatementVirtualListItemType = 'transaction' | 'date';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
f7route: Router.Route;
|
||||||
|
f7router: Router.Router;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime } = useI18n();
|
||||||
|
const { showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
|
const {
|
||||||
|
accountId,
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
reconciliationStatements,
|
||||||
|
openingBalance,
|
||||||
|
closingBalance,
|
||||||
|
firstDayOfWeek,
|
||||||
|
fiscalYearStart,
|
||||||
|
currentTimezoneOffsetMinutes,
|
||||||
|
isCurrentLiabilityAccount,
|
||||||
|
allCategoriesMap,
|
||||||
|
currentAccount,
|
||||||
|
displayStartDateTime,
|
||||||
|
displayEndDateTime,
|
||||||
|
displayTotalOutflows,
|
||||||
|
displayTotalInflows,
|
||||||
|
displayTotalBalance,
|
||||||
|
displayOpeningBalance,
|
||||||
|
displayClosingBalance,
|
||||||
|
getDisplayDate,
|
||||||
|
getDisplayTime,
|
||||||
|
getDisplayTimezone,
|
||||||
|
getDisplaySourceAmount,
|
||||||
|
getDisplayDestinationAmount,
|
||||||
|
getDisplayAccountBalance
|
||||||
|
} = useReconciliationStatementPageBase();
|
||||||
|
|
||||||
|
const accountsStore = useAccountsStore();
|
||||||
|
const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||||
|
const transactionsStore = useTransactionsStore();
|
||||||
|
|
||||||
|
const finishQuery = ref<boolean>(false);
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
const loadingError = ref<unknown | null>(null);
|
||||||
|
const queryDateRangeType = ref<number>(DateRange.ThisMonth.type);
|
||||||
|
const showCustomDateRangeSheet = ref<boolean>(false);
|
||||||
|
const showMoreActionSheet = ref<boolean>(false);
|
||||||
|
const virtualDataItems = ref<ReconciliationStatementVirtualListData>({
|
||||||
|
items: [],
|
||||||
|
topPosition: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
|
||||||
|
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
|
||||||
|
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
|
||||||
|
const displayEndTime = computed<string>(() => formatUnixTimeToLongDateTime(endTime.value));
|
||||||
|
|
||||||
|
const allReconciliationStatementVirtualListItems = computed<ReconciliationStatementVirtualListItem[]>(() => {
|
||||||
|
const ret: ReconciliationStatementVirtualListItem[] = [];
|
||||||
|
|
||||||
|
if (!reconciliationStatements.value || reconciliationStatements.value.length < 1) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
let lastDisplayDate: string | null = null;
|
||||||
|
|
||||||
|
for (let i = 0; i < reconciliationStatements.value.length; i++) {
|
||||||
|
const transaction = reconciliationStatements.value[i];
|
||||||
|
const displayDate = getDisplayDate(transaction);
|
||||||
|
|
||||||
|
if (lastDisplayDate !== displayDate) {
|
||||||
|
lastDisplayDate = displayDate;
|
||||||
|
ret.push({
|
||||||
|
index: index++,
|
||||||
|
type: 'date',
|
||||||
|
displayDate: displayDate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push({
|
||||||
|
index: index++,
|
||||||
|
type: 'transaction',
|
||||||
|
transaction: transaction
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
function init(): void {
|
||||||
|
const query = props.f7route.query;
|
||||||
|
const defaultDateRange = getDateRangeByDateType(queryDateRangeType.value, firstDayOfWeek.value, fiscalYearStart.value);
|
||||||
|
|
||||||
|
finishQuery.value = false;
|
||||||
|
loading.value = false;
|
||||||
|
accountId.value = query['accountId'] || '';
|
||||||
|
startTime.value = defaultDateRange?.minTime || 0;
|
||||||
|
endTime.value = defaultDateRange?.maxTime || 0;
|
||||||
|
reconciliationStatements.value = [];
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
accountsStore.loadAllAccounts({ force: false }),
|
||||||
|
transactionCategoriesStore.loadAllCategories({ force: false })
|
||||||
|
]).catch(error => {
|
||||||
|
loadingError.value = error;
|
||||||
|
showToast(error.message || error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeDateFilter(dateRangeType: number): void {
|
||||||
|
if (dateRangeType === DateRange.Custom.type) {
|
||||||
|
showCustomDateRangeSheet.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dateRange: TimeRangeAndDateType | null = null;
|
||||||
|
|
||||||
|
if (DateRange.isBillingCycle(dateRangeType)) {
|
||||||
|
dateRange = getDateRangeByBillingCycleDateType(dateRangeType, firstDayOfWeek.value, fiscalYearStart.value, accountsStore.getAccountStatementDate(accountId.value));
|
||||||
|
} else {
|
||||||
|
dateRange = getDateRangeByDateType(dateRangeType, firstDayOfWeek.value, fiscalYearStart.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dateRange) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queryDateRangeType.value = dateRange.dateType;
|
||||||
|
startTime.value = dateRange.minTime;
|
||||||
|
endTime.value = dateRange.maxTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeCustomDateFilter(minTime: number, maxTime: number): void {
|
||||||
|
if (!minTime || !maxTime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let dateType: number | null = getDateTypeByBillingCycleDateRange(minTime, maxTime, firstDayOfWeek.value, fiscalYearStart.value, DateRangeScene.Normal, accountsStore.getAccountStatementDate(accountId.value));
|
||||||
|
|
||||||
|
if (!dateType) {
|
||||||
|
dateType = getDateTypeByDateRange(minTime, maxTime, firstDayOfWeek.value, fiscalYearStart.value, DateRangeScene.Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
queryDateRangeType.value = dateType;
|
||||||
|
startTime.value = minTime;
|
||||||
|
endTime.value = maxTime;
|
||||||
|
showCustomDateRangeSheet.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reload(force: boolean): void {
|
||||||
|
finishQuery.value = true;
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
transactionsStore.getReconciliationStatements({
|
||||||
|
accountId: accountId.value,
|
||||||
|
startTime: startTime.value,
|
||||||
|
endTime: endTime.value
|
||||||
|
}).then(result => {
|
||||||
|
if (force) {
|
||||||
|
showToast('Data has been updated');
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = false;
|
||||||
|
reconciliationStatements.value = result.transactions;
|
||||||
|
openingBalance.value = result.openingBalance;
|
||||||
|
closingBalance.value = result.closingBalance;
|
||||||
|
}).catch(error => {
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if (!error.processed) {
|
||||||
|
showToast(error.message || error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTransaction(): void {
|
||||||
|
props.f7router.navigate(`/transaction/add?accountId=${accountId.value}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderExternal(vl: unknown, vlData: ReconciliationStatementVirtualListData): void {
|
||||||
|
virtualDataItems.value = vlData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPageAfterIn(): void {
|
||||||
|
routeBackOnError(props.f7router, loadingError);
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date:first-child {
|
||||||
|
border-radius: var(--f7-list-inset-border-radius) var(--f7-list-inset-border-radius) 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date {
|
||||||
|
background-color: var(--f7-list-group-title-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner {
|
||||||
|
padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
|
||||||
|
}
|
||||||
|
|
||||||
|
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner:after {
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list.reconciliation-statement-list li.transaction-info.last-transaction-of-day > .item-link > .item-content > .item-inner:after {
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list.reconciliation-statement-list li.transaction-info .account-balance {
|
||||||
|
margin-left: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user