Show symbol for accounts that haven't been recently reconciled #33
@ -5,6 +5,7 @@ package postgres
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.javil.eu/jacob1123/budgeteer/postgres/numeric"
|
"git.javil.eu/jacob1123/budgeteer/postgres/numeric"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -87,6 +88,7 @@ func (q *Queries) GetAccounts(ctx context.Context, budgetID uuid.UUID) ([]Accoun
|
|||||||
|
|
||||||
const getAccountsWithBalance = `-- name: GetAccountsWithBalance :many
|
const getAccountsWithBalance = `-- name: GetAccountsWithBalance :many
|
||||||
SELECT accounts.id, accounts.name, accounts.on_budget,
|
SELECT accounts.id, accounts.name, accounts.on_budget,
|
||||||
|
(SELECT MAX(transactions.date) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.status = 'Reconciled')::date as last_reconciled,
|
||||||
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW())::decimal(12,2) as working_balance,
|
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW())::decimal(12,2) as working_balance,
|
||||||
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status IN ('Cleared', 'Reconciled'))::decimal(12,2) as cleared_balance,
|
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status IN ('Cleared', 'Reconciled'))::decimal(12,2) as cleared_balance,
|
||||||
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status = 'Reconciled')::decimal(12,2) as reconciled_balance
|
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status = 'Reconciled')::decimal(12,2) as reconciled_balance
|
||||||
@ -99,6 +101,7 @@ type GetAccountsWithBalanceRow struct {
|
|||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
Name string
|
Name string
|
||||||
OnBudget bool
|
OnBudget bool
|
||||||
|
LastReconciled time.Time
|
||||||
WorkingBalance numeric.Numeric
|
WorkingBalance numeric.Numeric
|
||||||
ClearedBalance numeric.Numeric
|
ClearedBalance numeric.Numeric
|
||||||
ReconciledBalance numeric.Numeric
|
ReconciledBalance numeric.Numeric
|
||||||
@ -117,6 +120,7 @@ func (q *Queries) GetAccountsWithBalance(ctx context.Context, budgetID uuid.UUID
|
|||||||
&i.ID,
|
&i.ID,
|
||||||
&i.Name,
|
&i.Name,
|
||||||
&i.OnBudget,
|
&i.OnBudget,
|
||||||
|
&i.LastReconciled,
|
||||||
&i.WorkingBalance,
|
&i.WorkingBalance,
|
||||||
&i.ClearedBalance,
|
&i.ClearedBalance,
|
||||||
&i.ReconciledBalance,
|
&i.ReconciledBalance,
|
||||||
|
@ -15,6 +15,7 @@ ORDER BY accounts.name;
|
|||||||
|
|
||||||
-- name: GetAccountsWithBalance :many
|
-- name: GetAccountsWithBalance :many
|
||||||
SELECT accounts.id, accounts.name, accounts.on_budget,
|
SELECT accounts.id, accounts.name, accounts.on_budget,
|
||||||
|
(SELECT MAX(transactions.date) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.status = 'Reconciled')::date as last_reconciled,
|
||||||
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW())::decimal(12,2) as working_balance,
|
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW())::decimal(12,2) as working_balance,
|
||||||
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status IN ('Cleared', 'Reconciled'))::decimal(12,2) as cleared_balance,
|
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status IN ('Cleared', 'Reconciled'))::decimal(12,2) as cleared_balance,
|
||||||
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status = 'Reconciled')::decimal(12,2) as reconciled_balance
|
(SELECT SUM(transactions.amount) FROM transactions WHERE transactions.account_id = accounts.id AND transactions.date < NOW() AND transactions.status = 'Reconciled')::decimal(12,2) as reconciled_balance
|
||||||
|
@ -41,25 +41,25 @@ function createReconcilationTransaction() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="grid grid-cols-2">
|
<div class="grid grid-cols-[1fr_auto]">
|
||||||
<h1 class="inline">
|
<h1 class="inline">
|
||||||
{{ accounts.CurrentAccount?.Name }}
|
{{ accounts.CurrentAccount?.Name }}
|
||||||
<EditAccount />
|
<EditAccount />
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right flex flex-wrap flex-col md:flex-row justify-end gap-2 max-w-sm">
|
||||||
<span class="border-2 rounded-lg p-1 whitespace-nowrap">
|
<span class="border-2 rounded-lg p-1 whitespace-nowrap flex-1">
|
||||||
Working:
|
Working:
|
||||||
<Currency :value="accounts.CurrentAccount?.WorkingBalance" />
|
<Currency :value="accounts.CurrentAccount?.WorkingBalance" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="border-2 rounded-lg p-1 ml-2 whitespace-nowrap">
|
<span class="border-2 rounded-lg p-1 whitespace-nowrap flex-1">
|
||||||
Cleared:
|
Cleared:
|
||||||
<Currency :value="accounts.CurrentAccount?.ClearedBalance" />
|
<Currency :value="accounts.CurrentAccount?.ClearedBalance" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="border-2 border-blue-500 rounded-lg bg-blue-500 ml-2 p-1 whitespace-nowrap"
|
class="border-2 border-blue-500 rounded-lg bg-blue-500 p-1 whitespace-nowrap flex-1"
|
||||||
v-if="!transactions.Reconciling"
|
v-if="!transactions.Reconciling"
|
||||||
@click="transactions.Reconciling = true"
|
@click="transactions.Reconciling = true"
|
||||||
>
|
>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import Currency from "../components/Currency.vue"
|
import Currency from "../components/Currency.vue"
|
||||||
import { useBudgetsStore } from "../stores/budget"
|
import { useBudgetsStore } from "../stores/budget"
|
||||||
import { useAccountStore } from "../stores/budget-account"
|
import { Account, useAccountStore } from "../stores/budget-account"
|
||||||
import { useSettingsStore } from "../stores/settings"
|
import { useSettingsStore } from "../stores/settings"
|
||||||
|
|
||||||
const ExpandMenu = computed(() => useSettingsStore().Menu.Expand);
|
const ExpandMenu = computed(() => useSettingsStore().Menu.Expand);
|
||||||
@ -16,6 +16,18 @@ const OnBudgetAccounts = computed(() => accountStore.OnBudgetAccounts);
|
|||||||
const OffBudgetAccounts = computed(() => accountStore.OffBudgetAccounts);
|
const OffBudgetAccounts = computed(() => accountStore.OffBudgetAccounts);
|
||||||
const OnBudgetAccountsBalance = computed(() => accountStore.OnBudgetAccountsBalance);
|
const OnBudgetAccountsBalance = computed(() => accountStore.OnBudgetAccountsBalance);
|
||||||
const OffBudgetAccountsBalance = computed(() => accountStore.OffBudgetAccountsBalance);
|
const OffBudgetAccountsBalance = computed(() => accountStore.OffBudgetAccountsBalance);
|
||||||
|
|
||||||
|
function isRecentlyReconciled(account : Account) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const recently = 7 * 24 * 60 * 60 * 1000;
|
||||||
|
console.log(account.Name, account.LastReconciled, now, recently, new Date(now-recently));
|
||||||
|
return new Date(now - recently).getTime() < account.LastReconciled.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAccountName(account : Account) {
|
||||||
|
const reconciledMarker = isRecentlyReconciled(account) ? "" : " *";
|
||||||
|
return account.Name + reconciledMarker;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -35,7 +47,7 @@ const OffBudgetAccountsBalance = computed(() => accountStore.OffBudgetAccountsBa
|
|||||||
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="OnBudgetAccountsBalance" />
|
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="OnBudgetAccountsBalance" />
|
||||||
</div>
|
</div>
|
||||||
<div v-for="account in OnBudgetAccounts" class="flex flex-row justify-between">
|
<div v-for="account in OnBudgetAccounts" class="flex flex-row justify-between">
|
||||||
<router-link :to="'/budget/'+CurrentBudgetID+'/account/'+account.ID">{{account.Name}}</router-link>
|
<router-link :to="'/budget/'+CurrentBudgetID+'/account/'+account.ID">{{getAccountName(account)}}</router-link>
|
||||||
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="account.ClearedBalance" />
|
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="account.ClearedBalance" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -45,7 +57,7 @@ const OffBudgetAccountsBalance = computed(() => accountStore.OffBudgetAccountsBa
|
|||||||
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="OffBudgetAccountsBalance" />
|
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="OffBudgetAccountsBalance" />
|
||||||
</div>
|
</div>
|
||||||
<div v-for="account in OffBudgetAccounts" class="flex flex-row justify-between">
|
<div v-for="account in OffBudgetAccounts" class="flex flex-row justify-between">
|
||||||
<router-link :to="'/budget/'+CurrentBudgetID+'/account/'+account.ID">{{account.Name}}</router-link>
|
<router-link :to="'/budget/'+CurrentBudgetID+'/account/'+account.ID">{{getAccountName(account)}}</router-link>
|
||||||
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="account.ClearedBalance" />
|
<Currency :class="ExpandMenu?'md:inline':'md:hidden'" :value="account.ClearedBalance" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@ -20,6 +20,7 @@ export interface Account {
|
|||||||
WorkingBalance: number
|
WorkingBalance: number
|
||||||
ReconciledBalance: number
|
ReconciledBalance: number
|
||||||
Transactions: string[]
|
Transactions: string[]
|
||||||
|
LastReconciled: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Category {
|
export interface Category {
|
||||||
|
@ -58,6 +58,7 @@ export const useBudgetsStore = defineStore('budget', {
|
|||||||
for (const account of response.Accounts || []) {
|
for (const account of response.Accounts || []) {
|
||||||
const existingAccount = accounts.Accounts.get(account.ID);
|
const existingAccount = accounts.Accounts.get(account.ID);
|
||||||
account.Transactions = existingAccount?.Transactions ?? [];
|
account.Transactions = existingAccount?.Transactions ?? [];
|
||||||
|
account.LastReconciled = new Date(account.LastReconciled);
|
||||||
accounts.Accounts.set(account.ID, account);
|
accounts.Accounts.set(account.ID, account);
|
||||||
}
|
}
|
||||||
for (const category of response.Categories || []) {
|
for (const category of response.Categories || []) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user