489 lines
15 KiB
Vue
489 lines
15 KiB
Vue
<template>
|
|
<div>
|
|
<v-data-table :headers="headers" :items="priceList" :search="search" :loading="priceListLoading || typesLoading">
|
|
<template v-slot:top>
|
|
<v-toolbar flat color="white">
|
|
<v-toolbar-title>Preisliste</v-toolbar-title>
|
|
<v-spacer></v-spacer>
|
|
<v-text-field
|
|
v-model="search"
|
|
label="Suche Getränk"
|
|
single-line
|
|
hide-details
|
|
>
|
|
<template v-slot:append>
|
|
<v-icon>{{ searchIcon }}</v-icon>
|
|
</template>
|
|
</v-text-field>
|
|
<v-dialog v-model="dialog" v-if="isGastro">
|
|
<template v-slot:activator="{ on }">
|
|
<v-btn
|
|
fab
|
|
x-small
|
|
color="primary"
|
|
class="mb-2"
|
|
v-on="on"
|
|
style="margin: 5px"
|
|
>
|
|
<v-icon>{{ plus }}</v-icon>
|
|
</v-btn>
|
|
</template>
|
|
<v-card>
|
|
<v-card-title>
|
|
<span class="headline">{{ formTitle }}</span>
|
|
</v-card-title>
|
|
|
|
<v-card-text>
|
|
<v-container>
|
|
<v-row>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.name"
|
|
label="Name"
|
|
outlined
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-autocomplete
|
|
return-object
|
|
v-model="editedItem.type"
|
|
label="Kategorie"
|
|
item-text="name"
|
|
item-value="id"
|
|
:items="types"
|
|
outlined
|
|
:search-input.sync="searchType"
|
|
no-data-text="Kategorie nicht vorhanden."
|
|
>
|
|
<template v-slot:append-item>
|
|
<v-list-item v-if="!inType(searchType)">
|
|
<v-list-item-title>
|
|
{{ searchType }}
|
|
</v-list-item-title>
|
|
<v-btn
|
|
dark
|
|
x-small
|
|
color="blue darken-1"
|
|
@click="addType()"
|
|
:disabled="inType(searchType)"
|
|
fab
|
|
>
|
|
<v-icon>
|
|
{{ plus }}
|
|
</v-icon>
|
|
</v-btn>
|
|
</v-list-item>
|
|
</template>
|
|
</v-autocomplete>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.price"
|
|
label="Preis in €"
|
|
outlined
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.price_big"
|
|
label="Preis groß in €"
|
|
outlined
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.price_club"
|
|
label="Preis Club in €"
|
|
outlined
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.price_club_big"
|
|
label="Preis Club groß in €"
|
|
outlined
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col col="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.premium"
|
|
label="Aufpreis in €"
|
|
outlined
|
|
/>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.premium_club"
|
|
label="Aufpreis Club in €"
|
|
outlined
|
|
/>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.price_extern_club"
|
|
label="Preis extern Club in €"
|
|
outlined
|
|
/>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</v-card-text>
|
|
|
|
<v-card-actions>
|
|
<v-spacer></v-spacer>
|
|
<v-btn color="blue darken-1" text @click="close"
|
|
>Abbrechen</v-btn
|
|
>
|
|
<v-btn color="blue darken-1" text @click="save"
|
|
>Speichern</v-btn
|
|
>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</v-toolbar>
|
|
</template>
|
|
<template v-slot:item.type="{ item }">
|
|
{{ computeType(item.type) }}
|
|
</template>
|
|
<template v-slot:item.price="{ item }">
|
|
{{ item.price ? (item.price / 100).toFixed(2) : '' }}
|
|
</template>
|
|
<template v-slot:item.price_big="{ item }">
|
|
{{ item.price_big ? (item.price_big / 100).toFixed(2) : '' }}
|
|
</template>
|
|
<template v-slot:item.price_club="{ item }">
|
|
{{
|
|
item.name.toLowerCase() == 'long island ice tea'.toLowerCase()
|
|
? 'Ein Klubmitglied bestellt keinen Long Island Icetea'
|
|
: item.price_club
|
|
? (item.price_club / 100).toFixed(2)
|
|
: ''
|
|
}}
|
|
</template>
|
|
<template v-slot:item.price_club_big="{ item }">
|
|
{{ item.price_club_big ? (item.price_club_big / 100).toFixed(2) : '' }}
|
|
</template>
|
|
<template v-slot:item.premium="{ item }">
|
|
{{ item.premium ? (item.premium / 100).toFixed(2) : '' }}
|
|
</template>
|
|
<template v-slot:item.premium_club="{ item }">
|
|
{{ item.premium_club ? (item.premium_club / 100).toFixed(2) : '' }}
|
|
</template>
|
|
<template v-slot:item.price_extern_club="{ item }">
|
|
{{
|
|
item.price_extern_club
|
|
? (item.price_extern_club / 100).toFixed(2)
|
|
: ''
|
|
}}
|
|
</template>
|
|
<template v-slot:item.action="{ item }">
|
|
<v-icon small class="mr-2" @click="editItem(item)">
|
|
{{ editIcon }}
|
|
</v-icon>
|
|
<v-icon small @click="deleteItem(item)">
|
|
{{ deleteIcon }}
|
|
</v-icon>
|
|
</template>
|
|
</v-data-table>
|
|
<v-card tile v-if="isGastro" :loading="typesLoading">
|
|
<v-card-title>
|
|
Kategorien
|
|
<v-spacer />
|
|
<v-btn fab x-small @click="dialogType = true" color="primary">
|
|
<v-icon>{{ plus }}</v-icon>
|
|
</v-btn>
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<div tile v-for="type in types" :key="type.id">
|
|
<v-card tile>
|
|
<v-card-text class="black--text">
|
|
<v-row class="ml-3 mr-3">
|
|
{{ type.name }}
|
|
<v-spacer />
|
|
<v-btn icon @click="editType(type)">
|
|
<v-icon>
|
|
{{ editIcon }}
|
|
</v-icon>
|
|
</v-btn>
|
|
<v-btn icon @click="deleteType(type)">
|
|
<v-icon>
|
|
{{ deleteIcon }}
|
|
</v-icon>
|
|
</v-btn>
|
|
</v-row>
|
|
</v-card-text>
|
|
</v-card>
|
|
</div>
|
|
</v-card-text>
|
|
<v-dialog v-model="dialogType">
|
|
<v-card>
|
|
<v-card-title>
|
|
{{ dialogTypeTitle }}
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<v-container>
|
|
<v-text-field
|
|
v-model="editedType.name"
|
|
outlined
|
|
label="Name der Kategorie"
|
|
/>
|
|
</v-container>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer />
|
|
<v-btn text color="blue darken-1" @click="closeType()">
|
|
Abbrechen
|
|
</v-btn>
|
|
<v-btn
|
|
text
|
|
color="blue darken-1"
|
|
@click="saveType()"
|
|
:disabled="inType(editedType.name)"
|
|
>
|
|
Speichern
|
|
</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
</v-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters, mapActions } from 'vuex'
|
|
import { mdiMagnify, mdiPlus, mdiPencil, mdiDelete } from '@mdi/js'
|
|
export default {
|
|
name: 'PriceList',
|
|
data() {
|
|
return {
|
|
editIcon: mdiPencil,
|
|
deleteIcon: mdiDelete,
|
|
searchIcon: mdiMagnify,
|
|
plus: mdiPlus,
|
|
searchType: null,
|
|
search: null,
|
|
dialog: null,
|
|
dialogType: null,
|
|
editedIndex: -1,
|
|
headers: [
|
|
{
|
|
text: 'Name',
|
|
value: 'name'
|
|
},
|
|
{
|
|
text: 'Kategorie',
|
|
value: 'type'
|
|
},
|
|
{
|
|
text: 'Preis in €',
|
|
value: 'price'
|
|
},
|
|
{
|
|
text: 'Preis groß in €',
|
|
value: 'price_big'
|
|
},
|
|
{
|
|
text: 'Preis Club in €',
|
|
value: 'price_club'
|
|
},
|
|
{
|
|
text: 'Preis groß Club in €',
|
|
value: 'price_club_big'
|
|
},
|
|
{
|
|
text: 'Aufpreis in €',
|
|
value: 'premium'
|
|
},
|
|
{
|
|
text: 'Aufpreis Club in €',
|
|
value: 'premium_club'
|
|
},
|
|
{
|
|
text: 'Preis Club extern in €',
|
|
value: 'price_extern_club'
|
|
}
|
|
],
|
|
editedItem: {
|
|
name: null,
|
|
type: { id: -1, name: null },
|
|
price: null,
|
|
price_big: null,
|
|
price_club: null,
|
|
price_club_big: null,
|
|
premium: null,
|
|
premium_club: null,
|
|
price_extern_club: null
|
|
},
|
|
defaultItem: {
|
|
name: null,
|
|
type: { id: -1, name: null },
|
|
price: null,
|
|
price_big: null,
|
|
price_club: null,
|
|
price_club_big: null,
|
|
premium: null,
|
|
premium_club: null,
|
|
price_extern_club: null
|
|
},
|
|
editedType: {
|
|
id: -1,
|
|
name: null
|
|
},
|
|
defaultType: {
|
|
id: -1,
|
|
name: null
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
...mapActions({
|
|
getPriceList: 'priceList/getPriceList',
|
|
getTypes: 'priceList/getTypes',
|
|
setDrink: 'priceList/setDrink',
|
|
updateDrink: 'priceList/updateDrink',
|
|
deleteDrink: 'priceList/deleteDrink',
|
|
setDrinkType: 'priceList/setDrinkType',
|
|
updateDrinkType: 'priceList/updateDrinkType',
|
|
deleteDrinkType: 'priceList/deleteDrinkType'
|
|
}),
|
|
editType(item) {
|
|
this.editedType = Object.assign({}, item)
|
|
this.dialogType = true
|
|
},
|
|
closeType() {
|
|
this.dialogType = false
|
|
setTimeout(() => {
|
|
this.editedType = Object.assign({}, this.defaultType)
|
|
}, 300)
|
|
},
|
|
saveType() {
|
|
this.editedType.id === -1
|
|
? this.setDrinkType(this.editedType)
|
|
: this.updateDrinkType(this.editedType)
|
|
this.closeType()
|
|
},
|
|
deleteType(item) {
|
|
confirm('Bist du sicher, dass die diese Kategorie entfernen wills?') &&
|
|
this.deleteDrinkType({ id: item.id })
|
|
},
|
|
addType() {
|
|
this.setDrinkType({ name: this.searchType })
|
|
},
|
|
close() {
|
|
this.dialog = false
|
|
setTimeout(() => {
|
|
this.editedItem = Object.assign({}, this.defaultItem)
|
|
this.editedIndex = -1
|
|
}, 300)
|
|
},
|
|
editItem(item) {
|
|
this.editedIndex = item.id
|
|
this.editedItem = Object.assign({}, item)
|
|
for (let i in this.editedItem) {
|
|
this.editedItem[i] = isNaN(this.editedItem[i])
|
|
? this.editedItem[i]
|
|
: this.editedItem[i] == null || this.editedItem[i] == 0
|
|
? null
|
|
: (this.editedItem[i] / 100).toFixed(2)
|
|
}
|
|
this.editedItem.type = Object.assign(
|
|
{},
|
|
this.types.find(a => a.id == item.type)
|
|
)
|
|
this.dialog = true
|
|
},
|
|
|
|
deleteItem(item) {
|
|
confirm('Bist du sicher, dass die dieses Getränk entfernen wills?') &&
|
|
this.deleteDrink({ id: item.id })
|
|
},
|
|
save() {
|
|
var drink = {
|
|
id: this.editedIndex,
|
|
name: this.editedItem.name,
|
|
type: this.editedItem.type.id,
|
|
price: !isNaN(this.editedItem.price)
|
|
? this.editedItem.price * 100
|
|
: null,
|
|
price_big: !isNaN(this.editedItem.price_big)
|
|
? this.editedItem.price_big * 100
|
|
: null,
|
|
price_club: !isNaN(this.editedItem.price_club)
|
|
? this.editedItem.price_club * 100
|
|
: null,
|
|
price_club_big: !isNaN(this.editedItem.price_club_big)
|
|
? this.editedItem.price_club_big * 100
|
|
: null,
|
|
premium: !isNaN(this.editedItem.premium)
|
|
? this.editedItem.premium * 100
|
|
: null,
|
|
premium_club: !isNaN(this.editedItem.premium_club)
|
|
? this.editedItem.premium_club * 100
|
|
: null,
|
|
price_extern_club: !isNaN(this.editedItem.price_extern_club)
|
|
? this.editedItem.price_extern_club * 100
|
|
: null
|
|
}
|
|
drink.id === -1 ? this.setDrink(drink) : this.updateDrink(drink)
|
|
this.editedItem = Object.assign({}, this.defaultItem)
|
|
this.close()
|
|
}
|
|
},
|
|
computed: {
|
|
...mapGetters({
|
|
priceList: 'priceList/priceList',
|
|
types: 'priceList/types',
|
|
priceListLoading: 'priceList/priceListLoading',
|
|
typesLoading: 'priceList/typesLoading',
|
|
isGastro: 'isGastro'
|
|
}),
|
|
formTitle() {
|
|
return this.editedIndex === -1 ? 'Neues Getränk' : 'Bearbeite Getränk'
|
|
},
|
|
inType() {
|
|
return text => {
|
|
return !!this.types.find(a => {
|
|
if (a.name === null || text === null) {
|
|
return true
|
|
} else {
|
|
return a.name.toLowerCase() === text.toLowerCase()
|
|
}
|
|
})
|
|
}
|
|
},
|
|
dialogTypeTitle() {
|
|
return this.editedType.id === -1
|
|
? 'Neue Kategorie'
|
|
: 'Bearbeite Kategorie'
|
|
},
|
|
computeType() {
|
|
return id => {
|
|
const type = this.types.find(a => {
|
|
return a.id === id
|
|
})
|
|
return type ? type.name : null
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
this.getPriceList()
|
|
this.getTypes()
|
|
if (this.isGastro) {
|
|
this.headers.push({
|
|
text: 'Aktion',
|
|
value: 'action',
|
|
sortable: false,
|
|
filterable: false
|
|
})
|
|
}
|
|
},
|
|
watch: {
|
|
dialog(val) {
|
|
val || this.close()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped></style>
|