Group transactions by date to simplify grouping in UI
This commit is contained in:
		| @@ -21,19 +21,6 @@ const Reconciling = computed(() => useTransactionsStore().Reconciling); | |||||||
| const transactionsStore = useTransactionsStore(); | const transactionsStore = useTransactionsStore(); | ||||||
| const TX = transactionsStore.Transactions.get(props.transactionid)!; | 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() { | function getStatusSymbol() { | ||||||
|     if(TX.Status == "Reconciled") |     if(TX.Status == "Reconciled") | ||||||
|         return "✔"; |         return "✔"; | ||||||
| @@ -46,13 +33,6 @@ function getStatusSymbol() { | |||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <template> | <template> | ||||||
|   <tr v-if="dateChanged()" class="table-row md:hidden"> |  | ||||||
|     <td class="py-2" colspan="5"> |  | ||||||
|       <span class="bg-gray-400 dark:bg-slate-600 rounded-lg p-1 px-2 w-full block"> |  | ||||||
|         {{ formatDate(TX.Date) }} |  | ||||||
|       </span> |  | ||||||
|     </td> |  | ||||||
|   </tr> |  | ||||||
|   <tr |   <tr | ||||||
|     v-if="!edit" |     v-if="!edit" | ||||||
|     class="{{new Date(TX.Date) > new Date() ? 'future' : ''}}" |     class="{{new Date(TX.Date) > new Date() ? 'future' : ''}}" | ||||||
|   | |||||||
| @@ -6,3 +6,12 @@ export function formatDate(date: Date): string { | |||||||
|         day: "2-digit", |         day: "2-digit", | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export function groupBy<T, K extends keyof any>(list: T[], getKey: (item: T) => K) { | ||||||
|  |   return list.reduce((previous, currentItem) => { | ||||||
|  |     const group = getKey(currentItem); | ||||||
|  |     if (!previous[group]) previous[group] = []; | ||||||
|  |     previous[group].push(currentItem); | ||||||
|  |     return previous; | ||||||
|  |   }, {} as Record<K, T[]>); | ||||||
|  | } | ||||||
| @@ -10,6 +10,7 @@ import { useTransactionsStore } from "../stores/transactions"; | |||||||
| import Modal from "../components/Modal.vue"; | import Modal from "../components/Modal.vue"; | ||||||
| import Input from "../components/Input.vue"; | import Input from "../components/Input.vue"; | ||||||
| import Checkbox from "../components/Checkbox.vue"; | import Checkbox from "../components/Checkbox.vue"; | ||||||
|  | import { formatDate } from "../date"; | ||||||
|  |  | ||||||
| defineProps<{ | defineProps<{ | ||||||
|     budgetid: string |     budgetid: string | ||||||
| @@ -144,12 +145,21 @@ function createReconcilationTransaction() { | |||||||
|       :budgetid="budgetid" |       :budgetid="budgetid" | ||||||
|       :accountid="accountid" |       :accountid="accountid" | ||||||
|     /> |     /> | ||||||
|     <TransactionRow |     <template v-for="(dayTransactions, index) in transactions.TransactionsByDate"> | ||||||
|       v-for="(transaction, index) in transactions.TransactionsList" |       <tr class="table-row md:hidden"> | ||||||
|       :key="transaction.ID" |         <td class="py-2" colspan="5"> | ||||||
|       :transactionid="transaction.ID" |           <span class="bg-gray-400 dark:bg-slate-600 rounded-lg p-1 px-2 w-full block"> | ||||||
|       :index="index" |             {{ index }} | ||||||
|     /> |           </span> | ||||||
|  |         </td> | ||||||
|  |       </tr> | ||||||
|  |       <TransactionRow | ||||||
|  |         v-for="(transaction, index) in dayTransactions" | ||||||
|  |         :key="transaction.ID" | ||||||
|  |         :transactionid="transaction.ID" | ||||||
|  |         :index="index" | ||||||
|  |       /> | ||||||
|  |     </template> | ||||||
|   </table> |   </table> | ||||||
|   <div class="md:hidden"> |   <div class="md:hidden"> | ||||||
|     <Modal @submit="submitModal"> |     <Modal @submit="submitModal"> | ||||||
|   | |||||||
| @@ -201,10 +201,9 @@ export const useAccountStore = defineStore("budget/account", { | |||||||
|             ); |             ); | ||||||
|             const response = await result.json(); |             const response = await result.json(); | ||||||
|             const transactionsStore = useTransactionsStore(); |             const transactionsStore = useTransactionsStore(); | ||||||
|             const transactions = transactionsStore.AddTransactions( |             transactionsStore.AddTransactions( | ||||||
|                 response.Transactions |                 response.Transactions | ||||||
|             ); |             ); | ||||||
|             account.Transactions = transactions; |  | ||||||
|         }, |         }, | ||||||
|         async FetchMonthBudget(budgetid: string, year: number, month: number) { |         async FetchMonthBudget(budgetid: string, year: number, month: number) { | ||||||
|             const result = await GET( |             const result = await GET( | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import { defineStore } from "pinia"; | import { defineStore } from "pinia"; | ||||||
| import { POST } from "../api"; | import { POST } from "../api"; | ||||||
|  | import { formatDate, groupBy } from "../date"; | ||||||
| import { useAccountStore } from "./budget-account"; | import { useAccountStore } from "./budget-account"; | ||||||
|  |  | ||||||
| interface State { | interface State { | ||||||
| @@ -21,6 +22,7 @@ export interface Transaction { | |||||||
|     PayeeID: string | undefined; |     PayeeID: string | undefined; | ||||||
|     Amount: number; |     Amount: number; | ||||||
|     Reconciled: boolean; |     Reconciled: boolean; | ||||||
|  |     AccountID: string; | ||||||
| } | } | ||||||
|  |  | ||||||
| export const useTransactionsStore = defineStore("budget/transactions", { | export const useTransactionsStore = defineStore("budget/transactions", { | ||||||
| @@ -39,24 +41,27 @@ export const useTransactionsStore = defineStore("budget/transactions", { | |||||||
|             } |             } | ||||||
|             return reconciledBalance; |             return reconciledBalance; | ||||||
|         }, |         }, | ||||||
|         TransactionsList(state): Transaction[] { |         TransactionsByDate(state) : Record<string, Transaction[]> { | ||||||
|             const accountsStore = useAccountStore(); |             const accountsStore = useAccountStore(); | ||||||
|             return accountsStore.CurrentAccount!.Transactions.map((x) => { |             const accountID = accountsStore.CurrentAccountID; | ||||||
|                 return this.Transactions.get(x)!; |             const allTransactions = [...this.Transactions.values()]; | ||||||
|             }); |             return groupBy(allTransactions.filter(x => x.AccountID == accountID), 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); | ||||||
|         }, |         }, | ||||||
|     }, |     }, | ||||||
|     actions: { |     actions: { | ||||||
|         AddTransactions(transactions: Array<Transaction>) { |         AddTransactions(transactions: Array<Transaction>) { | ||||||
|             const transactionIds = [] as Array<string>; |  | ||||||
|             this.$patch(() => { |             this.$patch(() => { | ||||||
|                 for (const transaction of transactions) { |                 for (const transaction of transactions) { | ||||||
|                     transaction.Date = new Date(transaction.Date); |                     transaction.Date = new Date(transaction.Date); | ||||||
|                     this.Transactions.set(transaction.ID, transaction); |                     this.Transactions.set(transaction.ID, transaction); | ||||||
|                     transactionIds.push(transaction.ID); |  | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|             return transactionIds; |  | ||||||
|         }, |         }, | ||||||
|         SetReconciledForAllTransactions(value: boolean) { |         SetReconciledForAllTransactions(value: boolean) { | ||||||
|             for (const transaction of this.TransactionsList) { |             for (const transaction of this.TransactionsList) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user