From 43a4647d7442051575b4aec4f649279c28207eb8 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Fri, 22 Apr 2022 18:31:31 +0000 Subject: [PATCH 01/16] Add query to find problematic transactions --- postgres/queries/transactions.sql | 17 ++++- postgres/transactions.sql.go | 104 ++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/postgres/queries/transactions.sql b/postgres/queries/transactions.sql index 2376d0b..3e9c9d6 100644 --- a/postgres/queries/transactions.sql +++ b/postgres/queries/transactions.sql @@ -45,4 +45,19 @@ AND accounts.id = transactions.account_id; -- name: GetTransactionsByMonthAndCategory :many SELECT * FROM transactions_by_month -WHERE transactions_by_month.budget_id = @budget_id; \ No newline at end of file +WHERE transactions_by_month.budget_id = @budget_id; + +-- name: GetProblematicTransactions :many +SELECT * +FROM transactions +LEFT JOIN accounts + ON transactions.account_id = accounts.id +LEFT JOIN transactions AS otherGroupTransaction + ON transactions.group_id = otherGroupTransaction.group_id + AND transactions.id != otherGroupTransaction.id + AND transactions.account_id != otherGroupTransaction.account_id +LEFT JOIn accounts AS otherGroupAccount + ON otherGroupTransaction.account_id = accounts.id +WHERE transactions.category_id IS NULL +AND accounts.on_budget +AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget); \ No newline at end of file diff --git a/postgres/transactions.sql.go b/postgres/transactions.sql.go index cdab72a..9b720c1 100644 --- a/postgres/transactions.sql.go +++ b/postgres/transactions.sql.go @@ -7,6 +7,7 @@ package postgres import ( "context" + "database/sql" "time" "git.javil.eu/jacob1123/budgeteer/postgres/numeric" @@ -117,6 +118,109 @@ func (q *Queries) GetAllTransactionsForBudget(ctx context.Context, budgetID uuid return items, nil } +const getProblematicTransactions = `-- name: GetProblematicTransactions :many +SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.account_id, transactions.category_id, transactions.payee_id, transactions.group_id, transactions.status, accounts.id, accounts.budget_id, accounts.name, accounts.on_budget, accounts.is_open, accounts.last_reconciled, othergrouptransaction.id, othergrouptransaction.date, othergrouptransaction.memo, othergrouptransaction.amount, othergrouptransaction.account_id, othergrouptransaction.category_id, othergrouptransaction.payee_id, othergrouptransaction.group_id, othergrouptransaction.status, othergroupaccount.id, othergroupaccount.budget_id, othergroupaccount.name, othergroupaccount.on_budget, othergroupaccount.is_open, othergroupaccount.last_reconciled +FROM transactions +LEFT JOIN accounts + ON transactions.account_id = accounts.id +LEFT JOIN transactions AS otherGroupTransaction + ON transactions.group_id = otherGroupTransaction.group_id + AND transactions.id != otherGroupTransaction.id + AND transactions.account_id != otherGroupTransaction.account_id +LEFT JOIn accounts AS otherGroupAccount + ON otherGroupTransaction.account_id = accounts.id +WHERE transactions.category_id IS NULL +AND accounts.on_budget +AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget) +` + +type GetProblematicTransactionsRow struct { + ID uuid.UUID + Date time.Time + Memo string + Amount numeric.Numeric + AccountID uuid.UUID + CategoryID uuid.NullUUID + PayeeID uuid.NullUUID + GroupID uuid.NullUUID + Status TransactionStatus + ID_2 uuid.NullUUID + BudgetID uuid.NullUUID + Name sql.NullString + OnBudget sql.NullBool + IsOpen sql.NullBool + LastReconciled sql.NullTime + ID_3 uuid.UUID + Date_2 time.Time + Memo_2 string + Amount_2 numeric.Numeric + AccountID_2 uuid.UUID + CategoryID_2 uuid.NullUUID + PayeeID_2 uuid.NullUUID + GroupID_2 uuid.NullUUID + Status_2 TransactionStatus + ID_4 uuid.NullUUID + BudgetID_2 uuid.NullUUID + Name_2 sql.NullString + OnBudget_2 sql.NullBool + IsOpen_2 sql.NullBool + LastReconciled_2 sql.NullTime +} + +func (q *Queries) GetProblematicTransactions(ctx context.Context) ([]GetProblematicTransactionsRow, error) { + rows, err := q.db.QueryContext(ctx, getProblematicTransactions) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetProblematicTransactionsRow + for rows.Next() { + var i GetProblematicTransactionsRow + if err := rows.Scan( + &i.ID, + &i.Date, + &i.Memo, + &i.Amount, + &i.AccountID, + &i.CategoryID, + &i.PayeeID, + &i.GroupID, + &i.Status, + &i.ID_2, + &i.BudgetID, + &i.Name, + &i.OnBudget, + &i.IsOpen, + &i.LastReconciled, + &i.ID_3, + &i.Date_2, + &i.Memo_2, + &i.Amount_2, + &i.AccountID_2, + &i.CategoryID_2, + &i.PayeeID_2, + &i.GroupID_2, + &i.Status_2, + &i.ID_4, + &i.BudgetID_2, + &i.Name_2, + &i.OnBudget_2, + &i.IsOpen_2, + &i.LastReconciled_2, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const getTransaction = `-- name: GetTransaction :one SELECT id, date, memo, amount, group_id, status, account, payee_id, category_id, payee, category_group, category, transfer_account, budget_id, account_id FROM display_transactions WHERE id = $1 From 07c0c56d11d3b3f7457f1142da5c3524fef005a2 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Fri, 22 Apr 2022 18:33:32 +0000 Subject: [PATCH 02/16] Add budgetID param --- postgres/queries/transactions.sql | 3 ++- postgres/transactions.sql.go | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/postgres/queries/transactions.sql b/postgres/queries/transactions.sql index 3e9c9d6..545e09c 100644 --- a/postgres/queries/transactions.sql +++ b/postgres/queries/transactions.sql @@ -60,4 +60,5 @@ LEFT JOIn accounts AS otherGroupAccount ON otherGroupTransaction.account_id = accounts.id WHERE transactions.category_id IS NULL AND accounts.on_budget -AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget); \ No newline at end of file +AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget) +AND accounts.budget_id = $1; \ No newline at end of file diff --git a/postgres/transactions.sql.go b/postgres/transactions.sql.go index 9b720c1..067f607 100644 --- a/postgres/transactions.sql.go +++ b/postgres/transactions.sql.go @@ -132,6 +132,7 @@ LEFT JOIn accounts AS otherGroupAccount WHERE transactions.category_id IS NULL AND accounts.on_budget AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget) +AND accounts.budget_id = $1 ` type GetProblematicTransactionsRow struct { @@ -167,8 +168,8 @@ type GetProblematicTransactionsRow struct { LastReconciled_2 sql.NullTime } -func (q *Queries) GetProblematicTransactions(ctx context.Context) ([]GetProblematicTransactionsRow, error) { - rows, err := q.db.QueryContext(ctx, getProblematicTransactions) +func (q *Queries) GetProblematicTransactions(ctx context.Context, budgetID uuid.UUID) ([]GetProblematicTransactionsRow, error) { + rows, err := q.db.QueryContext(ctx, getProblematicTransactions, budgetID) if err != nil { return nil, err } From 777520e9df0fe6daee77fc7768bc6bb13e897fce Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Fri, 22 Apr 2022 18:39:28 +0000 Subject: [PATCH 03/16] Simplify query --- postgres/queries/transactions.sql | 6 +-- postgres/transactions.sql.go | 77 ++++++------------------------- 2 files changed, 17 insertions(+), 66 deletions(-) diff --git a/postgres/queries/transactions.sql b/postgres/queries/transactions.sql index 545e09c..aebc7ff 100644 --- a/postgres/queries/transactions.sql +++ b/postgres/queries/transactions.sql @@ -48,8 +48,8 @@ FROM transactions_by_month WHERE transactions_by_month.budget_id = @budget_id; -- name: GetProblematicTransactions :many -SELECT * -FROM transactions +SELECT transactions.* +FROM display_transactions AS transactions LEFT JOIN accounts ON transactions.account_id = accounts.id LEFT JOIN transactions AS otherGroupTransaction @@ -57,7 +57,7 @@ LEFT JOIN transactions AS otherGroupTransaction AND transactions.id != otherGroupTransaction.id AND transactions.account_id != otherGroupTransaction.account_id LEFT JOIn accounts AS otherGroupAccount - ON otherGroupTransaction.account_id = accounts.id + ON otherGroupTransaction.account_id = otherGroupAccount.id WHERE transactions.category_id IS NULL AND accounts.on_budget AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget) diff --git a/postgres/transactions.sql.go b/postgres/transactions.sql.go index 067f607..60fcf1d 100644 --- a/postgres/transactions.sql.go +++ b/postgres/transactions.sql.go @@ -7,7 +7,6 @@ package postgres import ( "context" - "database/sql" "time" "git.javil.eu/jacob1123/budgeteer/postgres/numeric" @@ -119,8 +118,8 @@ func (q *Queries) GetAllTransactionsForBudget(ctx context.Context, budgetID uuid } const getProblematicTransactions = `-- name: GetProblematicTransactions :many -SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.account_id, transactions.category_id, transactions.payee_id, transactions.group_id, transactions.status, accounts.id, accounts.budget_id, accounts.name, accounts.on_budget, accounts.is_open, accounts.last_reconciled, othergrouptransaction.id, othergrouptransaction.date, othergrouptransaction.memo, othergrouptransaction.amount, othergrouptransaction.account_id, othergrouptransaction.category_id, othergrouptransaction.payee_id, othergrouptransaction.group_id, othergrouptransaction.status, othergroupaccount.id, othergroupaccount.budget_id, othergroupaccount.name, othergroupaccount.on_budget, othergroupaccount.is_open, othergroupaccount.last_reconciled -FROM transactions +SELECT transactions.id, transactions.date, transactions.memo, transactions.amount, transactions.group_id, transactions.status, transactions.account, transactions.payee_id, transactions.category_id, transactions.payee, transactions.category_group, transactions.category, transactions.transfer_account, transactions.budget_id, transactions.account_id +FROM display_transactions AS transactions LEFT JOIN accounts ON transactions.account_id = accounts.id LEFT JOIN transactions AS otherGroupTransaction @@ -128,86 +127,38 @@ LEFT JOIN transactions AS otherGroupTransaction AND transactions.id != otherGroupTransaction.id AND transactions.account_id != otherGroupTransaction.account_id LEFT JOIn accounts AS otherGroupAccount - ON otherGroupTransaction.account_id = accounts.id + ON otherGroupTransaction.account_id = otherGroupAccount.id WHERE transactions.category_id IS NULL AND accounts.on_budget AND (otherGroupAccount.id IS NULL OR NOT otherGroupAccount.on_budget) AND accounts.budget_id = $1 ` -type GetProblematicTransactionsRow struct { - ID uuid.UUID - Date time.Time - Memo string - Amount numeric.Numeric - AccountID uuid.UUID - CategoryID uuid.NullUUID - PayeeID uuid.NullUUID - GroupID uuid.NullUUID - Status TransactionStatus - ID_2 uuid.NullUUID - BudgetID uuid.NullUUID - Name sql.NullString - OnBudget sql.NullBool - IsOpen sql.NullBool - LastReconciled sql.NullTime - ID_3 uuid.UUID - Date_2 time.Time - Memo_2 string - Amount_2 numeric.Numeric - AccountID_2 uuid.UUID - CategoryID_2 uuid.NullUUID - PayeeID_2 uuid.NullUUID - GroupID_2 uuid.NullUUID - Status_2 TransactionStatus - ID_4 uuid.NullUUID - BudgetID_2 uuid.NullUUID - Name_2 sql.NullString - OnBudget_2 sql.NullBool - IsOpen_2 sql.NullBool - LastReconciled_2 sql.NullTime -} - -func (q *Queries) GetProblematicTransactions(ctx context.Context, budgetID uuid.UUID) ([]GetProblematicTransactionsRow, error) { +func (q *Queries) GetProblematicTransactions(ctx context.Context, budgetID uuid.UUID) ([]DisplayTransaction, error) { rows, err := q.db.QueryContext(ctx, getProblematicTransactions, budgetID) if err != nil { return nil, err } defer rows.Close() - var items []GetProblematicTransactionsRow + var items []DisplayTransaction for rows.Next() { - var i GetProblematicTransactionsRow + var i DisplayTransaction if err := rows.Scan( &i.ID, &i.Date, &i.Memo, &i.Amount, - &i.AccountID, - &i.CategoryID, - &i.PayeeID, &i.GroupID, &i.Status, - &i.ID_2, + &i.Account, + &i.PayeeID, + &i.CategoryID, + &i.Payee, + &i.CategoryGroup, + &i.Category, + &i.TransferAccount, &i.BudgetID, - &i.Name, - &i.OnBudget, - &i.IsOpen, - &i.LastReconciled, - &i.ID_3, - &i.Date_2, - &i.Memo_2, - &i.Amount_2, - &i.AccountID_2, - &i.CategoryID_2, - &i.PayeeID_2, - &i.GroupID_2, - &i.Status_2, - &i.ID_4, - &i.BudgetID_2, - &i.Name_2, - &i.OnBudget_2, - &i.IsOpen_2, - &i.LastReconciled_2, + &i.AccountID, ); err != nil { return nil, err } From 44254ed4d0d3648637794850e1ba0309e6fe8624 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Fri, 22 Apr 2022 20:50:52 +0000 Subject: [PATCH 04/16] Group transactions by date to simplify grouping in UI --- web/src/components/TransactionRow.vue | 20 -------------------- web/src/date.ts | 9 +++++++++ web/src/pages/Account.vue | 22 ++++++++++++++++------ web/src/stores/budget-account.ts | 3 +-- web/src/stores/transactions.ts | 19 ++++++++++++------- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/web/src/components/TransactionRow.vue b/web/src/components/TransactionRow.vue index 82320e4..48799e1 100644 --- a/web/src/components/TransactionRow.vue +++ b/web/src/components/TransactionRow.vue @@ -21,19 +21,6 @@ const Reconciling = computed(() => useTransactionsStore().Reconciling); const transactionsStore = useTransactionsStore(); const TX = transactionsStore.Transactions.get(props.transactionid)!; -function dateChanged() { - const currentAccount = useAccountStore().CurrentAccount; - if (currentAccount == null) - return true; - const transactionIndex = currentAccount.Transactions.indexOf(props.transactionid); - if(transactionIndex<=0) - return true; - - const previousTransactionId = currentAccount.Transactions[transactionIndex-1]; - const previousTransaction = transactionsStore.Transactions.get(previousTransactionId); - return TX.Date.getTime() != previousTransaction?.Date.getTime(); -} - function getStatusSymbol() { if(TX.Status == "Reconciled") return "✔"; @@ -46,13 +33,6 @@ function getStatusSymbol() { From f56d09501613388ac616f70a01bf49cb5731a9f8 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Fri, 22 Apr 2022 20:57:41 +0000 Subject: [PATCH 06/16] Reintroduce alternating row-colors by date --- web/src/components/TransactionRow.vue | 1 + web/src/pages/Account.vue | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/components/TransactionRow.vue b/web/src/components/TransactionRow.vue index e3a56e4..3b34168 100644 --- a/web/src/components/TransactionRow.vue +++ b/web/src/components/TransactionRow.vue @@ -36,6 +36,7 @@ function getStatusSymbol() { {{ formatDate(TX.Date) }} diff --git a/web/src/pages/Account.vue b/web/src/pages/Account.vue index c5f070f..ab67e29 100644 --- a/web/src/pages/Account.vue +++ b/web/src/pages/Account.vue @@ -145,11 +145,11 @@ function createReconcilationTransaction() { :budgetid="budgetid" :accountid="accountid" /> - From 8f99499c2f5aa3ff43b7cb8d3018ce48aebf6050 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Sat, 23 Apr 2022 10:49:03 +0000 Subject: [PATCH 11/16] Hide Index when logged in --- web/src/router/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/src/router/index.ts b/web/src/router/index.ts index d858949..26504d8 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -14,7 +14,12 @@ import Settings from "../pages/Settings.vue"; import WelcomePage from "../pages/WelcomePage.vue"; const routes = [ - { path: "/", name: "Index", component: WelcomePage }, + { + path: "/", + name: "Index", + component: WelcomePage, + meta: { hideForAuth: true }, + }, { path: "/dashboard", name: "Dashboard", From cfb1dbe276be027a38ea8a8e3ac1d7197680af2f Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Sat, 23 Apr 2022 10:59:07 +0000 Subject: [PATCH 12/16] Rename menu to problematic transactions --- web/src/pages/AllAccounts.vue | 2 +- web/src/pages/BudgetSidebar.vue | 2 +- web/src/router/index.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/src/pages/AllAccounts.vue b/web/src/pages/AllAccounts.vue index 244ec92..fc722f8 100644 --- a/web/src/pages/AllAccounts.vue +++ b/web/src/pages/AllAccounts.vue @@ -34,7 +34,7 @@ onMounted(() => {

- All Accounts + Problematic Transactions

diff --git a/web/src/pages/BudgetSidebar.vue b/web/src/pages/BudgetSidebar.vue index bf7cfb3..4e3679e 100644 --- a/web/src/pages/BudgetSidebar.vue +++ b/web/src/pages/BudgetSidebar.vue @@ -40,7 +40,7 @@ function toggleMenu() { Budget
- All Accounts + Problematic Transactions
  • diff --git a/web/src/router/index.ts b/web/src/router/index.ts index 26504d8..61bab6f 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -65,8 +65,8 @@ const routes = [ meta: { requiresAuth: true }, }, { - path: "/budget/:budgetid/all-accounts", - name: "All Accounts", + path: "/budget/:budgetid/problematic-transactions", + name: "Problematic Transactions", components: { default: AllAccounts, sidebar: BudgetSidebar }, props: true, meta: { requiresAuth: true }, From 4fa227c4528ad7dace290b024437c366c49b6180 Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Sat, 23 Apr 2022 11:05:07 +0000 Subject: [PATCH 13/16] ESLINT --- .vscode/settings.json | 4 +++- web/.eslintrc.js | 3 ++- web/src/components/MainMenu.vue | 38 ++++++++++++++++----------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1820a53..b41677f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,7 @@ }, "gopls": { "formatting.gofumpt": true, - } + }, + "editor.detectIndentation": false, + "editor.tabSize": 2 } \ No newline at end of file diff --git a/web/.eslintrc.js b/web/.eslintrc.js index 60afd68..fa71bf5 100644 --- a/web/.eslintrc.js +++ b/web/.eslintrc.js @@ -7,7 +7,8 @@ module.exports = { ], rules: { // override/add rules settings here, such as: - 'vue/max-attributes-per-line': 'off' + 'vue/max-attributes-per-line': 'off', + 'vue/singleline-html-element-content-newline': 'off', // 'vue/no-unused-vars': 'error' }, parser: "vue-eslint-parser", diff --git a/web/src/components/MainMenu.vue b/web/src/components/MainMenu.vue index 49dc2ee..9ea4820 100644 --- a/web/src/components/MainMenu.vue +++ b/web/src/components/MainMenu.vue @@ -10,37 +10,35 @@ const router = useRouter(); const CurrentBudgetName = computed(() => useBudgetsStore().CurrentBudgetName); const LoggedIn = computed(() => useSessionStore().LoggedIn); function logout() { - useSessionStore().logout(); - router.push("/login"); + useSessionStore().logout(); + router.push("/login"); } function toggleMenu() { - useSettingsStore().toggleMenu(); + useSettingsStore().toggleMenu(); } function toggleMenuSize() { - useSettingsStore().toggleMenuSize(); + useSettingsStore().toggleMenuSize(); } router.afterEach(function(to, from) { - useSettingsStore().Menu.Show = false; + useSettingsStore().Menu.Show = false; }) From c30b33a070ab7a6ce3190ea9e4abf3daf95208bb Mon Sep 17 00:00:00 2001 From: Jan Bader Date: Sat, 23 Apr 2022 11:12:35 +0000 Subject: [PATCH 14/16] ESLINT 2 --- web/.eslintrc.js | 2 ++ web/src/components/TransactionRow.vue | 4 ++-- web/src/pages/Account.vue | 2 +- web/src/pages/AllAccounts.vue | 2 +- web/src/pages/BudgetSidebar.vue | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/web/.eslintrc.js b/web/.eslintrc.js index fa71bf5..3aa8946 100644 --- a/web/.eslintrc.js +++ b/web/.eslintrc.js @@ -9,6 +9,8 @@ module.exports = { // override/add rules settings here, such as: 'vue/max-attributes-per-line': 'off', 'vue/singleline-html-element-content-newline': 'off', + 'vue/first-attribute-linebreak': 'off', + 'vue/html-closing-bracket-newline': 'off', // 'vue/no-unused-vars': 'error' }, parser: "vue-eslint-parser", diff --git a/web/src/components/TransactionRow.vue b/web/src/components/TransactionRow.vue index 84b1bc1..0ebebd5 100644 --- a/web/src/components/TransactionRow.vue +++ b/web/src/components/TransactionRow.vue @@ -42,7 +42,7 @@ function getStatusSymbol() { {{ formatDate(TX.Date) }} - + {{ TX.Account }} @@ -75,7 +75,7 @@ function getStatusSymbol() { diff --git a/web/src/pages/Account.vue b/web/src/pages/Account.vue index 7d43cc0..1371129 100644 --- a/web/src/pages/Account.vue +++ b/web/src/pages/Account.vue @@ -131,7 +131,7 @@ function createReconcilationTransaction() { :budgetid="budgetid" :accountid="accountid" /> -