release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
21 changed files with 2543 additions and 33 deletions
Showing only changes of commit 3ea93fb800 - Show all commits

29
package-lock.json generated
View File

@ -1707,10 +1707,13 @@
"dev": true
},
"serialize-javascript": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.0.0.tgz",
"integrity": "sha512-skZcHYw2vEX4bw90nAr2iTTsz6x2SrHEnfxgKYmZlvJYBEZrvbKtobJWlQ20zczKb3bsHHXXTYt48zBA7ni9cw==",
"dev": true
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz",
"integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"source-map": {
"version": "0.6.1",
@ -4538,9 +4541,9 @@
"dev": true
},
"elliptic": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
"integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
"dev": true,
"requires": {
"bn.js": "^4.4.0",
@ -6842,9 +6845,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"lodash.defaultsdeep": {
@ -11026,9 +11029,9 @@
"dev": true
},
"vuetify": {
"version": "2.2.29",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.2.29.tgz",
"integrity": "sha512-UI1i8kEdV+s7tNQe2yJJMPlvxGTE8cZfUAXEGV2yO4owHmeybn6p5YzFpJqimoKkfX6ok+zV29+6yIKfkyUDAA=="
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.3.9.tgz",
"integrity": "sha512-E5K9flTvS21tCkHgqDBMl0BY/Rld4SLUaJpQ+sQdL8/2uPcWmWLrdumn4SI8LBFojE0UP1GSaH4zKuxLL36fYg=="
},
"vuetify-loader": {
"version": "1.4.4",

View File

@ -13,7 +13,7 @@
"core-js": "^3.6.5",
"vue": "^2.6.10",
"vue-router": "^3.2.0",
"vuetify": "^2.2.29",
"vuetify": "^2.3.8",
"vuex": "^3.4.0"
},
"devDependencies": {

View File

@ -0,0 +1,433 @@
<template>
<div>
<v-container v-if="!first_loading">
<v-card class="mx-auto" outlined :loading="loading">
<v-card-title>
<div class="title">Dienstgetränke</div>
<v-chip class="ma-2" color="red" text-color="white" v-if="locked"
>Gesperrt</v-chip
>
<v-btn class="menuBtn" @click.stop="isMenuShow = !isMenuShow" icon>
<v-icon>{{ menuIcon }}</v-icon>
</v-btn>
</v-card-title>
<v-card-subtitle v-if="limit - free_drink_list_history_job_credit > 0">
Noch
{{ ((limit - free_drink_list_history_job_credit) / 100).toFixed(2) }}
übrig!!
</v-card-subtitle>
<v-card-text>
<v-row v-if="!first_loading">
<v-col cols="12">
<v-row>
<v-col
v-for="freeDrink in free_drink_list_config_job"
:key="freeDrink.id"
cols="6"
xs="3"
sm="4"
class="drinkCol"
>
<v-btn
class="drinkBtn"
block
:disabled="locked"
:color="color"
@click="addAmount(freeDrink, freeDrinkTypeJob)"
>{{ freeDrink.label }}</v-btn
>
</v-col>
</v-row>
<v-row v-if="!first_loading" class="justify-end">
<v-col cols="3">
<v-list-item>
<v-list-item-content class="text-center">
<v-list-item-action-text :class="getColor()">
{{
(free_drink_list_history_job_credit / 100).toFixed(2)
}}
</v-list-item-action-text>
</v-list-item-content>
</v-list-item>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card-text>
</v-card>
<v-card class="mx-auto" outlined :loading="loading">
<v-card-title>
<div class="title">Bandgetränke</div>
<v-btn class="menuBtn" @click.stop="isMenuShow = !isMenuShow" icon>
<v-icon>{{ menuIcon }}</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<v-row v-if="!first_loading">
<v-col cols="12">
<v-row>
<v-col
v-for="freeDrink in free_drink_list_config_band"
:key="freeDrink.id"
cols="6"
xs="3"
sm="4"
class="drinkCol"
>
<v-btn
class="drinkBtn"
block
:color="color_fix"
@click="addAmount(freeDrink, freeDrinkTypeBand)"
>{{ freeDrink.label }}</v-btn
>
</v-col>
</v-row>
<v-row v-if="!first_loading" class="justify-end">
<v-col cols="3">
<v-list-item>
<v-list-item-content class="text-center">
<v-list-item-action-text class="title">
{{
free_drink_list_history_band_without_canceled.length
}}
Getränke
</v-list-item-action-text>
</v-list-item-content>
</v-list-item>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-container>
<v-navigation-drawer v-model="isMenuShow" right app clipped>
<v-list-item-group :key="componentRenderer">
<v-list-item inactive>
<v-list-item-title class="headline">Verlauf</v-list-item-title>
</v-list-item>
<v-divider />
<div
v-for="freeDrinkHistory in free_drink_list_history"
:key="freeDrinkHistory.id"
>
<v-list-item
three-line
inactive
@click="canceledAmount(freeDrinkHistory)"
>
<v-list-item-content>
<v-list-item-title>{{
now(freeDrinkHistory.timestamp)
}}</v-list-item-title>
<v-list-item-subtitle
>{{ freeDrinkHistory.free_drink_type.name }}:
{{ freeDrinkHistory.free_drink_config.label }} wurde für
{{
(freeDrinkHistory.free_drink_config.price / 100).toFixed(2)
}}
hinzugefügt.
</v-list-item-subtitle>
<v-list-item-subtitle
class="red--text"
v-if="freeDrinkHistory.canceled"
>STORNIERT!!!</v-list-item-subtitle
>
<v-list-item-action-text
v-if="
isStronoEnabled(freeDrinkHistory.timestamp) &&
!freeDrinkHistory.canceled
"
>Klicken um zu Stornieren</v-list-item-action-text
>
</v-list-item-content>
</v-list-item>
</div>
</v-list-item-group>
</v-navigation-drawer>
<v-dialog v-model="showConfirmCanceledDialog" max-width="290">
<v-card>
<v-card-title>Willst du wirklich??</v-card-title>
<v-card-text v-if="canceledMessage">
{{ canceledMessage.free_drink_type.name }}: Willst du wirklich ein
{{ canceledMessage.free_drink_config.label }} im Wert von
{{ (canceledMessage.free_drink_config.price / 100).toFixed(2) }}
stornieren?
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn text @click="cancelCanceled">Abbrechen</v-btn>
<v-btn text @click="acceptCanceled">Stornieren</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-container v-if="first_loading">
<AddAmountSkeleton />
</v-container>
<v-snackbar
:color="
snackbar_messages.length > 0
? snackbar_messages[0].error
? 'error'
: 'success'
: 'success'
"
bottom
:timeout="0"
:multi-line="true"
:value="snackbar_messages.length > 0 ? snackbar_messages[0].visible : null"
vertical
>
<v-list-item
v-for="(message, index) in snackbar_messages"
:key="index"
:style="
message.error
? 'background-color: #FF5252;'
: 'background-color: #4CAF50;'
"
v-show="message.visible"
>
<v-list-item-content>
<v-list-item-title style="color: white">
{{ createMessage(message) }}
</v-list-item-title>
</v-list-item-content>
<v-list-item-action v-if="message.error">
<v-btn icon @click="message.visible = false">
<v-icon color="white">
mdi-close
</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-snackbar>
</div>
</template>
<script>
// eslint-disable-next-line no-unused-vars
import AddAmountSkeleton from '../user/Skeleton/AddAmountSkeleton'
import { mapActions, mapGetters } from 'vuex'
import { mdiPlus, mdiMenu } from '@mdi/js'
export default {
name: 'BarFreedrinks',
components: { AddAmountSkeleton },
created() {
this.timer = setInterval(() => (this.componentRenderer += 1), 1000)
this.get_free_drink_list_config()
this.get_free_drink_list_history()
},
data() {
return {
plus: mdiPlus,
menuIcon: mdiMenu,
showConfirmCanceledDialog: false,
canceledMessage: null,
limit: 1000,
amount: 0,
customValue: null,
color: 'green accent-4',
color_fix: 'green accent-4',
timer: '',
componentRenderer: 0,
isMenuShow: false,
freeDrinkTypeJob: 1,
freeDrinkTypeBand: 3
}
},
methods: {
...mapActions('freeDrinkList', [
'get_free_drink_list_config',
'get_free_drink_list_history',
'set_free_drink_list_history',
'update_free_drink_list_history'
]),
output() {
console.log(this.free_drink_list_config)
},
addAmount(freeDrink, free_drink_type_id) {
this.set_free_drink_list_history({ ...freeDrink, free_drink_type_id })
/*if (amount) {
this.amount += amount
this.generateMessage(amount)
}
this.checkLocked()*/
},
canceledAmount(historyElement) {
if (!this.isStronoEnabled(historyElement.timestamp)) {
return
}
this.showConfirmCanceledDialog = true
this.canceledMessage = historyElement
},
cancelCanceled() {
this.showConfirmCanceledDialog = null
this.canceledMessage = null
},
generateMessage(amount) {
this.messages.push({
date: new Date(),
canceled: false,
amount: amount,
error: false,
visible: true
})
},
createMessage(message) {
var text = ''
if (message.error) {
text =
'ERROR: ' + message.free_drink_type.name +': Konnte ' + message.label + ' für ' +
(message.price / 100).toFixed(2) +
'€ nicht hinzufügen.'
} else {
text = message.free_drink_type.name + ': ' + message.label + ' wurde für ' + (message.price / 100).toFixed(2) + '€ hinzugefügt.'
}
return text
},
checkLocked() {
this.locked = this.limit - this.amount <= 0
},
getColor() {
return this.locked ? 'title red--text' : 'title'
},
acceptCanceled() {
this.canceledMessage.canceled = true
this.update_free_drink_list_history(this.canceledMessage)
this.cancelCanceled()
},
acceptStorno() {
this.stornoMessage.storno = true
this.amount -= this.stornoMessage.amount
console.log(this.amount, this.stornoMessage)
this.cancelStorno()
},
stornoAmount(message) {
if (!this.isStronoEnabled(message.date) || message.storno) {
return
}
this.showConfirmStornoDialog = true
this.stornoMessage = message
},
cancelStorno() {
this.showConfirmStornoDialog = null
this.stornoMessage = null
},
},
computed: {
...mapGetters('freeDrinkList', [
'free_drink_list_config_job',
'free_drink_list_config_band',
'free_drink_list_history',
'free_drink_list_history_job_credit',
'free_drink_list_history_band',
'free_drink_list_history_band_without_canceled',
'loading',
'snackbar_messages'
]),
now() {
return now => {
var actual = new Date()
var zero = new Date(0)
var date = new Date(actual - now)
if (date.getFullYear() === zero.getFullYear()) {
if (date.getMonth() === zero.getMonth()) {
if (date.getDate() === zero.getDate()) {
if (date.getHours() === zero.getDate()) {
if (date.getMinutes() < 1) {
return 'vor ' + date.getSeconds() + ' Sekunden'
} else if (date.getMinutes() < 10) {
return 'vor ' + date.getMinutes() + ' Minuten'
} else {
return (
(now.getHours() < 10 ? '0' : '') +
now.getHours() +
':' +
(now.getMinutes() < 10 ? '0' : '') +
now.getMinutes()
)
}
} else {
return (
(now.getHours() < 10 ? '0' : '') +
now.getHours() +
':' +
(now.getMinutes() < 10 ? '0' : '') +
now.getMinutes()
)
}
}
}
}
return (
now.getDate() +
'.' +
now.getMonth() +
'.' +
now.getFullYear() +
' ' +
(now.getHours() < 10 ? '0' : '') +
now.getHours() +
':' +
(now.getMinutes() < 10 ? '0' : '') +
now.getMinutes()
)
}
},
isStronoEnabled() {
return now => {
var actual = new Date()
return actual - now < 60000
}
},
locked() {
return this.free_drink_list_history_job_credit >= 1000
},
first_loading() {
return (
this.loading &&
this.free_drink_list_history.length == 0 &&
this.free_drink_list_config_band.length == 0 &&
this.free_drink_list_config_job.length == 0
)
}
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>
<style scoped>
.drinkBtn {
width: 100%;
}
.drinkCol {
padding: 6px !important;
}
.title {
width: calc(100% - 135px);
min-width: 150px;
font-size: 1.25rem !important;
font-weight: 500;
line-height: 2rem;
letter-spacing: 0.0125em !important;
font-family: 'Roboto', sans-serif !important;
}
.menuBtn {
right: 15px;
position: absolute;
}
.history-item {
cursor: pointer;
}
</style>

View File

@ -8,16 +8,25 @@
Geruecht
</v-list-item-title>
</v-list-item>
<v-list-item link :to="{name: 'baruserFreedrinks'}">
<v-list-item-icon>
<v-icon>{{ beer }}</v-icon>
</v-list-item-icon>
<v-list-item-title>
Freigetränke
</v-list-item-title>
</v-list-item>
</v-list>
</template>
<script>
import { mdiGlassMugVariant } from '@mdi/js'
import { mdiGlassMugVariant,mdiBeer } from '@mdi/js'
export default {
name: 'BarNavigation',
data() {
return {
glass_mug_variant: mdiGlassMugVariant
glass_mug_variant: mdiGlassMugVariant,
beer: mdiBeer
}
}
}

View File

@ -106,6 +106,7 @@ export default {
return retUser ? retUser.amount : 0
},
getLocked(user) {
if(!user) return
let retUser = this.users.find(item => {
return item.username === user.username
})

View File

@ -4,9 +4,13 @@
<v-list-item-icon>
<v-icon>{{ account }}</v-icon>
</v-list-item-icon>
<v-list-item-title>
Home
</v-list-item-title>
<v-list-item-title>Home</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'freedrinkUser' }">
<v-list-item-icon>
<v-icon>{{ beer }}</v-icon>
</v-list-item-icon>
<v-list-item-title>Freigetränk buchen</v-list-item-title>
</v-list-item>
<v-list-item link :to="{ name: 'userOverview' }">
<v-list-item-icon>
@ -25,21 +29,14 @@
}"
>
<v-list-item-icon>
<v-icon>
{{ briefcase }}
</v-icon>
<v-icon>{{ briefcase }}</v-icon>
</v-list-item-icon>
<v-list-item-title>Dienstübersicht</v-list-item-title>
</v-list-item>
<v-list-item
link
:to="{ name: 'jobRequests', params: { kind: 'jobInvites' } }"
>
<v-list-item link :to="{ name: 'jobRequests', params: { kind: 'jobInvites' } }">
<v-list-item-icon>
<v-badge overlap color="red" :content="news" :value="news !== 0">
<v-icon>
{{ switchAccount }}
</v-icon>
<v-icon>{{ switchAccount }}</v-icon>
</v-badge>
</v-list-item-icon>
<v-list-item-title>Dienstanfragen</v-list-item-title>
@ -59,7 +56,8 @@ import {
mdiHome,
mdiBank,
mdiBriefcase,
mdiAccountSwitch
mdiAccountSwitch,
mdiBeer
} from '@mdi/js'
import { mapGetters, mapActions } from 'vuex'
@ -71,7 +69,8 @@ export default {
account: mdiHome,
bank: mdiBank,
briefcase: mdiBriefcase,
switchAccount: mdiAccountSwitch
switchAccount: mdiAccountSwitch,
beer: mdiBeer
}
},
methods: {
@ -93,7 +92,6 @@ export default {
},
created() {
this.getUser()
},
watch: {
loading(newValue) {

View File

@ -0,0 +1,472 @@
<template>
<div>
<v-container>
<v-card class="mx-auto" outlined v-if="!first_loading" :loading="loading">
<v-card-title>
<div class="title">Freigetränk für Versammlungen/Arbeit</div>
<v-btn class="menuBtn" @click.stop="isMenuShow = !isMenuShow" icon>
<v-icon>{{ menuIcon }}</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<v-row v-if="!first_loading">
<v-col cols="12">
<v-row>
<v-col
v-for="freeDrink in free_drink_list_config_workgroup"
:key="freeDrink.id"
cols="6"
xs="3"
sm="4"
class="drinkCol"
>
<v-btn
class="drinkBtn"
block
:color="color_fix"
@click="addAmount(freeDrink, freeDrinkTypeWorkgroup)"
>{{ freeDrink.label }}</v-btn
>
</v-col>
</v-row>
<v-row v-if="!first_loading" class="justify-end">
<v-col cols="3">
<v-list-item>
<v-list-item-content class="text-center">
<v-list-item-action-text class="title">
{{
free_drink_list_history_workgroup_without_canceled.length
}}
Getränke
</v-list-item-action-text>
</v-list-item-content>
</v-list-item>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-container>
<v-navigation-drawer v-model="isMenuShow" right app clipped>
<v-list-item-group :key="componentRenderer">
<v-list-item inactive>
<v-list-item-title class="headline">Verlauf</v-list-item-title>
</v-list-item>
<v-divider />
<div
v-for="freeDrinkHistory in free_drink_list_history_workgroup"
:key="freeDrinkHistory.id"
>
<v-list-item
three-line
inactive
@click="canceledAmount(freeDrinkHistory)"
>
<v-list-item-content>
<v-list-item-title>{{
now(freeDrinkHistory.timestamp)
}}</v-list-item-title>
<v-list-item-subtitle>
{{ freeDrinkHistory.free_drink_config.label }} wurde für
{{
(freeDrinkHistory.free_drink_config.price / 100).toFixed(2)
}}
hinzugefügt.
</v-list-item-subtitle>
<v-list-item-subtitle
class="red--text"
v-if="freeDrinkHistory.canceled"
>STORNIERT!!!</v-list-item-subtitle
>
<v-list-item-action-text
v-if="
isStronoEnabled(freeDrinkHistory.timestamp) &&
!freeDrinkHistory.canceled
"
>Klicken um zu Stornieren</v-list-item-action-text
>
</v-list-item-content>
</v-list-item>
</div>
</v-list-item-group>
</v-navigation-drawer>
<v-dialog v-model="showConfirmCanceledDialog" max-width="290">
<v-card>
<v-card-title>Willst du wirklich??</v-card-title>
<v-card-text v-if="canceledMessage">
{{ canceledMessage.free_drink_type.name }}: Willst du wirklich ein
{{ canceledMessage.free_drink_config.label }} im Wert von
{{ (canceledMessage.free_drink_config.price / 100).toFixed(2) }}
stornieren?
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn text @click="cancelCanceled">Abbrechen</v-btn>
<v-btn text @click="acceptCanceled">Stornieren</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="showReasonDialog" max-width="290">
<v-card>
<v-card-title>Willst du wirklich??</v-card-title>
<v-card-text>
<v-combobox
v-model="selectedReason"
:items="free_drink_list_reasons"
item-value="id"
item-text="name"
label="Grund fürs Getränk"
></v-combobox>
<v-textarea
label="Beschreibung"
v-model="reasonDescription"
></v-textarea>
<v-text-field
type="number"
label="Anzahl der Getränke"
v-model="drinkCount"
></v-text-field>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn text @click="cancelFreedrink">Abbrechen</v-btn>
<v-btn text @click="confirmFreeDrink">Bestätigen</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-container v-if="first_loading">
<AddAmountSkeleton />
</v-container>
<v-snackbar
:color="
snackbar_messages.length > 0
? snackbar_messages[0].error
? 'error'
: 'success'
: 'success'
"
bottom
:timeout="0"
:multi-line="true"
:value="
snackbar_messages.length > 0 ? snackbar_messages[0].visible : null
"
vertical
>
<v-list-item
v-for="(message, index) in snackbar_messages"
:key="index"
:style="
message.error
? 'background-color: #FF5252;'
: 'background-color: #4CAF50;'
"
v-show="message.visible"
>
<v-list-item-content>
<v-list-item-title style="color: white">
{{ createMessage(message) }}
</v-list-item-title>
</v-list-item-content>
<v-list-item-action v-if="message.error">
<v-btn icon @click="message.visible = false">
<v-icon color="white">
mdi-close
</v-icon>
</v-btn>
</v-list-item-action>
</v-list-item>
</v-snackbar>
</div>
</template>
<script>
// eslint-disable-next-line no-unused-vars
import AddAmountSkeleton from '../Skeleton/AddAmountSkeleton'
import { mapGetters, mapActions } from 'vuex'
import { mdiPlus, mdiMenu } from '@mdi/js'
export default {
name: 'FreedrinkUserView',
components: { AddAmountSkeleton },
created() {
// this.timer = setInterval(() => (this.componentRenderer += 1), 1000)
this.get_free_drink_list_config()
this.get_free_drink_list_history()
this.get_free_drink_list_reasons()
},
data() {
return {
plus: mdiPlus,
menuIcon: mdiMenu,
locked: false,
showConfirmCanceledDialog: false,
showReasonDialog: false,
customValue: null,
color: 'green accent-4',
color_fix: 'green accent-4',
messages: [],
amount: 0,
free_drink: null,
free_drink_type_id: null,
selectedDrink: null,
drinkCount: 1,
timer: '',
componentRenderer: 0,
isMenuShow: false,
selectedReason: null,
reasonDescription: null,
freeDrinkTypeWorkgroup: 2,
snackbarTimeout: 3000,
canceledMessage: null
}
},
methods: {
...mapActions('freeDrinkList', [
'get_free_drink_list_config',
'get_free_drink_list_history',
'get_free_drink_list_reasons',
'set_free_drink_list_history',
'update_free_drink_list_history'
]),
getReason() {
const reasonArray = []
if (!this.user) {
return
}
if (this.user.group.includes('user')) {
reasonArray.push('AG-Besprechung')
reasonArray.push('AGDSN')
}
if (this.user.group.includes('bar')) {
reasonArray.push('Dienstantrittsschnaps')
}
if (this.user.group.includes('vorstand')) {
reasonArray.push('Vorstandssitzung')
reasonArray.push('Vermietungsgespräch')
}
if (this.user.group.includes('gastro')) {
reasonArray.push('Helmke-Fahrern')
reasonArray.push('Vertretergespräch')
}
return reasonArray
},
addAmount(free_drink, free_drink_type_id) {
if (free_drink) {
this.showReasonDialog = true
this.free_drink = free_drink
this.free_drink_type_id = free_drink_type_id
}
},
stornoAmount(message) {
if (!this.isStronoEnabled(message.date) || message.storno) {
return
}
this.showConfirmStornoDialog = true
this.stornoMessage = message
},
cancelStorno() {
this.showConfirmStornoDialog = null
this.stornoMessage = null
},
confirmFreeDrink() {
if (this.drinkCount >= 0) {
this.set_free_drink_list_history({
...this.free_drink,
free_drink_type_id: this.free_drink_type_id,
free_drink_list_reason_id: this.selectedReason.id,
description: this.reasonDescription,
count: this.drinkCount
})
}
this.cancelFreedrink()
},
cancelFreedrink() {
this.showReasonDialog = false
this.amount = null
this.selectedReason = null
this.reasonDescription = null
this.drinkCount = 0
this.free_drink_type_id = null
this.free_drink = null
},
generateMessage() {
this.messages.push({
date: new Date(),
storno: false,
amount: this.amount,
reasonDescription: this.reasonDescription,
selectedReason: this.selectedReason,
drinkCount: this.drinkCount
})
},
createMessage(message) {
var text = ''
if (message.error) {
text =
'ERROR: ' +
message.free_drink_type.name +
': Konnte ' +
message.label +
' für ' +
(message.price / 100).toFixed(2) +
'€ nicht hinzufügen.'
} else {
text =
message.free_drink_type.name +
': ' +
message.label +
' wurde für ' +
(message.price / 100).toFixed(2) +
'€ hinzugefügt.'
}
return text
},
checkLocked() {
this.locked = this.limit - this.amount <= 0
},
getColor() {
return this.locked ? 'title red--text' : 'title'
},
acceptStorno() {
this.stornoMessage.storno = true
this.amount -= this.stornoMessage.amount
console.log(this.amount, this.stornoMessage)
this.cancelStorno()
},
acceptCanceled() {
this.canceledMessage.canceled = true
this.update_free_drink_list_history(this.canceledMessage)
this.cancelCanceled()
},
canceledAmount(historyElement) {
if (!this.isStronoEnabled(historyElement.timestamp)) {
return
}
this.showConfirmCanceledDialog = true
this.canceledMessage = historyElement
},
cancelCanceled() {
this.showConfirmCanceledDialog = null
this.canceledMessage = null
},
},
computed: {
...mapGetters({
user: 'user/user'
}),
...mapGetters('freeDrinkList', [
'free_drink_list_config_workgroup',
'free_drink_list_history',
'loading',
'free_drink_list_reasons',
'free_drink_list_reasons_loading',
'free_drink_list_history_workgroup_without_canceled',
'free_drink_list_history_workgroup',
'snackbar_messages'
]),
now() {
return now => {
var actual = new Date()
var zero = new Date(0)
var date = new Date(actual - now)
if (date.getFullYear() === zero.getFullYear()) {
if (date.getMonth() === zero.getMonth()) {
if (date.getDate() === zero.getDate()) {
if (date.getHours() === zero.getDate()) {
if (date.getMinutes() < 1) {
return 'vor ' + date.getSeconds() + ' Sekunden'
} else if (date.getMinutes() < 10) {
return 'vor ' + date.getMinutes() + ' Minuten'
} else {
return (
(now.getHours() < 10 ? '0' : '') +
now.getHours() +
':' +
(now.getMinutes() < 10 ? '0' : '') +
now.getMinutes()
)
}
} else {
return (
(now.getHours() < 10 ? '0' : '') +
now.getHours() +
':' +
(now.getMinutes() < 10 ? '0' : '') +
now.getMinutes()
)
}
}
}
}
return (
now.getDate() +
'.' +
now.getMonth() +
'.' +
now.getFullYear() +
' ' +
(now.getHours() < 10 ? '0' : '') +
now.getHours() +
':' +
(now.getMinutes() < 10 ? '0' : '') +
now.getMinutes()
)
}
},
isStronoEnabled() {
return now => {
var actual = new Date()
return actual - now < 60000
}
},
first_loading() {
return (
this.loading &&
this.free_drink_list_history.length == 0 &&
this.free_drink_list_config_workgroup.length == 0
)
}
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>
<style scoped>
.drinkBtn {
width: 100%;
}
.drinkCol {
padding: 6px !important;
}
.title {
width: calc(100% - 135px);
min-width: 150px;
font-size: 1.25rem !important;
font-weight: 500;
line-height: 2rem;
letter-spacing: 0.0125em !important;
font-family: 'Roboto', sans-serif !important;
}
.menuBtn {
right: 15px;
position: absolute;
}
.history-item {
cursor: pointer;
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<div>
<v-bottom-navigation v-model="bottom_nav" horizontal>
<v-btn link :to="{ name: 'freeDrinkListMain' }">
<span>Übersicht</span>
</v-btn>
<v-btn link :to="{name: 'freeDrinkListJob'}">
<span>Dienstgetränke</span>
</v-btn>
<v-btn link :to="{name: 'freeDrinkListWorkgroup'}">
<span>AG-Getränke</span>
</v-btn>
<v-btn link :to="{name: 'freeDrinkListBand'}">
<span>Bandgetränke</span>
</v-btn>
<v-btn link :to="{ name: 'freeDrinkListConfig' }">
<span>Einstellungen</span>
<v-icon>mdi-cogs</v-icon>
</v-btn>
</v-bottom-navigation>
<v-toolbar v-if="$route.name != 'freeDrinkListConfig'" flat dense>
<v-spacer/>
<v-toolbar-items>
<v-btn icon @click="change_month(-1)">
<v-icon>mdi-chevron-left</v-icon>
</v-btn>
<v-item>
<v-list-item-title>
{{month[date.getMonth()]}} {{date.getFullYear()}}
</v-list-item-title>
</v-item>
<v-btn icon @click="change_month(1)">
<v-icon>mdi-chevron-right</v-icon>
</v-btn>
</v-toolbar-items>
<v-spacer/>
</v-toolbar>
<v-progress-linear indeterminate v-if="loading" />
<div>
<router-view />
</div>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
export default {
name: 'FreeDrinkList',
data() {
return {
bottom_nav: true,
date: new Date(),
month: [
'Januar',
'Februar',
'März',
'April',
'Mai',
'Juni',
'Juli',
'August',
'September',
'Oktober',
'November',
'Dezember'
]
}
},
created() {
this.get_free_drink_list_reasons()
this.get_free_drink_list_config()
this.get_free_drink_list_history_from_to({
from_date: {
year: this.from_date.getFullYear(),
month: this.from_date.getMonth() + 1,
day: 1
},
to_date: {
year: this.to_date.getFullYear(),
month: this.to_date.getMonth() + 1,
day: 1
}
})
this.get_free_drink_types()
this.getPriceList()
},
methods: {
...mapActions('freeDrinkList', [
'get_free_drink_list_config',
'get_free_drink_list_history_from_to',
'get_free_drink_list_reasons',
'get_free_drink_types',
]),
...mapActions('priceList', ['getPriceList']),
change_month(payload) {
this.date = new Date(this.date.getFullYear(), this.date.getMonth() + payload, 1)
}
},
computed: {
...mapGetters('freeDrinkList', [
'free_drink_list_config_loading',
'free_drink_list_history_loading',
'free_drink_list_reasons_loading',
'free_drink_types_loading'
]),
...mapGetters('priceList', [
'priceListLoading'
]),
to_date() {
return new Date(this.date.getFullYear(), this.date.getMonth()+1,1)
},
from_date() {
return new Date(this.date.getFullYear(), this.date.getMonth(), 1)
},
loading() {
return this.free_drink_types_loading || this.free_drink_list_reasons_loading || this.free_drink_list_history_loading || this.free_drink_list_config_loading || this.priceListLoading
}
},
watch: {
date() {
this.get_free_drink_list_history_from_to({
from_date: {
year: this.from_date.getFullYear(),
month: this.from_date.getMonth() + 1,
day: 1
},
to_date: {
year: this.to_date.getFullYear(),
month: this.to_date.getMonth() + 1,
day: 1
}
})
}
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,123 @@
<template>
<div>
<v-row justify="space-around">
<v-card>
<v-card-title class="text-center">
Anzahl Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{free_drink_list_history_band_without_canceled.length}}
</v-card-text>
</v-card>
<v-card>
<v-card-title class="text-center">
Summe Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ (sum/100).toFixed(2)}}
</v-card-text>
</v-card>
</v-row>
<v-data-table :headers="header" :items="table"/>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: "FreeDrinkListBand",
data() {
return {
header: [
{
text: 'Datum',
value: 'date'
},
{
text: 'Label Freigetränk',
value: 'label'
},
{
text: 'Freigetränk',
value: 'name'
},
{
text: 'Anzahl',
value: 'count'
},
{
text: 'User',
value: 'user'
},
{
text: 'Preis pro Getränk',
value: 'pricepro'
},
{
text: 'Preis gesamt',
value: 'sum'
}
]
}
},
computed: {
...mapGetters('freeDrinkList', ['free_drink_list_history_band_without_canceled', 'free_drink_list_config']),
sum() {
let sum = 0
this.free_drink_list_history_band_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
table() {
if (this.free_drink_list_history_band_without_canceled.length == 0) {
return []
}
let retVal = []
const date_month = this.free_drink_list_history_band_without_canceled[0].timestamp
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
for (let day = 1; day <= days; day++) {
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
let history_of_date = this.free_drink_list_history_band_without_canceled.filter(item => {
return item.timestamp >= from && item.timestamp <= to && !item.canceled
})
this.free_drink_list_config.forEach(drink_config => {
let history_of_config = history_of_date.filter(item => {
return item.free_drink_config_id == drink_config.id
})
// eslint-disable-next-line no-unused-vars
let users = []
history_of_config.forEach(history_config => {
if (!users.find(user_id => { return user_id == history_config.user_id})) {
users.push(history_config.user_id)
}
})
users.forEach(user_id => {
let history_of_user = history_of_config.filter(item => {
return item.user_id == user_id
})
if (history_of_user.length > 0) {
retVal.push({
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
label: drink_config.label,
name: drink_config.drink.name,
user: `${history_of_user[0].user.firstname} ${history_of_user[0].user.lastname}`,
count: history_of_user.length,
pricepro: (drink_config.price / 100).toFixed(2),
sum: (drink_config.price / 100 * history_of_user.length).toFixed(2)
})
}
})
})
}
return retVal
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,212 @@
<template>
<div>
<v-card tile>
<v-card-title>
Freigetränke
</v-card-title>
<v-card-text>
<v-list>
<template
v-for="(free_drink_config, index) in free_drink_list_config">
<v-list-item
:key="free_drink_config.label"
dense
>
<v-list-item-content>
<FreeDrinkListConfigConfigItem :free_drink_config="free_drink_config" @save="save" @delete_free_drink_list_config="delete_free_drink_config" />
</v-list-item-content>
</v-list-item>
<v-divider
v-if="(index + 1 < free_drink_list_config.length) || new_free_drink_list_config"
:key="index"
/>
</template>
<v-list-item v-if="new_free_drink_list_config">
<v-list-item-content>
<FreeDrinkListConfigConfigItem :free_drink_config="default_model" @save="save" @delete_free_drink_config="new_free_drink_list_config=false"/>
</v-list-item-content>
</v-list-item>
</v-list>
</v-card-text>
<v-card-actions dense>
<v-spacer />
<v-btn fab small color="success" @click="new_free_drink_list_config=true" v-if="!new_free_drink_list_config">
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-card-actions>
</v-card>
<v-card tile>
<v-card-title>Gründe für Freigetränke</v-card-title>
<v-card-text>
<v-list>
<template
v-for="(free_drink_reason, index) in free_drink_list_reasons">
<v-list-item
:key="free_drink_reason.name"
dense
>
<v-list-item-content>
<FreeDrinkListConfigReasonItem :free_drink_reason="free_drink_reason" @save="save_reason" @delete_free_drink_list_reason="delete_free_drink_reason" />
</v-list-item-content>
</v-list-item>
<v-divider
v-if="(index + 1 < free_drink_list_reasons.length) || new_free_drink_list_reason"
:key="index"
/>
</template>
<v-list-item v-if="new_free_drink_list_reason">
<v-list-item-content>
<FreeDrinkListConfigReasonItem :free_drink_reason="default_model_reason" @save="save_reason" @delete_free_drink_reason="new_free_drink_list_reason=false"/>
</v-list-item-content>
</v-list-item>
</v-list>
</v-card-text>
<v-card-actions dense>
<v-spacer />
<v-btn fab small color="success" @click="new_free_drink_list_reason=true" v-if="!new_free_drink_list_reason">
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-card-actions>
</v-card>
<v-dialog v-model="check_delete_free_drink_list_config" max-width="400">
<v-card>
<v-card-title>
Wirklich löschen?
</v-card-title>
<v-card-text>
Willst du wirklich <span class="font-weight-black">{{check_model.label}}</span> mit dem Getränk <span class="font-weight-black">{{check_model.drink.name}}</span> löschen?
Wenn du dies löscht, wird auch der ganze Verlauf gelöscht. Dh. es ist nicht mehr vollständig nachvollziehbar, was getrunken wurde.
</v-card-text>
<v-card-actions>
<v-spacer/>
<v-btn @click="cancel_delete()">Abbrechen</v-btn>
<v-btn @click="accept_delete()" color="error">Löschen</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="check_delete_free_drink_list_reason" max-width="400">
<v-card>
<v-card-title>
Wirklich löschen?
</v-card-title>
<v-card-text>
Willst du wirklich den Grund <span class="font-weight-black">{{check_model_reason.name}}</span> löschen?
Wenn du dies löscht, wird auch der im Verlauf alle dieser Gründe gelöscht.. Dh. es ist nicht mehr vollständig nachvollziehbar, aus welchem Grund ein Freigetränk rausgegeben wurde.
</v-card-text>
<v-card-actions>
<v-spacer/>
<v-btn @click="cancel_delete_reason()">Abbrechen</v-btn>
<v-btn @click="accept_delete_reason()" color="error">Löschen</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
import { mapGetters, mapActions} from 'vuex'
import FreeDrinkListConfigConfigItem
from '@/components/vorstand/FreeDrinkList/FreeDrinkListConfigComponents/FreeDrinkListConfigConfigItem'
import FreeDrinkListConfigReasonItem
from '@/components/vorstand/FreeDrinkList/FreeDrinkListConfigComponents/FreeDrinkListConfigReasonItem'
export default {
name: 'FreeDrinkListConfig',
components: { FreeDrinkListConfigConfigItem, FreeDrinkListConfigReasonItem },
data() {
return {
new_free_drink_list_config: false,
new_free_drink_list_reason: false,
default_model: {
id: -1,
label: null,
free_drink_types: null,
drink: null,
price: null
},
check_model: {
label: null,
drink: {name: null}
},
default_check_model: {
label: null,
drink: {name: null}
},
check_delete_free_drink_list_config: false,
check_delete_free_drink_list_reason: false,
default_model_reason: {
id: -1,
name: null
},
check_model_reason: {
name: null
},
default_check_model_reason: {
name: null
}
}
},
methods: {
...mapActions('freeDrinkList', ['set_free_drink_list_config', 'delete_free_drink_list_config', 'update_free_drink_list_config', 'set_free_drink_list_reason', 'update_free_drink_list_reason', 'delete_free_drink_list_reason']),
log() {
console.log(this.free_drink_list_config)
},
reset(free_drink_config) {
let data = this.model.find(item => {
return item.id == free_drink_config.id
})
this.set_free_drink_config(data.origin)
this.model.splice(this.model.indexOf(data), 1)
},
cancel_delete() {
this.check_delete_free_drink_list_config = false
this.check_model = Object.assign({}, this.default_check_model)
},
accept_delete() {
this.delete_free_drink_list_config(this.check_model)
this.cancel_delete()
},
delete_free_drink_config(free_drink_config) {
Object.assign(this.check_model, free_drink_config)
this.check_delete_free_drink_list_config = true
console.log(this.check_delete_free_drink_list_config)
},
save(free_drink_config) {
if (free_drink_config.id > 0) {
this.update_free_drink_list_config(free_drink_config)
} else {
this.set_free_drink_list_config(free_drink_config)
}
},
delete_free_drink_reason(free_drink_reason) {
Object.assign(this.check_model_reason, free_drink_reason)
this.check_delete_free_drink_list_reason = true
},
save_reason(free_drink_reason) {
if (free_drink_reason.id > 0) {
this.update_free_drink_list_reason(free_drink_reason)
} else {
this.set_free_drink_list_reason(free_drink_reason)
}
},
cancel_delete_reason() {
this.check_delete_free_drink_list_reason = false
this.check_model_reason = Object.assign({}, this.default_check_model_reason)
},
accept_delete_reason() {
this.delete_free_drink_list_reason(this.check_model_reason)
this.cancel_delete_reason()
},
},
computed: {
...mapGetters('freeDrinkList', [
'free_drink_list_config',
'free_drink_list_reasons'
])
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,120 @@
<template>
<div>
<v-form :ref="free_drink_config.id">
<v-row>
<v-col cols="12" sm="6" md="3">
<v-text-field
outlined
label="Label"
:value="free_drink_config.label"
@change="set_model($event, 'label')"
dense
/>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-autocomplete
outlined
label="Zugeordnetes Getränk"
:items="priceList"
:item-text="item => {return item.name + '/' + (item.price_club/100).toFixed(2) + '€'}"
item-value="id"
:value="free_drink_config.drink"
@change="set_model($event, 'drink')"
return-object
dense
/>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-autocomplete
outlined
label="Freigetränkaufnahme"
multiple
:items="free_drink_types"
item-text="name"
item-value="id"
:value="free_drink_config.free_drink_types"
return-object
@change="set_model($event, 'free_drink_types')"
dense
/>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
outlined
label="Preis in €"
type="number"
:value="(free_drink_config.price/100).toFixed(2)"
@change="set_model(Math.round($event*100), 'price')"
dense
/>
</v-col>
</v-row>
</v-form>
<v-row justify="end">
<v-btn
v-if="free_drink_config.id > 0"
icon
class="mr-3"
@click="$emit('delete_free_drink_list_config', free_drink_config)">
<v-icon>mdi-delete</v-icon>
</v-btn>
<v-btn
v-else
fab
color="error"
x-small
class="mr-4"
@click="$emit('delete_free_drink_config')"
>
<v-icon>mdi-minus</v-icon>
</v-btn>
<v-btn
v-if="!is_same || free_drink_config.id < 0"
class="mr-3"
color="success"
@click="() => {$emit('save', model); $emit('delete_free_drink_config'); model = null}"
>
Save
</v-btn>
</v-row>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: "FreeDrinkListConfigConfigItem",
props: ['free_drink_config'],
data() {
return {
model: null
}
},
methods: {
set_model(event, type) {
console.log(!!this.model)
if (!this.model) {
this.model = Object.assign({}, this.free_drink_config)
}
if (type == 'drink') {
this.model.drink_id = event.id
}
this.model[type] = event
console.log(this.model)
}
},
computed: {
...mapGetters('freeDrinkList', [
'free_drink_types']),
...mapGetters('priceList', ["priceList"]),
is_same() {
console.log(this.model ? 'yo': 'no')
return this.model ? JSON.stringify(this.model) == JSON.stringify(this.free_drink_config) : true
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,70 @@
<template>
<div>
<v-row>
<v-col>
<v-text-field
outlined
label="Name"
:value="free_drink_reason.name"
@change="set_model($event)"
dense />
</v-col>
</v-row>
<v-row justify="end">
<v-btn
v-if="free_drink_reason.id > 0"
icon
class="mr-3"
@click="$emit('delete_free_drink_list_reason', free_drink_reason)">
<v-icon>mdi-delete</v-icon>
</v-btn>
<v-btn
v-else
fab
color="error"
x-small
class="mr-4"
@click="$emit('delete_free_drink_reason')"
>
<v-icon>mdi-minus</v-icon>
</v-btn>
<v-btn
v-if="!is_same || free_drink_reason.id < 0"
class="mr-3"
color="success"
@click="() => {$emit('save', model); $emit('delete_free_drink_reason'); model = null}"
>
Save
</v-btn>
</v-row>
</div>
</template>
<script>
export default {
name: "FreeDrinkListConfigReason",
props: ['free_drink_reason'],
data() {
return {
model: null
}
},
methods: {
set_model(event) {
if (!this.model) {
this.model = Object.assign({}, this.free_drink_reason)
}
this.model.name = event
}
},
computed: {
is_same() {
return this.model ? JSON.stringify(this.model) == JSON.stringify(this.free_drink_reason): true
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,123 @@
<template>
<div>
<v-row justify="space-around">
<v-card>
<v-card-title class="text-center">
Anzahl Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{free_drink_list_history_job_without_canceled.length}}
</v-card-text>
</v-card>
<v-card>
<v-card-title class="text-center">
Summe Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ (sum/100).toFixed(2)}}
</v-card-text>
</v-card>
</v-row>
<v-data-table :headers="header" :items="table"/>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: "FreeDrinkListJob",
data() {
return {
header: [
{
text: 'Datum',
value: 'date'
},
{
text: 'Label Freigetränk',
value: 'label'
},
{
text: 'Freigetränk',
value: 'name'
},
{
text: 'Anzahl',
value: 'count'
},
{
text: 'User',
value: 'user'
},
{
text: 'Preis pro Getränk',
value: 'pricepro'
},
{
text: 'Preis gesamt',
value: 'sum'
}
]
}
},
computed: {
...mapGetters('freeDrinkList', ['free_drink_list_history_job_without_canceled', 'free_drink_list_config']),
sum() {
let sum = 0
this.free_drink_list_history_job_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
table() {
if (this.free_drink_list_history_job_without_canceled.length == 0) {
return []
}
let retVal = []
const date_month = this.free_drink_list_history_job_without_canceled[0].timestamp
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
for (let day = 1; day <= days; day++) {
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
let history_of_date = this.free_drink_list_history_job_without_canceled.filter(item => {
return item.timestamp >= from && item.timestamp <= to && !item.canceled
})
this.free_drink_list_config.forEach(drink_config => {
let history_of_config = history_of_date.filter(item => {
return item.free_drink_config_id == drink_config.id
})
// eslint-disable-next-line no-unused-vars
let users = []
history_of_config.forEach(history_config => {
if (!users.find(user_id => { return user_id == history_config.user_id})) {
users.push(history_config.user_id)
}
})
users.forEach(user_id => {
let history_of_user = history_of_config.filter(item => {
return item.user_id == user_id
})
if (history_of_user.length > 0) {
retVal.push({
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
label: drink_config.label,
name: drink_config.drink.name,
user: `${history_of_user[0].user.firstname} ${history_of_user[0].user.lastname}`,
count: history_of_user.length,
pricepro: (drink_config.price / 100).toFixed(2),
sum: (drink_config.price / 100 * history_of_user.length).toFixed(2)
})
}
})
})
}
return retVal
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,166 @@
<template>
<div>
<v-row justify="space-around">
<v-card>
<v-card-title class="text-center">
Anzahl Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{free_drink_list_history_without_canceled.length}}
</v-card-text>
<v-card-title class="text-center">
Summe Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ (sum/100).toFixed(2)}}
</v-card-text>
</v-card>
<v-card>
<v-card-title class="text-center">
Anzahl Dienstgetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ free_drink_list_history_job_without_canceled.length }}
</v-card-text>
<v-card-title class="text-center">
Summe Dienstgetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{(sumJob/100).toFixed(2)}}
</v-card-text>
</v-card>
<v-card>
<v-card-title class="text-center">
Anzahl AG-Getränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ free_drink_list_history_workgroup_without_canceled.length }}
</v-card-text>
<v-card-title class="text-center">
Summe AG-Getränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{(sumWorkgroup/100).toFixed(2)}}
</v-card-text>
</v-card>
<v-card>
<v-card-title class="text-center">
Anzahl Bandgetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ free_drink_list_history_band_without_canceled.length }}
</v-card-text>
<v-card-title class="text-center">
Summe Bandgetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{(sumBand/100).toFixed(2)}}
</v-card-text>
</v-card>
</v-row>
<v-data-table :headers="header" :items="table"/>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: "FreeDrinkListMain",
data() {
return {
header: [
{
text: 'Datum',
value: 'date'
},
{
text: 'Label Freigetränk',
value: 'label'
},
{
text: 'Freigetränk',
value: 'name'
},
{
text: 'Anzahl',
value: 'count'
},
{
text: 'Preis pro Getränk',
value: 'pricepro'
},
{
text: 'Preis gesamt',
value: 'sum'
}
]
}
},
computed: {
...mapGetters('freeDrinkList', ['free_drink_list_history_without_canceled', 'free_drink_list_config', 'free_drink_list_history_job_without_canceled', 'free_drink_list_history_band_without_canceled', 'free_drink_list_history_workgroup_without_canceled']),
sum() {
let sum = 0
this.free_drink_list_history_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
sumJob() {
let sum = 0
this.free_drink_list_history_job_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
sumWorkgroup() {
let sum = 0
this.free_drink_list_history_workgroup_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
sumBand() {
let sum = 0
this.free_drink_list_history_band_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
table() {
if (this.free_drink_list_history_without_canceled.length == 0) {
return []
}
let retVal = []
const date_month = this.free_drink_list_history_without_canceled[0].timestamp
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
for (let day = 1; day <= days; day++) {
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
let history_of_date = this.free_drink_list_history_without_canceled.filter(item => {
return item.timestamp >= from && item.timestamp <= to && !item.canceled
})
this.free_drink_list_config.forEach(drink_config => {
let history_of_config = history_of_date.filter(item => {
return item.free_drink_config_id == drink_config.id
})
if (history_of_config.length > 0) {
retVal.push({
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
label: drink_config.label,
name: drink_config.drink.name,
count: history_of_config.length,
pricepro: (drink_config.price/100).toFixed(2),
sum: (drink_config.price/100*history_of_config.length).toFixed(2)
})
}
})
}
return retVal
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,112 @@
<template>
<div>
<v-row justify="space-around">
<v-card>
<v-card-title class="text-center">
Anzahl Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{free_drink_list_history_workgroup_without_canceled.length}}
</v-card-text>
</v-card>
<v-card>
<v-card-title class="text-center">
Summe Freigetränke
</v-card-title>
<v-card-text class="text-h2 text-center">
{{ (sum/100).toFixed(2)}}
</v-card-text>
</v-card>
</v-row>
<v-data-table :headers="header" :items="table"/>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name: "FreeDrinkListWorkgroup",
data() {
return {
header: [
{
text: 'Datum',
value: 'date'
},
{
text: 'Label Freigetränk',
value: 'label'
},
{
text: 'Freigetränk',
value: 'name'
},
{
text: 'User',
value: 'user'
},
{
text: 'Preis',
value: 'pricepro'
},
{
text: 'Grund',
value: 'reason'
},
{
text: 'Beschreibung',
value: 'description'
}
]
}
},
computed: {
...mapGetters('freeDrinkList', ['free_drink_list_history_workgroup_without_canceled', 'free_drink_list_config']),
sum() {
let sum = 0
this.free_drink_list_history_workgroup_without_canceled.forEach(item => {
sum += item.free_drink_config.price
})
return sum
},
table() {
if (this.free_drink_list_history_workgroup_without_canceled.length == 0) {
return []
}
let retVal = []
const date_month = this.free_drink_list_history_workgroup_without_canceled[0].timestamp
let days = new Date(date_month.getFullYear(), date_month.getMonth() + 1, 0).getDate()
for (let day = 1; day <= days; day++) {
let from = new Date(date_month.getFullYear(), date_month.getMonth(), day)
let to = new Date(date_month.getFullYear(), date_month.getMonth(), day + 1)
let history_of_date = this.free_drink_list_history_workgroup_without_canceled.filter(item => {
return item.timestamp >= from && item.timestamp <= to && !item.canceled
})
this.free_drink_list_config.forEach(drink_config => {
let history_of_config = history_of_date.filter(item => {
return item.free_drink_config_id == drink_config.id
})
console.log(history_of_config)
history_of_config.forEach(history_config => {
retVal.push({
date: `${from.getDate()}.${from.getMonth() + 1}.${from.getFullYear()}`,
label: drink_config.label,
name: drink_config.drink.name,
user: `${history_config.user.firstname} ${history_config.user.lastname}`,
reason: history_config.free_drink_list_reason ? history_config.free_drink_list_reason.name : null,
description: history_config.description,
pricepro: (drink_config.price / 100).toFixed(2)
})
})
})
}
return retVal
}
}
}
</script>
<style scoped>
</style>

View File

@ -31,6 +31,14 @@
Dienstarten
</v-list-item-title>
</v-list-item>
<v-list-item link :to="{name: 'freeDrinkList'}">
<v-list-item-icon>
<v-icon>mdi-beer</v-icon>
</v-list-item-icon>
<v-list-item-title>
Freigetränke
</v-list-item-title>
</v-list-item>
</v-list>
</template>

View File

@ -28,6 +28,14 @@ const url = {
saveLifeTime: main + 'saveLifeTime',
getLifeTime: main + 'getLifeTime',
resetPassword: main + 'passwordReset',
freeDrinkListConfig: main + 'freeDrinkListConfig',
freeDrinkListHistory: main + 'freeDrinkListHistory',
freeDrinkListHistoryFromTo: main + 'freeDrinkListHistoryFromTo',
deleteDrinkListHistory: main + 'deleteDrinkListHistory',
freeDrinkListReasons: main + 'freeDrinkListReasons',
deleteFreeDrinkListReason: main + 'deleteFreeDrinkListReason',
freeDrinkTypes: main + 'freeDrinkTypes',
deleteFreeDrinkListConfig: main + 'deleteFreeDrinkListConfig',
vorstand: {
sm: {
addUser: main + 'sm/addUser',

View File

@ -4,6 +4,7 @@ import FinanzerView from '@/views/FinanzerView'
import Login from '@/views/Login'
import store from '@/store/index'
import GeruechteView from '../views/contents/GeruechteView'
import BarFreedrinksView from '../views/contents/BarFreedrinksView'
import AddAmount from '../components/user/AddAmount'
import CreditOverview from '../components/user/CreditOverview'
import MainView from '../views/MainView'
@ -16,6 +17,7 @@ import Overview from '../components/finanzer/Overview'
import User from '../components/finanzer/User'
import ServiceManagement from '../components/vorstand/ServiceManagement'
import Config from '@/components/user/Config'
import FreedrinkUserView from '@/components/user/freedrink/freedrinkUserView'
import Jobs from '@/components/user/Jobs'
import PriceList from '@/components/pricelist/PriceList'
import ManagementNavigation from '@/components/vorstand/ManagementNavigation'
@ -26,6 +28,12 @@ import WorkgroupManagement from '@/components/vorstand/WorkgroupManagement'
import JobKindManager from '@/components/vorstand/JobKindManager'
import JobsRequest from '@/components/user/JobsRequest'
import ResetPassword from '@/components/ResetPassword'
import FreeDrinkList from '@/components/vorstand/FreeDrinkList'
import FreeDrinkListMain from '@/components/vorstand/FreeDrinkList/FreeDrinkListMain'
import FreeDrinkListConfig from '@/components/vorstand/FreeDrinkList/FreeDrinkListConfig'
import FreeDrinkListJob from '@/components/vorstand/FreeDrinkList/FreeDrinkListJob'
import FreeDrinkListWorkgroup from '@/components/vorstand/FreeDrinkList/FreeDrinkListWorkgroup'
import FreeDrinkListBand from '@/components/vorstand/FreeDrinkList/FreeDrinkListBand'
Vue.use(VueRouter)
@ -80,6 +88,38 @@ const routes = [
path: 'jobkindmanagement',
name: 'jobkindManagement',
component: JobKindManager
},
{
path: 'freeDrinkList',
name: 'freeDrinkList',
component: FreeDrinkList,
children: [
{
path: 'main',
name: 'freeDrinkListMain',
component: FreeDrinkListMain
},
{
path: 'config',
name: 'freeDrinkListConfig',
component: FreeDrinkListConfig
},
{
path: 'freeDrinkListJob',
name: 'freeDrinkListJob',
component: FreeDrinkListJob
},
{
path: 'freeDrinkListWorkgroup',
name: 'freeDrinkListWorkgroup',
component: FreeDrinkListWorkgroup
},
{
path: 'freeDrinkListBand',
name: 'freeDrinkListBand',
component: FreeDrinkListBand
}
]
}
]
},
@ -93,6 +133,11 @@ const routes = [
name: 'add',
component: AddAmount
},
{
path: 'freedrinkUser',
name: 'freedrinkUser',
component: FreedrinkUserView
},
{
path: 'overview',
name: 'userOverview',
@ -124,6 +169,11 @@ const routes = [
path: 'geruecht',
name: 'geruecht',
component: GeruechteView
},
{
path: 'baruserFreedrinks',
name: 'baruserFreedrinks',
component: BarFreedrinksView
}
]
},

View File

@ -13,6 +13,7 @@ import jkm from '@/store/modules/jobkindManager'
import jobInvites from '@/store/modules/jobInvites'
import jobRequests from '@/store/modules/jobRequests'
import connectionError from '@/store/modules/connectionError'
import freeDrinkList from '@/store/modules/freeDrinkList'
Vue.use(Vuex)
@ -30,6 +31,7 @@ export default new Vuex.Store({
jkm,
jobInvites,
jobRequests,
connectionError
connectionError,
freeDrinkList
}
})

View File

@ -0,0 +1,438 @@
import axios from 'axios'
import url from '@/plugins/routes'
const timeout = 20000
const state = {
free_drink_list_config: [],
free_drink_list_history: [],
free_drink_list_reasons: [],
free_drink_types: [],
free_drink_list_config_loading: false,
free_drink_list_history_loading: false,
free_drink_list_reasons_loading: false,
free_drink_types_loading: false,
snackbar_messages: []
}
const mutations = {
set_free_drink_list_config(state, data) {
state.free_drink_list_config = data
},
set_free_drink_list_history(state, data) {
data.forEach(item => {
item.timestamp = new Date(
item.timestamp.year,
item.timestamp.month - 1,
item.timestamp.day,
item.timestamp.hour,
item.timestamp.minute,
item.timestamp.second
)
})
state.free_drink_list_history = data
state.free_drink_list_history.reverse()
},
set_free_drink_list_config_loading(state, loading) {
state.free_drink_list_config_loading = loading
},
set_free_drink_list_history_loading(state, loading) {
state.free_drink_list_history_loading = loading
},
set_free_drink_list_reasons_loading(state, loading) {
state.free_drink_list_reasons_loading = loading
},
add_snackbar_message(state, { data, error }) {
data.error = error
data.visible = true
data.free_drink_type = data.free_drink_types.find(item => {
return item.id == data.free_drink_type_id
})
data.timer = setTimeout(() => {
if (!data.error) {
data.visible = false
}
}, 5000)
console.log(data)
state.snackbar_messages.unshift(data)
},
set_free_drink_list_reasons(state, data) {
state.free_drink_list_reasons = data
},
set_free_drink_types(state, data) {
state.free_drink_types = data
},
set_free_drink_types_loading(state, loading) {
state.free_drink_types_loading = loading
},
set_free_drink_config(state, data) {
let config = state.free_drink_list_config.find(item => {
return item.id == data.id
})
Object.assign(config, data)
}
}
const actions = {
async get_free_drink_list_config({ commit, dispatch, rootState }) {
try {
commit('set_free_drink_list_config_loading', true)
const response = await axios.get(url.freeDrinkListConfig, {
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_config', response.data)
} catch (e) {
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_config_loading', false)
}
},
async get_free_drink_list_history({ commit, dispatch, rootState }) {
try {
commit('set_free_drink_list_history_loading', true)
const response = await axios.get(url.freeDrinkListHistory, {
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_history', response.data)
} catch (e) {
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_history_loading', false)
}
},
async get_free_drink_list_history_from_to({ commit, dispatch, rootState }, data) {
try {
commit('set_free_drink_list_history_loading', true)
const response = await axios.post(url.freeDrinkListHistoryFromTo, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_history', response.data)
} catch (e) {
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_history_loading', false)
}
},
async set_free_drink_list_history({ commit, dispatch, rootState }, data) {
try {
commit('set_free_drink_list_history_loading', true)
const response = await axios.post(
url.freeDrinkListHistory,
{ ...data },
{
headers: { Token: rootState.login.user.accessToken },
timeout
}
)
commit('set_free_drink_list_history', response.data)
commit('add_snackbar_message', { data, error: false })
} catch (e) {
commit('add_snackbar_message', { data, error: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_history_loading', false)
}
},
async update_free_drink_list_history({ commit, dispatch, rootState }, data) {
try {
commit('set_free_drink_list_history_loading', true)
const response = await axios.put(
url.freeDrinkListHistory,
{ ...data },
{ headers: { Token: rootState.login.user.accessToken }, timeout }
)
commit('set_free_drink_list_history', response.data)
commit('add_snackbar_message', { data, error: false })
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_history_loading', false)
}
},
async get_free_drink_list_reasons({ commit, dispatch, rootState }) {
try {
commit('set_free_drink_list_reasons_loading', true)
const response = await axios.get(url.freeDrinkListReasons, {
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_reasons', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_reasons_loading', false)
}
},
async get_free_drink_types({ commit, dispatch, rootState }) {
try {
commit('set_free_drink_types_loading', true)
const response = await axios.get(url.freeDrinkTypes, {
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_types', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_types_loading', false)
}
},
async set_free_drink_list_config({commit, dispatch, rootState}, data) {
try {
commit('set_free_drink_list_config_loading', true)
const response = await axios.post(url.freeDrinkListConfig, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_config', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_config_loading', false)
}
},
async update_free_drink_list_config({commit, dispatch, rootState}, data) {
try {
commit('set_free_drink_list_config_loading', true)
const response = await axios.put(url.freeDrinkListConfig, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_config', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_config_loading', false)
}
},
async delete_free_drink_list_config({commit, dispatch, rootState}, data) {
try {
commit('set_free_drink_list_config_loading', true)
const response = await axios.post(url.deleteFreeDrinkListConfig, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_config', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_config_loading', false)
}
},
async set_free_drink_list_reason({ commit, dispatch, rootState }, data) {
try {
commit('set_free_drink_list_reasons_loading', true)
const response = await axios.post(url.freeDrinkListReasons, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_reasons', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_reasons_loading', false)
}
}
,
async update_free_drink_list_reason({ commit, dispatch, rootState }, data) {
try {
commit('set_free_drink_list_reasons_loading', true)
const response = await axios.put(url.freeDrinkListReasons, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_reasons', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_reasons_loading', false)
}
},
async delete_free_drink_list_reason({ commit, dispatch, rootState }, data) {
try {
commit('set_free_drink_list_reasons_loading', true)
const response = await axios.post(url.deleteFreeDrinkListReason, {...data},{
headers: { Token: rootState.login.user.accessToken },
timeout
})
commit('set_free_drink_list_reasons', response.data)
} catch (e) {
dispatch('connectionError/addError', null, { root: true })
if (e.message == 'Network Error') {
dispatch('connectionError/addError', null, { root: true })
}
if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true })
} finally {
commit('set_free_drink_list_reasons_loading', false)
}
}
}
const getters = {
free_drink_list_config(state) {
return state.free_drink_list_config
},
free_drink_list_config_job(state) {
return state.free_drink_list_config.filter(item => {
console.log(item)
return item.free_drink_types.find(drink_type => {
return drink_type.id == 1
})
})
},
free_drink_list_config_workgroup(state) {
return state.free_drink_list_config.filter(item => {
return item.free_drink_types.find(drink_type => {
return drink_type.id == 2
})
})
},
free_drink_list_config_band(state) {
return state.free_drink_list_config.filter(item => {
return item.free_drink_types.find(drink_type => {
return drink_type.id == 3
})
})
},
free_drink_list_history(state) {
return state.free_drink_list_history
},
free_drink_list_history_without_canceled(state) {
return state.free_drink_list_history.filter(item => {
return !item.canceled
})
},
free_drink_list_history_band(state) {
return state.free_drink_list_history.filter(item => {
return item.free_drink_type.id == 3
})
},
free_drink_list_history_band_without_canceled(state) {
return state.free_drink_list_history.filter(item => {
return item.free_drink_type.id == 3 && !item.canceled
})
},
free_drink_list_history_job_without_canceled(state) {
return state.free_drink_list_history.filter(item => {
return item.free_drink_type.id == 1 && !item.canceled
})
},
free_drink_list_history_job_credit(state) {
let jobDrinks = state.free_drink_list_history.filter(item => {
return item.free_drink_type.id == 1 && !item.canceled
})
let credit = 0
jobDrinks.forEach(item => {
credit += item.free_drink_config.price
})
return credit
},
free_drink_list_history_workgroup_without_canceled(state) {
return state.free_drink_list_history.filter(item => {
return item.free_drink_type.id == 2 && !item.canceled
})
},
free_drink_list_history_workgroup(state) {
return state.free_drink_list_history.filter(item => {
return item.free_drink_type.id == 2
})
},
loading(state) {
return (
state.free_drink_list_history_loading ||
state.free_drink_list_config_loading
)
},
snackbar_messages(state) {
return state.snackbar_messages
},
free_drink_list_reasons(state) {
return state.free_drink_list_reasons
},
free_drink_list_reasons_loading(state) {
return state.free_drink_list_reasons_loading
},
free_drink_types(state) {
return state.free_drink_types
},
free_drink_list_history_loading(state) {
return state.free_drink_list_history_loading
},
free_drink_list_config_loading(state) {
return state.free_drink_list_config_loading
},
free_drink_types_loading(state) {
return state.free_drink_types_loading
},
free_drink_list_config_by_id: (state) => (id) => {
return state.free_drink_list_config.find(item => { return item.id == id})
}
}
export default {
namespaced: true,
state,
mutations,
actions,
getters
}

View File

@ -0,0 +1,24 @@
<template>
<div>
<BarFreedrinks></BarFreedrinks>
</div>
</template>
<script>
import BarFreedrinks from '@/components/baruser/BarFreedrinks'
// eslint-disable-next-line no-unused-vars
import { mapActions } from 'vuex'
export default {
name: 'BarFreedrinksView',
components: { BarFreedrinks },
created() {},
data() {
return {}
},
methods: {
...mapActions(['logout'])
}
}
</script>
<style scoped></style>