budgeteer/web/src/stores/budget-account.ts
Jan Bader 510c91205d
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Rewrite categories to be nested below groups
2022-02-23 21:56:20 +00:00

150 lines
5.0 KiB
TypeScript

import { defineStore } from "pinia"
import { GET, POST } from "../api";
import { useSessionStore } from "./session";
interface State {
Accounts: Map<string, Account>,
CurrentAccountID: string | null,
Categories: Map<string, Category>,
Months: Map<number, Map<number, Map<string, Category>>>,
Transactions: any[],
Assignments: []
}
export interface Transaction {
ID: string,
Date: string,
TransferAccount: string,
CategoryGroup: string,
Category: string,
Memo: string,
Status: string,
GroupID: string,
Payee: string,
Amount: number,
}
export interface Account {
ID: string
Name: string
OnBudget: boolean
Balance: number
}
export interface Category {
ID: string
Group: string
Name: string
AvailableLastMonth: number
Assigned: number
Activity: number
Available: number
}
export const useAccountStore = defineStore("budget/account", {
state: (): State => ({
Accounts: new Map<string, Account>(),
CurrentAccountID: null,
Months: new Map<number, Map<number, Map<string, Category>>>(),
Categories: new Map<string, Category>(),
Transactions: [],
Assignments: []
}),
getters: {
AccountsList(state) {
return [...state.Accounts.values()];
},
AllCategoriesForMonth: (state) => (year: number, month: number) => {
const yearMap = state.Months.get(year);
const monthMap = yearMap?.get(month);
return [...monthMap?.values() || []];
},
CategoryGroupsForMonth(state) {
return (year: number, month: number) => {
const categories = this.AllCategoriesForMonth(year, month);
const categoryGroups = [];
let prev = undefined;
for (const category of categories) {
if(category.Group != prev)
categoryGroups.push(category.Group);
prev = category.Group;
}
return categoryGroups;
}
},
CategoriesForMonthAndGroup(state) {
return (year: number, month: number, group : string) => {
const categories = this.AllCategoriesForMonth(year, month);
return categories.filter(x => x.Group == group);
}
},
CurrentAccount(state): Account | undefined {
if (state.CurrentAccountID == null)
return undefined;
return state.Accounts.get(state.CurrentAccountID);
},
OnBudgetAccounts(state) {
return [...state.Accounts.values()].filter(x => x.OnBudget);
},
OnBudgetAccountsBalance(state): number {
return this.OnBudgetAccounts.reduce((prev, curr) => prev + Number(curr.Balance), 0);
},
OffBudgetAccounts(state) {
return [...state.Accounts.values()].filter(x => !x.OnBudget);
},
OffBudgetAccountsBalance(state): number {
return this.OffBudgetAccounts.reduce((prev, curr) => prev + Number(curr.Balance), 0);
},
TransactionsList(state) {
return (state.Transactions || []);
}
},
actions: {
async SetCurrentAccount(budgetid: string, accountid: string) {
if (budgetid == null)
return
this.CurrentAccountID = accountid;
if (this.CurrentAccount == undefined)
return
useSessionStore().setTitle(this.CurrentAccount.Name);
await this.FetchAccount(accountid);
},
async FetchAccount(accountid: string) {
const result = await GET("/account/" + accountid + "/transactions");
const response = await result.json();
this.Transactions = response.Transactions;
},
async FetchMonthBudget(budgetid: string, year: number, month: number) {
const result = await GET("/budget/" + budgetid + "/" + year + "/" + month);
const response = await result.json();
if(response.Categories == undefined || response.Categories.length <= 0)
return;
this.addCategoriesForMonth(year, month, response.Categories);
},
addCategoriesForMonth(year: number, month: number, categories: Category[]): void {
this.$patch((state) => {
const yearMap = state.Months.get(year) || new Map<number, Map<string, Category>>();
const monthMap = yearMap.get(month) || new Map<string, Category>();
for (const category of categories) {
monthMap.set(category.ID, category);
}
yearMap.set(month, monthMap);
state.Months.set(year, yearMap);
});
},
logout() {
this.$reset()
},
async saveTransaction(payload: string) {
const result = await POST("/transaction/new", payload);
const response = await result.json();
this.Transactions.unshift(response);
}
}
})