129 lines
5.0 KiB
TypeScript
129 lines
5.0 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import { GET, POST } from "../api";
|
|
import { formatDate, groupBy } from "../date";
|
|
import { useBudgetsStore } from "./budget";
|
|
import { useAccountStore } from "./budget-account";
|
|
|
|
interface State {
|
|
Transactions: Map<string, Transaction>;
|
|
Reconciling: boolean;
|
|
ProblematicTransactions: Array<string>;
|
|
}
|
|
|
|
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;
|
|
Account: string;
|
|
AccountID: string;
|
|
}
|
|
|
|
export const useTransactionsStore = defineStore("budget/transactions", {
|
|
state: (): State => ({
|
|
Transactions: new Map<string, Transaction>(),
|
|
Reconciling: false,
|
|
ProblematicTransactions: new Array<string>(),
|
|
}),
|
|
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;
|
|
},
|
|
TransactionsByDate(state) : Record<string, Transaction[]> {
|
|
const accountsStore = useAccountStore();
|
|
const allTransactions = [...this.Transactions.values()];
|
|
return groupBy(allTransactions, x => formatDate(x.Date));
|
|
},
|
|
TransactionsList(state) : Transaction[] {
|
|
const accountsStore = useAccountStore();
|
|
const accountID = accountsStore.CurrentAccountID;
|
|
const allTransactions = [...this.Transactions.values()];
|
|
return allTransactions.filter(x => x.AccountID == accountID);
|
|
},
|
|
ProblematicTransactionsList(state) : Transaction[] {
|
|
return [...state.ProblematicTransactions.map(x => state.Transactions!.get(x)!)];
|
|
}
|
|
},
|
|
actions: {
|
|
AddTransactions(transactions: Array<Transaction>) {
|
|
this.$patch(() => {
|
|
for (const transaction of transactions) {
|
|
transaction.Date = new Date(transaction.Date);
|
|
this.Transactions.set(transaction.ID, transaction);
|
|
}
|
|
});
|
|
},
|
|
SetReconciledForAllTransactions(value: boolean) {
|
|
for (const transaction of this.TransactionsList) {
|
|
if (transaction.Status == "Reconciled") continue;
|
|
|
|
transaction.Reconciled = value;
|
|
}
|
|
},
|
|
async GetProblematicTransactions() {
|
|
const budgetStore = useBudgetsStore();
|
|
const result = await GET("/budget/" + budgetStore.CurrentBudgetID + "/problematic-transactions");
|
|
const response = await result.json();
|
|
this.AddTransactions(response.Transactions);
|
|
this.ProblematicTransactions = [...response.Transactions.map((x : Transaction) => x.ID)];
|
|
},
|
|
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]);
|
|
},
|
|
},
|
|
});
|