191 lines
6.0 KiB
TypeScript
191 lines
6.0 KiB
TypeScript
import { api, useMainStore, useUserStore } from '@flaschengeist/api';
|
|
import { defineStore } from 'pinia';
|
|
import { AxiosResponse } from 'axios';
|
|
import { Notify } from 'quasar';
|
|
|
|
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;
|
|
}
|
|
|
|
export interface UserLimit {
|
|
userid: string;
|
|
limit?: number;
|
|
}
|
|
|
|
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,
|
|
user_limits: [] as Array<UserLimit>,
|
|
}),
|
|
|
|
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(filter?: { limit?: number; offset?: number; sortBy?: string; descending?: boolean }) {
|
|
const { data } = await api.get<{ balances: BalancesResponse[]; count: number }>('/balance', {
|
|
params: filter,
|
|
});
|
|
this.balances = data.balances;
|
|
return { balances: this.balances, count: data.count };
|
|
},
|
|
|
|
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;
|
|
descending?: 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;
|
|
},
|
|
|
|
async getLimits(filter?: { userids: undefined | string }) {
|
|
const { data } = await api.get<Array<UserLimit>>('users/balance/limit', {
|
|
params: filter,
|
|
});
|
|
this.user_limits = data;
|
|
},
|
|
|
|
async setLimits(limit: number) {
|
|
await api.put('users/balance/limit', { limit });
|
|
useUserStore().users.forEach((user) => {
|
|
const user_limit = this.user_limits.find((a) => a.userid === user.userid);
|
|
if (user_limit) {
|
|
user_limit.limit = limit;
|
|
} else {
|
|
this.user_limits.push({ userid: user.userid, limit });
|
|
}
|
|
});
|
|
},
|
|
|
|
async setLimit(limit: number, userid: string) {
|
|
await api.put(`users/${userid}/balance/limit`, { limit });
|
|
const user_limit = this.user_limits.find((a) => a.userid === userid);
|
|
if (user_limit) {
|
|
user_limit.limit = limit;
|
|
} else {
|
|
this.user_limits.push({ userid, limit });
|
|
}
|
|
},
|
|
},
|
|
});
|