Compare commits
4 Commits
86a06e8094
...
9584774d18
Author | SHA1 | Date |
---|---|---|
Tim Gröger | 9584774d18 | |
Tim Gröger | 59a430bea8 | |
Tim Gröger | ebffecd364 | |
Tim Gröger | 56b09abeaa |
|
@ -1,6 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="col-sm-4 col-xs-12">
|
<div class="col-sm-4 col-xs-12">
|
||||||
<q-input v-model.number="amount" type="number" filled label="Eigener Betrag" step="0.1" min="0" suffix="€" />
|
<q-input
|
||||||
|
v-model.number="amount"
|
||||||
|
ref="refAmount"
|
||||||
|
type="number"
|
||||||
|
filled
|
||||||
|
label="Eigener Betrag"
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
suffix="€"
|
||||||
|
:rules="[check_cent_step]"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 col-xs-6">
|
<div class="col-sm-4 col-xs-6">
|
||||||
<q-btn style="width: 100%" color="primary" label="Anschreiben" @click="changeBalance(amount * -1)">
|
<q-btn style="width: 100%" color="primary" label="Anschreiben" @click="changeBalance(amount * -1)">
|
||||||
|
@ -22,9 +32,11 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, PropType, computed, watch } from 'vue';
|
import { defineComponent, ref, PropType, computed, watch } from 'vue';
|
||||||
|
import { QInput } from 'quasar';
|
||||||
import { useBalanceStore } from '../store';
|
import { useBalanceStore } from '../store';
|
||||||
import { hasPermission, useUserStore } from '@flaschengeist/api';
|
import { hasPermission, useUserStore } from '@flaschengeist/api';
|
||||||
import PERMISSIONS from '../permissions';
|
import PERMISSIONS from '../permissions';
|
||||||
|
import { check_cent_step } from '../utils';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BalanceAddBody',
|
name: 'BalanceAddBody',
|
||||||
props: {
|
props: {
|
||||||
|
@ -44,12 +56,15 @@ export default defineComponent({
|
||||||
const store = useBalanceStore();
|
const store = useBalanceStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const amount = ref<number>(0);
|
const amount = ref<number>(0);
|
||||||
|
const refAmount = ref<QInput>();
|
||||||
async function changeBalance(amount: number) {
|
async function changeBalance(amount: number) {
|
||||||
await store.changeBalance(amount, user.value);
|
await refAmount.value?.validate();
|
||||||
|
if (amount != 0 && !refAmount.value?.hasError) await store.changeBalance(amount, user.value);
|
||||||
emit('change-balance', user.value);
|
emit('change-balance', user.value);
|
||||||
}
|
}
|
||||||
function addShortcut() {
|
async function addShortcut() {
|
||||||
if (amount.value != 0) void store.createShortcut(amount.value * -1);
|
await refAmount.value?.validate();
|
||||||
|
if (amount.value != 0 && !refAmount.value?.hasError) void store.createShortcut(amount.value * -1);
|
||||||
}
|
}
|
||||||
const canAddCredit = hasPermission(PERMISSIONS.CREDIT);
|
const canAddCredit = hasPermission(PERMISSIONS.CREDIT);
|
||||||
const user = computed(() =>
|
const user = computed(() =>
|
||||||
|
@ -60,7 +75,7 @@ export default defineComponent({
|
||||||
watch(amount, (a) => {
|
watch(amount, (a) => {
|
||||||
amount.value = Math.abs(a);
|
amount.value = Math.abs(a);
|
||||||
});
|
});
|
||||||
return { changeBalance, addShortcut, canAddCredit, amount };
|
return { changeBalance, addShortcut, canAddCredit, amount, check_cent_step, refAmount };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,8 +10,10 @@
|
||||||
<div v-if="showSelector" class="col-6">
|
<div v-if="showSelector" class="col-6">
|
||||||
<UserSelector v-model="user" />
|
<UserSelector v-model="user" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1 justify-end">
|
<div class="col">
|
||||||
<q-btn round flat icon="mdi-format-list-checks" @click="openHistory" />
|
<div class="row fit justify-end content-end items-end">
|
||||||
|
<q-btn round flat icon="mdi-format-list-checks" @click="openHistory" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="col-sm-4 col-xs-12">
|
<div class="col-sm-4 col-xs-12">
|
||||||
<q-input v-model.number="amount" type="number" filled label="Betrag" step="0.1" min="0" suffix="€" />
|
<q-input
|
||||||
|
v-model.number="amount"
|
||||||
|
ref="refAmount"
|
||||||
|
type="number"
|
||||||
|
filled
|
||||||
|
label="Betrag"
|
||||||
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
suffix="€"
|
||||||
|
:rules="[check_cent_step]"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 col-xs-6">
|
<div class="col-sm-4 col-xs-6">
|
||||||
<UserSelector v-model="receiver" label="Empfänger" />
|
<UserSelector v-model="receiver" label="Empfänger" />
|
||||||
|
@ -11,8 +21,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType, ref } from 'vue';
|
import { computed, defineComponent, PropType, ref } from 'vue';
|
||||||
|
import { QInput } from 'quasar';
|
||||||
import UserSelector from '@flaschengeist/users/src/components/UserSelector.vue';
|
import UserSelector from '@flaschengeist/users/src/components/UserSelector.vue';
|
||||||
import { useBalanceStore } from '../store';
|
import { useBalanceStore } from '../store';
|
||||||
|
import { check_cent_step } from '../utils';
|
||||||
import { useUserStore } from '@flaschengeist/api';
|
import { useUserStore } from '@flaschengeist/api';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BalanceTransferBody',
|
name: 'BalanceTransferBody',
|
||||||
|
@ -31,6 +43,7 @@ export default defineComponent({
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const receiver = ref<FG.User | undefined>(undefined);
|
const receiver = ref<FG.User | undefined>(undefined);
|
||||||
const amount = ref<number>(0);
|
const amount = ref<number>(0);
|
||||||
|
const refAmount = ref<QInput>();
|
||||||
const sender = computed(() =>
|
const sender = computed(() =>
|
||||||
(<FG.User>props.user).userid
|
(<FG.User>props.user).userid
|
||||||
? <FG.User>props.user
|
? <FG.User>props.user
|
||||||
|
@ -38,11 +51,18 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
|
|
||||||
const sendDisabled = computed(() => {
|
const sendDisabled = computed(() => {
|
||||||
return !(receiver.value && sender.value && sender.value.userid != receiver.value.userid && amount.value > 0);
|
return !(
|
||||||
|
receiver.value &&
|
||||||
|
sender.value &&
|
||||||
|
sender.value.userid != receiver.value.userid &&
|
||||||
|
amount.value > 0 &&
|
||||||
|
!refAmount.value?.hasError
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function sendAmount() {
|
async function sendAmount() {
|
||||||
if (receiver.value) {
|
await refAmount.value?.validate();
|
||||||
|
if (receiver.value && !refAmount.value?.hasError) {
|
||||||
await store.changeBalance(amount.value, receiver.value, sender.value);
|
await store.changeBalance(amount.value, receiver.value, sender.value);
|
||||||
emit('changeBalance', { sender: sender.value, receiver: receiver.value });
|
emit('changeBalance', { sender: sender.value, receiver: receiver.value });
|
||||||
}
|
}
|
||||||
|
@ -53,6 +73,8 @@ export default defineComponent({
|
||||||
amount,
|
amount,
|
||||||
sendAmount,
|
sendAmount,
|
||||||
sendDisabled,
|
sendDisabled,
|
||||||
|
refAmount,
|
||||||
|
check_cent_step,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,17 @@
|
||||||
<q-icon name="mdi-magnify" />
|
<q-icon name="mdi-magnify" />
|
||||||
</template>
|
</template>
|
||||||
</q-input>
|
</q-input>
|
||||||
<q-input v-model.number="limit" label="Limit" type="number" step="0.01" suffix="€" filled dense>
|
<q-input
|
||||||
|
ref="refLimit"
|
||||||
|
v-model.number="limit"
|
||||||
|
label="Limit"
|
||||||
|
type="number"
|
||||||
|
step="0.01"
|
||||||
|
suffix="€"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
:rules="[check_cent_step]"
|
||||||
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<q-btn
|
<q-btn
|
||||||
:icon="sign === '+' ? 'mdi-plus' : 'mdi-minus'"
|
:icon="sign === '+' ? 'mdi-plus' : 'mdi-minus'"
|
||||||
|
@ -107,6 +117,8 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, defineComponent, computed, onBeforeMount } from 'vue';
|
import { ref, defineComponent, computed, onBeforeMount } from 'vue';
|
||||||
|
import { QInput } from 'quasar';
|
||||||
|
import { check_cent_step } from '../utils';
|
||||||
import { useBalanceStore } from '../store';
|
import { useBalanceStore } from '../store';
|
||||||
import { useUserStore } from '@flaschengeist/api';
|
import { useUserStore } from '@flaschengeist/api';
|
||||||
import BalanceAddBody from '../components/BalanceAddBody.vue';
|
import BalanceAddBody from '../components/BalanceAddBody.vue';
|
||||||
|
@ -120,6 +132,7 @@ export default defineComponent({
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const showMenu = ref<{ [userid: string]: boolean }>({});
|
const showMenu = ref<{ [userid: string]: boolean }>({});
|
||||||
|
const refLimit = ref<QInput>();
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
void userStore.getUsers();
|
void userStore.getUsers();
|
||||||
|
@ -241,6 +254,10 @@ export default defineComponent({
|
||||||
if (sign.value === '-') {
|
if (sign.value === '-') {
|
||||||
l = -l;
|
l = -l;
|
||||||
}
|
}
|
||||||
|
await refLimit.value?.validate();
|
||||||
|
if (refLimit.value?.hasError) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
await store.setLimit(l, userid);
|
await store.setLimit(l, userid);
|
||||||
limit.value = undefined;
|
limit.value = undefined;
|
||||||
}
|
}
|
||||||
|
@ -257,10 +274,14 @@ export default defineComponent({
|
||||||
sign.value = sign.value === '+' ? '-' : '+';
|
sign.value = sign.value === '+' ? '-' : '+';
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLimits(l: number) {
|
async function setLimits(l: number) {
|
||||||
if (sign.value === '-') {
|
if (sign.value === '-') {
|
||||||
l = -l;
|
l = -l;
|
||||||
}
|
}
|
||||||
|
await refLimit.value?.validate();
|
||||||
|
if (refLimit.value?.hasError) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
void store.setLimits(l);
|
void store.setLimits(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,6 +306,8 @@ export default defineComponent({
|
||||||
showMenu,
|
showMenu,
|
||||||
sign,
|
sign,
|
||||||
changeSign,
|
changeSign,
|
||||||
|
check_cent_step,
|
||||||
|
refLimit,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
</q-list>
|
</q-list>
|
||||||
<q-list v-if="show">
|
<q-list v-if="show">
|
||||||
<div v-for="(transaction, index) in transactions" :key="index" class="col-sm-12">
|
<div v-for="(transaction, index) in transactions" :key="index" class="col-sm-12">
|
||||||
<balance-transaction v-model:transaction="transactions[index]" />
|
<balance-transaction v-model:transaction="transactions[index]" @update:transaction="updateBalance" />
|
||||||
</div>
|
</div>
|
||||||
</q-list>
|
</q-list>
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
|
@ -128,6 +128,7 @@ export default defineComponent({
|
||||||
tabs,
|
tabs,
|
||||||
transactions,
|
transactions,
|
||||||
show,
|
show,
|
||||||
|
updateBalance: () => balanceStore.getBalance(mainStore.currentUser),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
24
src/store.ts
24
src/store.ts
|
@ -131,14 +131,14 @@ export const useBalanceStore = defineStore({
|
||||||
user: FG.User,
|
user: FG.User,
|
||||||
filter:
|
filter:
|
||||||
| {
|
| {
|
||||||
limit?: number;
|
limit?: number;
|
||||||
offset?: number;
|
offset?: number;
|
||||||
from?: Date;
|
from?: Date;
|
||||||
to?: Date;
|
to?: Date;
|
||||||
showReversals?: boolean;
|
showReversals?: boolean;
|
||||||
showCancelled?: boolean;
|
showCancelled?: boolean;
|
||||||
descending?: boolean;
|
descending?: boolean;
|
||||||
}
|
}
|
||||||
| undefined = undefined
|
| undefined = undefined
|
||||||
) {
|
) {
|
||||||
if (!filter) filter = { limit: 10 };
|
if (!filter) filter = { limit: 10 };
|
||||||
|
@ -146,7 +146,13 @@ export const useBalanceStore = defineStore({
|
||||||
params: filter,
|
params: filter,
|
||||||
});
|
});
|
||||||
data.transactions.forEach((t) => fixTransaction(t));
|
data.transactions.forEach((t) => fixTransaction(t));
|
||||||
if (data.transactions) this.transactions.push(...data.transactions);
|
if (data.transactions) {
|
||||||
|
data.transactions.forEach((t) => {
|
||||||
|
const idx = this.transactions.findIndex((x) => x.id === t.id);
|
||||||
|
if (idx == -1) this.transactions.push(t);
|
||||||
|
else this.transactions[idx] = t;
|
||||||
|
});
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export function check_cent_step(value: number): boolean | string {
|
||||||
|
return (value * 100) % 1 === 0 || 'Betrag muss in 1-Cent-Schritten angegeben werden';
|
||||||
|
}
|
Loading…
Reference in New Issue