167 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
| import { api } from 'src/boot/axios';
 | |
| 
 | |
| interface BalanceResponse {
 | |
|   balance: number;
 | |
|   credit: number;
 | |
|   debit: number;
 | |
|   limit?: number;
 | |
| }
 | |
| 
 | |
| export interface BalancesResponse extends BalanceResponse {
 | |
|   userid: string;
 | |
| }
 | |
| 
 | |
| export interface TransactionsResponse {
 | |
|   transactions: Array<FG.Transaction>;
 | |
|   count?: number;
 | |
| }
 | |
| 
 | |
| import { defineStore } from 'pinia';
 | |
| import { useMainStore } from 'src/stores';
 | |
| import { AxiosResponse } from 'axios';
 | |
| import { Notify } from 'quasar';
 | |
| 
 | |
| function fixTransaction(t: FG.Transaction) {
 | |
|   t.time = new Date(t.time);
 | |
| }
 | |
| 
 | |
| export const useBalanceStore = defineStore({
 | |
|   id: 'balance',
 | |
| 
 | |
|   state: () => ({
 | |
|     balances: [] as BalancesResponse[],
 | |
|     shortcuts: [] as number[],
 | |
|     transactions: [] as FG.Transaction[],
 | |
|     _balances_dirty: 0,
 | |
|   }),
 | |
| 
 | |
|   getters: {
 | |
|     balance(): BalancesResponse | undefined {
 | |
|       const mainStore = useMainStore();
 | |
|       return this.balances.find((v) => v.userid === mainStore.user?.userid);
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   actions: {
 | |
|     async createShortcut(shortcut: number) {
 | |
|       const mainStore = useMainStore();
 | |
|       this.shortcuts.push(shortcut);
 | |
|       this.shortcuts.sort((a, b) => a - b);
 | |
|       await api.put(`/users/${mainStore.currentUser.userid}/balance/shortcuts`, this.shortcuts);
 | |
|     },
 | |
| 
 | |
|     async removeShortcut(shortcut: number) {
 | |
|       const mainStore = useMainStore();
 | |
|       this.shortcuts = this.shortcuts.filter((value: number) => value !== shortcut);
 | |
|       this.shortcuts.sort((a, b) => a - b);
 | |
|       await api.put(`/users/${mainStore.currentUser.userid}/balance/shortcuts`, this.shortcuts);
 | |
|     },
 | |
| 
 | |
|     async getShortcuts(force = false) {
 | |
|       if (force || this.shortcuts.length == 0) {
 | |
|         const mainStore = useMainStore();
 | |
|         const { data } = await api.get<number[]>(
 | |
|           `/users/${mainStore.currentUser.userid}/balance/shortcuts`
 | |
|         );
 | |
|         this.shortcuts = data;
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     async getBalance(user: FG.User) {
 | |
|       const { data } = await api.get<BalanceResponse>(`/users/${user.userid}/balance`);
 | |
|       const idx = this.balances.findIndex((x) => x.userid === user.userid);
 | |
|       if (idx == -1) this.balances.push(Object.assign(data, { userid: user.userid }));
 | |
|       else this.balances[idx] = Object.assign(data, { userid: user.userid });
 | |
|       return data;
 | |
|     },
 | |
| 
 | |
|     async getBalances(force = false) {
 | |
|       if (
 | |
|         force ||
 | |
|         this.balances.length == 0 ||
 | |
|         new Date().getTime() - this._balances_dirty > 60000
 | |
|       ) {
 | |
|         const { data } = await api.get<BalancesResponse[]>('/balance');
 | |
|         this.balances = data;
 | |
|       }
 | |
|       return this.balances;
 | |
|     },
 | |
| 
 | |
|     async changeBalance(amount: number, user: FG.User, sender: FG.User | undefined = undefined) {
 | |
|       const mainStore = useMainStore();
 | |
|       try {
 | |
|         const { data } = await api.put<FG.Transaction>(`/users/${user.userid}/balance`, {
 | |
|           amount,
 | |
|           user: user.userid,
 | |
|           sender: sender?.userid,
 | |
|         });
 | |
|         fixTransaction(data);
 | |
|         if (
 | |
|           user.userid === mainStore.currentUser.userid ||
 | |
|           sender?.userid === mainStore.currentUser.userid
 | |
|         )
 | |
|           this.transactions.push(data);
 | |
|         const f = this.balances.find((x) => x.userid === user.userid);
 | |
|         if (f) f.balance += amount;
 | |
|         if (sender) {
 | |
|           const f = this.balances.find((x) => x.userid === sender.userid);
 | |
|           if (f) f.balance += -1 * amount;
 | |
|         }
 | |
|         this._balances_dirty = 0;
 | |
|         return data;
 | |
|       } catch ({ response }) {
 | |
|         // Maybe Balance changed
 | |
|         if (response && (<AxiosResponse>response).status == 409) {
 | |
|           Notify.create({
 | |
|             type: 'negative',
 | |
|             group: false,
 | |
|             message: 'Das Limit wurde überschritten!',
 | |
|             timeout: 10000,
 | |
|             progress: true,
 | |
|             actions: [{ icon: 'mdi-close', color: 'white' }],
 | |
|           });
 | |
|           //void this.getTransactions(true);
 | |
|           void this.getBalance(sender ? sender : user);
 | |
|         }
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     async getTransactions(
 | |
|       user: FG.User,
 | |
|       filter:
 | |
|         | {
 | |
|             limit?: number;
 | |
|             offset?: number;
 | |
|             from?: Date;
 | |
|             to?: Date;
 | |
|             showReversals?: boolean;
 | |
|             showCancelled?: boolean;
 | |
|           }
 | |
|         | undefined = undefined
 | |
|     ) {
 | |
|       if (!filter) filter = { limit: 10 };
 | |
|       const { data } = await api.get<TransactionsResponse>(
 | |
|         `/users/${user.userid}/balance/transactions`,
 | |
|         { params: filter }
 | |
|       );
 | |
|       data.transactions.forEach((t) => fixTransaction(t));
 | |
|       if (data.transactions) this.transactions.push(...data.transactions);
 | |
|       return data;
 | |
|     },
 | |
| 
 | |
|     async revert(transaction: FG.Transaction) {
 | |
|       try {
 | |
|         const { data } = await api.delete<FG.Transaction>(`/balance/${transaction.id}`);
 | |
|         fixTransaction(data);
 | |
|         const f = this.transactions.find((x) => x.id === transaction.id);
 | |
|         if (f) f.reversal_id = data.id;
 | |
|         this.transactions.push(data);
 | |
|         console.log(data);
 | |
|       } catch (error) {
 | |
|         // ...
 | |
|       }
 | |
|       this._balances_dirty = 0;
 | |
|     },
 | |
|   },
 | |
| });
 |