Run prettier
This commit is contained in:
@ -1,195 +1,233 @@
|
||||
import { defineStore } from "pinia"
|
||||
import { defineStore } from "pinia";
|
||||
import { GET, POST } from "../api";
|
||||
import { useBudgetsStore } from "./budget";
|
||||
import { useSessionStore } from "./session";
|
||||
import { useTransactionsStore } from "./transactions";
|
||||
|
||||
interface State {
|
||||
Accounts: Map<string, Account>
|
||||
CurrentAccountID: string | null
|
||||
Categories: Map<string, Category>
|
||||
Months: Map<number, Map<number, Map<string, Category>>>
|
||||
Assignments: []
|
||||
Accounts: Map<string, Account>;
|
||||
CurrentAccountID: string | null;
|
||||
Categories: Map<string, Category>;
|
||||
Months: Map<number, Map<number, Map<string, Category>>>;
|
||||
Assignments: [];
|
||||
}
|
||||
|
||||
export interface Account {
|
||||
ID: string
|
||||
Name: string
|
||||
OnBudget: boolean
|
||||
IsOpen: boolean
|
||||
ClearedBalance: number
|
||||
WorkingBalance: number
|
||||
ReconciledBalance: number
|
||||
Transactions: string[]
|
||||
LastReconciled: NullDate
|
||||
ID: string;
|
||||
Name: string;
|
||||
OnBudget: boolean;
|
||||
IsOpen: boolean;
|
||||
ClearedBalance: number;
|
||||
WorkingBalance: number;
|
||||
ReconciledBalance: number;
|
||||
Transactions: string[];
|
||||
LastReconciled: NullDate;
|
||||
}
|
||||
|
||||
interface NullDate {
|
||||
Valid: boolean
|
||||
Time: Date
|
||||
Valid: boolean;
|
||||
Time: Date;
|
||||
}
|
||||
|
||||
export interface Category {
|
||||
ID: string
|
||||
Group: string
|
||||
Name: string
|
||||
AvailableLastMonth: number
|
||||
Assigned: number
|
||||
Activity: number
|
||||
ID: string;
|
||||
Group: string;
|
||||
Name: string;
|
||||
AvailableLastMonth: number;
|
||||
Assigned: number;
|
||||
Activity: 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>(),
|
||||
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() || []];
|
||||
},
|
||||
GetCategoryAvailable(state) {
|
||||
return (category: Category): number => {
|
||||
return category.AvailableLastMonth + Number(category.Assigned) + category.Activity;
|
||||
}
|
||||
},
|
||||
GetIncomeCategoryID(state) {
|
||||
const budget = useBudgetsStore();
|
||||
return budget.CurrentBudget?.IncomeCategoryID;
|
||||
},
|
||||
GetIncomeAvailable(state) {
|
||||
return (year: number, month: number) => {
|
||||
const IncomeCategoryID = this.GetIncomeCategoryID;
|
||||
if (IncomeCategoryID == null)
|
||||
return 0;
|
||||
state: (): State => ({
|
||||
Accounts: new Map<string, Account>(),
|
||||
CurrentAccountID: null,
|
||||
Months: new Map<number, Map<number, Map<string, Category>>>(),
|
||||
Categories: new Map<string, Category>(),
|
||||
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() || [])];
|
||||
},
|
||||
GetCategoryAvailable(state) {
|
||||
return (category: Category): number => {
|
||||
return (
|
||||
category.AvailableLastMonth +
|
||||
Number(category.Assigned) +
|
||||
category.Activity
|
||||
);
|
||||
};
|
||||
},
|
||||
GetIncomeCategoryID(state) {
|
||||
const budget = useBudgetsStore();
|
||||
return budget.CurrentBudget?.IncomeCategoryID;
|
||||
},
|
||||
GetIncomeAvailable(state) {
|
||||
return (year: number, month: number) => {
|
||||
const IncomeCategoryID = this.GetIncomeCategoryID;
|
||||
if (IncomeCategoryID == null) return 0;
|
||||
|
||||
const categories = this.AllCategoriesForMonth(year, month);
|
||||
const category = categories.filter(x => x.ID == IncomeCategoryID)[0];
|
||||
if (category == null)
|
||||
return 0;
|
||||
return category.AvailableLastMonth;
|
||||
}
|
||||
},
|
||||
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.ID == this.GetIncomeCategoryID)
|
||||
continue;
|
||||
const categories = this.AllCategoriesForMonth(year, month);
|
||||
const category = categories.filter(
|
||||
(x) => x.ID == IncomeCategoryID
|
||||
)[0];
|
||||
if (category == null) return 0;
|
||||
return category.AvailableLastMonth;
|
||||
};
|
||||
},
|
||||
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.ID == this.GetIncomeCategoryID) continue;
|
||||
|
||||
if (prev == undefined || category.Group != prev.Name) {
|
||||
prev = {
|
||||
Name: category.Group,
|
||||
Available: this.GetCategoryAvailable(category),
|
||||
AvailableLastMonth: category.AvailableLastMonth,
|
||||
Activity: category.Activity,
|
||||
Assigned: category.Assigned,
|
||||
}
|
||||
categoryGroups.push({
|
||||
...prev,
|
||||
Expand: prev.Name != "Hidden Categories",
|
||||
});
|
||||
} else {
|
||||
categoryGroups[categoryGroups.length-1].Available += this.GetCategoryAvailable(category);
|
||||
categoryGroups[categoryGroups.length-1].AvailableLastMonth += category.AvailableLastMonth;
|
||||
categoryGroups[categoryGroups.length-1].Activity += category.Activity;
|
||||
categoryGroups[categoryGroups.length-1].Assigned += category.Assigned;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return categoryGroups;
|
||||
}
|
||||
},
|
||||
CategoriesForMonthAndGroup(state) {
|
||||
return (year: number, month: number, group: string) => {
|
||||
const categories = this.AllCategoriesForMonth(year, month);
|
||||
return categories.filter(x => x.Group == group);
|
||||
}
|
||||
},
|
||||
GetAccount(state) {
|
||||
return (accountid: string) => {
|
||||
return this.Accounts.get(accountid);
|
||||
}
|
||||
},
|
||||
CurrentAccount(state): Account | undefined {
|
||||
if (state.CurrentAccountID == null)
|
||||
return undefined;
|
||||
if (prev == undefined || category.Group != prev.Name) {
|
||||
prev = {
|
||||
Name: category.Group,
|
||||
Available: this.GetCategoryAvailable(category),
|
||||
AvailableLastMonth: category.AvailableLastMonth,
|
||||
Activity: category.Activity,
|
||||
Assigned: category.Assigned,
|
||||
};
|
||||
categoryGroups.push({
|
||||
...prev,
|
||||
Expand: prev.Name != "Hidden Categories",
|
||||
});
|
||||
} else {
|
||||
categoryGroups[categoryGroups.length - 1].Available +=
|
||||
this.GetCategoryAvailable(category);
|
||||
categoryGroups[
|
||||
categoryGroups.length - 1
|
||||
].AvailableLastMonth += category.AvailableLastMonth;
|
||||
categoryGroups[categoryGroups.length - 1].Activity +=
|
||||
category.Activity;
|
||||
categoryGroups[categoryGroups.length - 1].Assigned +=
|
||||
category.Assigned;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return categoryGroups;
|
||||
};
|
||||
},
|
||||
CategoriesForMonthAndGroup(state) {
|
||||
return (year: number, month: number, group: string) => {
|
||||
const categories = this.AllCategoriesForMonth(year, month);
|
||||
return categories.filter((x) => x.Group == group);
|
||||
};
|
||||
},
|
||||
GetAccount(state) {
|
||||
return (accountid: string) => {
|
||||
return this.Accounts.get(accountid);
|
||||
};
|
||||
},
|
||||
CurrentAccount(state): Account | undefined {
|
||||
if (state.CurrentAccountID == null) return undefined;
|
||||
|
||||
return this.GetAccount(state.CurrentAccountID);
|
||||
},
|
||||
OnBudgetAccounts(state) {
|
||||
return [...state.Accounts.values()].filter(x => x.OnBudget);
|
||||
},
|
||||
OnBudgetAccountsBalance(state): number {
|
||||
return this.OnBudgetAccounts.reduce((prev, curr) => prev + Number(curr.ClearedBalance), 0);
|
||||
},
|
||||
OffBudgetAccounts(state) {
|
||||
return [...state.Accounts.values()].filter(x => !x.OnBudget);
|
||||
},
|
||||
OffBudgetAccountsBalance(state): number {
|
||||
return this.OffBudgetAccounts.reduce((prev, curr) => prev + Number(curr.ClearedBalance), 0);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async SetCurrentAccount(budgetid: string, accountid: string) {
|
||||
if (budgetid == null)
|
||||
return;
|
||||
return this.GetAccount(state.CurrentAccountID);
|
||||
},
|
||||
OnBudgetAccounts(state) {
|
||||
return [...state.Accounts.values()].filter((x) => x.OnBudget);
|
||||
},
|
||||
OnBudgetAccountsBalance(state): number {
|
||||
return this.OnBudgetAccounts.reduce(
|
||||
(prev, curr) => prev + Number(curr.ClearedBalance),
|
||||
0
|
||||
);
|
||||
},
|
||||
OffBudgetAccounts(state) {
|
||||
return [...state.Accounts.values()].filter((x) => !x.OnBudget);
|
||||
},
|
||||
OffBudgetAccountsBalance(state): number {
|
||||
return this.OffBudgetAccounts.reduce(
|
||||
(prev, curr) => prev + Number(curr.ClearedBalance),
|
||||
0
|
||||
);
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async SetCurrentAccount(budgetid: string, accountid: string) {
|
||||
if (budgetid == null) return;
|
||||
|
||||
this.CurrentAccountID = accountid;
|
||||
this.CurrentAccountID = accountid;
|
||||
|
||||
if (accountid == null)
|
||||
return;
|
||||
const account = this.GetAccount(accountid)!;
|
||||
useSessionStore().setTitle(account.Name);
|
||||
await this.FetchAccount(account);
|
||||
},
|
||||
async FetchAccount(account: Account) {
|
||||
const result = await GET("/account/" + account.ID + "/transactions");
|
||||
const response = await result.json();
|
||||
const transactionsStore = useTransactionsStore()
|
||||
const transactions = transactionsStore.AddTransactions(response.Transactions);
|
||||
account.Transactions = transactions;
|
||||
},
|
||||
async FetchMonthBudget(budgetid: string, year: number, month: number) {
|
||||
const result = await GET("/budget/" + budgetid + "/" + year + "/" + (month + 1));
|
||||
const response = await result.json();
|
||||
if (response.Categories == undefined || response.Categories.length <= 0)
|
||||
return;
|
||||
this.addCategoriesForMonth(year, month, response.Categories);
|
||||
},
|
||||
async EditAccount(accountid: string, name: string, onBudget: boolean, isOpen: boolean) {
|
||||
const result = await POST("/account/" + accountid, JSON.stringify({ name: name, onBudget: onBudget, isOpen: isOpen }));
|
||||
const response = await result.json();
|
||||
useBudgetsStore().MergeBudgetingData(response);
|
||||
if (accountid == null) return;
|
||||
const account = this.GetAccount(accountid)!;
|
||||
useSessionStore().setTitle(account.Name);
|
||||
await this.FetchAccount(account);
|
||||
},
|
||||
async FetchAccount(account: Account) {
|
||||
const result = await GET(
|
||||
"/account/" + account.ID + "/transactions"
|
||||
);
|
||||
const response = await result.json();
|
||||
const transactionsStore = useTransactionsStore();
|
||||
const transactions = transactionsStore.AddTransactions(
|
||||
response.Transactions
|
||||
);
|
||||
account.Transactions = transactions;
|
||||
},
|
||||
async FetchMonthBudget(budgetid: string, year: number, month: number) {
|
||||
const result = await GET(
|
||||
"/budget/" + budgetid + "/" + year + "/" + (month + 1)
|
||||
);
|
||||
const response = await result.json();
|
||||
if (
|
||||
response.Categories == undefined ||
|
||||
response.Categories.length <= 0
|
||||
)
|
||||
return;
|
||||
this.addCategoriesForMonth(year, month, response.Categories);
|
||||
},
|
||||
async EditAccount(
|
||||
accountid: string,
|
||||
name: string,
|
||||
onBudget: boolean,
|
||||
isOpen: boolean
|
||||
) {
|
||||
const result = await POST(
|
||||
"/account/" + accountid,
|
||||
JSON.stringify({
|
||||
name: name,
|
||||
onBudget: onBudget,
|
||||
isOpen: isOpen,
|
||||
})
|
||||
);
|
||||
const response = await result.json();
|
||||
useBudgetsStore().MergeBudgetingData(response);
|
||||
|
||||
if (!isOpen) {
|
||||
this.Accounts.delete(accountid);
|
||||
}
|
||||
},
|
||||
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);
|
||||
}
|
||||
if (!isOpen) {
|
||||
this.Accounts.delete(accountid);
|
||||
}
|
||||
},
|
||||
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()
|
||||
},
|
||||
}
|
||||
|
||||
})
|
||||
yearMap.set(month, monthMap);
|
||||
state.Months.set(year, yearMap);
|
||||
});
|
||||
},
|
||||
logout() {
|
||||
this.$reset();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -4,67 +4,67 @@ import { useAccountStore } from "./budget-account";
|
||||
import { Budget, useSessionStore } from "./session";
|
||||
|
||||
interface State {
|
||||
CurrentBudgetID: string | null,
|
||||
CurrentBudgetID: string | null;
|
||||
}
|
||||
|
||||
export const useBudgetsStore = defineStore('budget', {
|
||||
state: (): State => ({
|
||||
CurrentBudgetID: null,
|
||||
}),
|
||||
getters: {
|
||||
CurrentBudget(): Budget | undefined {
|
||||
if (this.CurrentBudgetID == null)
|
||||
return undefined;
|
||||
export const useBudgetsStore = defineStore("budget", {
|
||||
state: (): State => ({
|
||||
CurrentBudgetID: null,
|
||||
}),
|
||||
getters: {
|
||||
CurrentBudget(): Budget | undefined {
|
||||
if (this.CurrentBudgetID == null) return undefined;
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
return sessionStore.Budgets.get(this.CurrentBudgetID);
|
||||
},
|
||||
CurrentBudgetName(state): string {
|
||||
return this.CurrentBudget?.Name ?? "";
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
ImportYNAB(formData: FormData) {
|
||||
return POST(
|
||||
"/budget/" + this.CurrentBudgetID + "/import/ynab",
|
||||
formData,
|
||||
);
|
||||
},
|
||||
async NewBudget(budgetName: string): Promise<void> {
|
||||
const result = await POST(
|
||||
"/budget/new",
|
||||
JSON.stringify({ name: budgetName })
|
||||
);
|
||||
const response = await result.json();
|
||||
const sessionStore = useSessionStore();
|
||||
return sessionStore.Budgets.get(this.CurrentBudgetID);
|
||||
},
|
||||
CurrentBudgetName(state): string {
|
||||
return this.CurrentBudget?.Name ?? "";
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
ImportYNAB(formData: FormData) {
|
||||
return POST(
|
||||
"/budget/" + this.CurrentBudgetID + "/import/ynab",
|
||||
formData
|
||||
);
|
||||
},
|
||||
async NewBudget(budgetName: string): Promise<void> {
|
||||
const result = await POST(
|
||||
"/budget/new",
|
||||
JSON.stringify({ name: budgetName })
|
||||
);
|
||||
const response = await result.json();
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
sessionStore.Budgets.set(response.ID, response);
|
||||
},
|
||||
async SetCurrentBudget(budgetid: string): Promise<void> {
|
||||
this.CurrentBudgetID = budgetid;
|
||||
const sessionStore = useSessionStore();
|
||||
sessionStore.Budgets.set(response.ID, response);
|
||||
},
|
||||
async SetCurrentBudget(budgetid: string): Promise<void> {
|
||||
this.CurrentBudgetID = budgetid;
|
||||
|
||||
if (budgetid == null)
|
||||
return
|
||||
if (budgetid == null) return;
|
||||
|
||||
await this.FetchBudget(budgetid);
|
||||
},
|
||||
async FetchBudget(budgetid: string) {
|
||||
const result = await GET("/budget/" + budgetid);
|
||||
const response = await result.json();
|
||||
this.MergeBudgetingData(response);
|
||||
},
|
||||
MergeBudgetingData(response: any) {
|
||||
const accounts = useAccountStore();
|
||||
for (const account of response.Accounts || []) {
|
||||
const existingAccount = accounts.Accounts.get(account.ID);
|
||||
account.Transactions = existingAccount?.Transactions ?? [];
|
||||
if(account.LastReconciled.Valid)
|
||||
account.LastReconciled.Time = new Date(account.LastReconciled.Time);
|
||||
accounts.Accounts.set(account.ID, account);
|
||||
}
|
||||
for (const category of response.Categories || []) {
|
||||
accounts.Categories.set(category.ID, category);
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
await this.FetchBudget(budgetid);
|
||||
},
|
||||
async FetchBudget(budgetid: string) {
|
||||
const result = await GET("/budget/" + budgetid);
|
||||
const response = await result.json();
|
||||
this.MergeBudgetingData(response);
|
||||
},
|
||||
MergeBudgetingData(response: any) {
|
||||
const accounts = useAccountStore();
|
||||
for (const account of response.Accounts || []) {
|
||||
const existingAccount = accounts.Accounts.get(account.ID);
|
||||
account.Transactions = existingAccount?.Transactions ?? [];
|
||||
if (account.LastReconciled.Valid)
|
||||
account.LastReconciled.Time = new Date(
|
||||
account.LastReconciled.Time
|
||||
);
|
||||
accounts.Accounts.set(account.ID, account);
|
||||
}
|
||||
for (const category of response.Categories || []) {
|
||||
accounts.Categories.set(category.ID, category);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,62 +1,74 @@
|
||||
import { StorageSerializers, useStorage } from '@vueuse/core';
|
||||
import { defineStore } from 'pinia'
|
||||
import { POST } from '../api';
|
||||
import { StorageSerializers, useStorage } from "@vueuse/core";
|
||||
import { defineStore } from "pinia";
|
||||
import { POST } from "../api";
|
||||
|
||||
interface State {
|
||||
Session: Session | null
|
||||
Budgets: Map<string, Budget>,
|
||||
Session: Session | null;
|
||||
Budgets: Map<string, Budget>;
|
||||
}
|
||||
|
||||
interface Session {
|
||||
Token: string
|
||||
User: string
|
||||
Token: string;
|
||||
User: string;
|
||||
}
|
||||
|
||||
export interface Budget {
|
||||
ID: string
|
||||
Name: string
|
||||
AvailableBalance: number
|
||||
IncomeCategoryID: string
|
||||
ID: string;
|
||||
Name: string;
|
||||
AvailableBalance: number;
|
||||
IncomeCategoryID: string;
|
||||
}
|
||||
|
||||
export const useSessionStore = defineStore('session', {
|
||||
state: () => ({
|
||||
Session: useStorage<Session | null>('session', null, undefined, { serializer: StorageSerializers.object }),
|
||||
Budgets: useStorage<Map<string, Budget>>('budgets', new Map<string, Budget>(), undefined, { serializer: StorageSerializers.map }),
|
||||
}),
|
||||
getters: {
|
||||
BudgetsList: (state) => [ ...state.Budgets.values() ],
|
||||
AuthHeaders: (state) => ({'Authorization': 'Bearer ' + state.Session?.Token}),
|
||||
LoggedIn: (state) => state.Session != null,
|
||||
},
|
||||
actions: {
|
||||
setTitle(title : string) {
|
||||
document.title = "Budgeteer - " + title;
|
||||
},
|
||||
loginSuccess(x : any) {
|
||||
this.Session = {
|
||||
User: x.User,
|
||||
Token: x.Token,
|
||||
}
|
||||
for (const budget of x.Budgets) {
|
||||
this.Budgets.set(budget.ID, budget);
|
||||
}
|
||||
},
|
||||
async login(login: any) {
|
||||
const response = await POST("/user/login", JSON.stringify(login));
|
||||
const result = await response.json();
|
||||
this.loginSuccess(result);
|
||||
return result;
|
||||
},
|
||||
async register(login : any) {
|
||||
const response = await POST("/user/register", JSON.stringify(login));
|
||||
const result = await response.json();
|
||||
this.loginSuccess(result);
|
||||
return result;
|
||||
},
|
||||
logout() {
|
||||
this.Session = null;
|
||||
this.Budgets.clear();
|
||||
},
|
||||
}
|
||||
})
|
||||
export const useSessionStore = defineStore("session", {
|
||||
state: () => ({
|
||||
Session: useStorage<Session | null>("session", null, undefined, {
|
||||
serializer: StorageSerializers.object,
|
||||
}),
|
||||
Budgets: useStorage<Map<string, Budget>>(
|
||||
"budgets",
|
||||
new Map<string, Budget>(),
|
||||
undefined,
|
||||
{ serializer: StorageSerializers.map }
|
||||
),
|
||||
}),
|
||||
getters: {
|
||||
BudgetsList: (state) => [...state.Budgets.values()],
|
||||
AuthHeaders: (state) => ({
|
||||
Authorization: "Bearer " + state.Session?.Token,
|
||||
}),
|
||||
LoggedIn: (state) => state.Session != null,
|
||||
},
|
||||
actions: {
|
||||
setTitle(title: string) {
|
||||
document.title = "Budgeteer - " + title;
|
||||
},
|
||||
loginSuccess(x: any) {
|
||||
this.Session = {
|
||||
User: x.User,
|
||||
Token: x.Token,
|
||||
};
|
||||
for (const budget of x.Budgets) {
|
||||
this.Budgets.set(budget.ID, budget);
|
||||
}
|
||||
},
|
||||
async login(login: any) {
|
||||
const response = await POST("/user/login", JSON.stringify(login));
|
||||
const result = await response.json();
|
||||
this.loginSuccess(result);
|
||||
return result;
|
||||
},
|
||||
async register(login: any) {
|
||||
const response = await POST(
|
||||
"/user/register",
|
||||
JSON.stringify(login)
|
||||
);
|
||||
const result = await response.json();
|
||||
this.loginSuccess(result);
|
||||
return result;
|
||||
},
|
||||
logout() {
|
||||
this.Session = null;
|
||||
this.Budgets.clear();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -2,27 +2,27 @@ import { useStorage } from "@vueuse/core";
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
interface State {
|
||||
Menu: MenuSettings
|
||||
Menu: MenuSettings;
|
||||
}
|
||||
|
||||
interface MenuSettings {
|
||||
Show: boolean | null,
|
||||
Expand: boolean | null,
|
||||
Show: boolean | null;
|
||||
Expand: boolean | null;
|
||||
}
|
||||
|
||||
export const useSettingsStore = defineStore('settings', {
|
||||
state: () => ({
|
||||
Menu: useStorage<MenuSettings>('settings', {
|
||||
Show: null,
|
||||
Expand: false,
|
||||
}),
|
||||
}),
|
||||
actions: {
|
||||
toggleMenu() {
|
||||
this.Menu.Show = !this.Menu.Show;
|
||||
},
|
||||
toggleMenuSize() {
|
||||
this.Menu.Expand = !this.Menu.Expand;
|
||||
},
|
||||
}
|
||||
});
|
||||
export const useSettingsStore = defineStore("settings", {
|
||||
state: () => ({
|
||||
Menu: useStorage<MenuSettings>("settings", {
|
||||
Show: null,
|
||||
Expand: false,
|
||||
}),
|
||||
}),
|
||||
actions: {
|
||||
toggleMenu() {
|
||||
this.Menu.Show = !this.Menu.Show;
|
||||
},
|
||||
toggleMenuSize() {
|
||||
this.Menu.Expand = !this.Menu.Expand;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,105 +1,110 @@
|
||||
import { defineStore } from "pinia"
|
||||
import { defineStore } from "pinia";
|
||||
import { POST } from "../api";
|
||||
import { useAccountStore } from "./budget-account";
|
||||
|
||||
interface State {
|
||||
Transactions: Map<string, Transaction>
|
||||
Reconciling: boolean
|
||||
Transactions: Map<string, Transaction>;
|
||||
Reconciling: boolean;
|
||||
}
|
||||
|
||||
export interface Transaction {
|
||||
ID: string
|
||||
Date: Date
|
||||
TransferAccount: string
|
||||
CategoryGroup: string
|
||||
Category: string
|
||||
CategoryID: string | undefined
|
||||
Memo: string
|
||||
Status: string
|
||||
GroupID: string
|
||||
Payee: string
|
||||
PayeeID: string | undefined
|
||||
Amount: number
|
||||
Reconciled: boolean
|
||||
ID: string;
|
||||
Date: Date;
|
||||
TransferAccount: string;
|
||||
CategoryGroup: string;
|
||||
Category: string;
|
||||
CategoryID: string | undefined;
|
||||
Memo: string;
|
||||
Status: string;
|
||||
GroupID: string;
|
||||
Payee: string;
|
||||
PayeeID: string | undefined;
|
||||
Amount: number;
|
||||
Reconciled: boolean;
|
||||
}
|
||||
|
||||
export const useTransactionsStore = defineStore("budget/transactions", {
|
||||
state: (): State => ({
|
||||
Transactions: new Map<string, Transaction>(),
|
||||
Reconciling: false,
|
||||
}),
|
||||
getters: {
|
||||
ReconcilingBalance(state): number {
|
||||
const accountsStore = useAccountStore()
|
||||
let reconciledBalance = accountsStore.CurrentAccount!.ReconciledBalance;
|
||||
for (const transaction of this.TransactionsList) {
|
||||
if (transaction.Reconciled)
|
||||
reconciledBalance += transaction.Amount;
|
||||
}
|
||||
return reconciledBalance;
|
||||
},
|
||||
TransactionsList(state): Transaction[] {
|
||||
const accountsStore = useAccountStore()
|
||||
return accountsStore.CurrentAccount!.Transactions.map(x => {
|
||||
return this.Transactions.get(x)!
|
||||
});
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
AddTransactions(transactions: Array<Transaction>) {
|
||||
const transactionIds = [] as Array<string>;
|
||||
this.$patch(() => {
|
||||
for (const transaction of transactions) {
|
||||
transaction.Date = new Date(transaction.Date);
|
||||
this.Transactions.set(transaction.ID, transaction);
|
||||
transactionIds.push(transaction.ID);
|
||||
}
|
||||
});
|
||||
return transactionIds;
|
||||
},
|
||||
SetReconciledForAllTransactions(value: boolean) {
|
||||
for (const transaction of this.TransactionsList) {
|
||||
if (transaction.Status == "Reconciled")
|
||||
continue;
|
||||
state: (): State => ({
|
||||
Transactions: new Map<string, Transaction>(),
|
||||
Reconciling: false,
|
||||
}),
|
||||
getters: {
|
||||
ReconcilingBalance(state): number {
|
||||
const accountsStore = useAccountStore();
|
||||
let reconciledBalance =
|
||||
accountsStore.CurrentAccount!.ReconciledBalance;
|
||||
for (const transaction of this.TransactionsList) {
|
||||
if (transaction.Reconciled)
|
||||
reconciledBalance += transaction.Amount;
|
||||
}
|
||||
return reconciledBalance;
|
||||
},
|
||||
TransactionsList(state): Transaction[] {
|
||||
const accountsStore = useAccountStore();
|
||||
return accountsStore.CurrentAccount!.Transactions.map((x) => {
|
||||
return this.Transactions.get(x)!;
|
||||
});
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
AddTransactions(transactions: Array<Transaction>) {
|
||||
const transactionIds = [] as Array<string>;
|
||||
this.$patch(() => {
|
||||
for (const transaction of transactions) {
|
||||
transaction.Date = new Date(transaction.Date);
|
||||
this.Transactions.set(transaction.ID, transaction);
|
||||
transactionIds.push(transaction.ID);
|
||||
}
|
||||
});
|
||||
return transactionIds;
|
||||
},
|
||||
SetReconciledForAllTransactions(value: boolean) {
|
||||
for (const transaction of this.TransactionsList) {
|
||||
if (transaction.Status == "Reconciled") continue;
|
||||
|
||||
transaction.Reconciled = value;
|
||||
}
|
||||
},
|
||||
async SubmitReconcilation(reconciliationTransactionAmount: number) {
|
||||
const accountsStore = useAccountStore()
|
||||
const account = accountsStore.CurrentAccount!;
|
||||
const reconciledTransactions = this.TransactionsList.filter(x => x.Reconciled);
|
||||
for (const transaction of reconciledTransactions) {
|
||||
account.ReconciledBalance += transaction.Amount;
|
||||
transaction.Status = "Reconciled";
|
||||
transaction.Reconciled = false;
|
||||
}
|
||||
const result = await POST("/account/" + accountsStore.CurrentAccountID + "/reconcile", JSON.stringify({
|
||||
transactionIDs: reconciledTransactions.map(x => x.ID),
|
||||
reconciliationTransactionAmount: reconciliationTransactionAmount.toString(),
|
||||
}));
|
||||
const response = await result.json();
|
||||
const recTrans = response.ReconciliationTransaction;
|
||||
if (recTrans) {
|
||||
this.AddTransactions([recTrans]);
|
||||
account.Transactions.unshift(recTrans.ID);
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
this.$reset()
|
||||
},
|
||||
async saveTransaction(payload: string) {
|
||||
const accountsStore = useAccountStore()
|
||||
const result = await POST("/transaction/new", payload);
|
||||
const response = await result.json() as Transaction;
|
||||
this.AddTransactions([response]);
|
||||
accountsStore.CurrentAccount?.Transactions.unshift(response.ID);
|
||||
},
|
||||
async editTransaction(transactionid: string, payload: string) {
|
||||
const result = await POST("/transaction/" + transactionid, payload);
|
||||
const response = await result.json() as Transaction;
|
||||
this.AddTransactions([response]);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
transaction.Reconciled = value;
|
||||
}
|
||||
},
|
||||
async SubmitReconcilation(reconciliationTransactionAmount: number) {
|
||||
const accountsStore = useAccountStore();
|
||||
const account = accountsStore.CurrentAccount!;
|
||||
const reconciledTransactions = this.TransactionsList.filter(
|
||||
(x) => x.Reconciled
|
||||
);
|
||||
for (const transaction of reconciledTransactions) {
|
||||
account.ReconciledBalance += transaction.Amount;
|
||||
transaction.Status = "Reconciled";
|
||||
transaction.Reconciled = false;
|
||||
}
|
||||
const result = await POST(
|
||||
"/account/" + accountsStore.CurrentAccountID + "/reconcile",
|
||||
JSON.stringify({
|
||||
transactionIDs: reconciledTransactions.map((x) => x.ID),
|
||||
reconciliationTransactionAmount:
|
||||
reconciliationTransactionAmount.toString(),
|
||||
})
|
||||
);
|
||||
const response = await result.json();
|
||||
const recTrans = response.ReconciliationTransaction;
|
||||
if (recTrans) {
|
||||
this.AddTransactions([recTrans]);
|
||||
account.Transactions.unshift(recTrans.ID);
|
||||
}
|
||||
},
|
||||
logout() {
|
||||
this.$reset();
|
||||
},
|
||||
async saveTransaction(payload: string) {
|
||||
const accountsStore = useAccountStore();
|
||||
const result = await POST("/transaction/new", payload);
|
||||
const response = (await result.json()) as Transaction;
|
||||
this.AddTransactions([response]);
|
||||
accountsStore.CurrentAccount?.Transactions.unshift(response.ID);
|
||||
},
|
||||
async editTransaction(transactionid: string, payload: string) {
|
||||
const result = await POST("/transaction/" + transactionid, payload);
|
||||
const response = (await result.json()) as Transaction;
|
||||
this.AddTransactions([response]);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
Reference in New Issue
Block a user