2021-04-03 20:39:06 +00:00
|
|
|
<template>
|
|
|
|
<q-carousel
|
|
|
|
v-model="volume"
|
|
|
|
transition-prev="slide-right"
|
|
|
|
transition-next="slide-left"
|
|
|
|
animated
|
|
|
|
swipeable
|
|
|
|
control-color="primary"
|
|
|
|
arrows
|
2021-04-14 16:53:17 +00:00
|
|
|
:keep-alive="false"
|
2021-04-03 20:39:06 +00:00
|
|
|
>
|
2021-04-09 21:49:49 +00:00
|
|
|
<q-carousel-slide v-for="volume in volumes" :key="volume.id" :name="volume.id">
|
2021-04-11 14:29:11 +00:00
|
|
|
<div class="full-width row">
|
|
|
|
<q-input
|
2021-04-14 16:53:17 +00:00
|
|
|
v-model.number="volume._volume"
|
2021-04-11 14:29:11 +00:00
|
|
|
class="q-pa-sm col-10"
|
|
|
|
:outlined="!editable || !volume_can_edit"
|
|
|
|
:filled="editable && volume_can_edit"
|
|
|
|
:readonly="!editable || !volume_can_edit"
|
|
|
|
dense
|
|
|
|
label="Inhalt"
|
|
|
|
mask="#.###"
|
|
|
|
fill-mask="0"
|
|
|
|
suffix="L"
|
|
|
|
min="0"
|
|
|
|
step="0.001"
|
2021-04-14 16:53:17 +00:00
|
|
|
@update:model-value="updateVolume(volume)"
|
2021-04-11 14:29:11 +00:00
|
|
|
/>
|
2021-04-14 20:42:09 +00:00
|
|
|
<div
|
|
|
|
v-if="deleteable && editable && hasPermission(PERMISSIONS.DELETE_VOLUME)"
|
|
|
|
class="q-pa-sm col-2 text-right"
|
|
|
|
>
|
2021-04-11 14:29:11 +00:00
|
|
|
<q-btn round icon="mdi-delete" size="sm" color="negative" @click="deleteVolume">
|
|
|
|
<q-tooltip> Abgabe entfernen </q-tooltip>
|
|
|
|
</q-btn>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-04-13 14:20:32 +00:00
|
|
|
<div v-if="!public && !nodetails" class="full-width row q-gutter-sm q-pa-sm justify-around">
|
2021-04-03 20:39:06 +00:00
|
|
|
<div v-for="(min_price, index) in volume.min_prices" :key="index">
|
|
|
|
<q-badge class="text-body1" color="primary"> {{ min_price.percentage }}% </q-badge>
|
|
|
|
<div class="text-body1">{{ min_price.price.toFixed(3) }}€</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="q-pa-sm">
|
|
|
|
<div v-for="(price, index) in volume.prices" :key="price.id">
|
|
|
|
<div class="fit row justify-around q-py-sm">
|
2021-04-14 20:42:09 +00:00
|
|
|
<div
|
|
|
|
v-if="!editable || !hasPermission(PERMISSIONS.EDIT_PRICE)"
|
|
|
|
class="text-body1 col-3"
|
|
|
|
>
|
|
|
|
{{ price.price.toFixed(2) }}€
|
|
|
|
</div>
|
2021-04-09 21:49:49 +00:00
|
|
|
<q-input
|
|
|
|
v-else
|
|
|
|
v-model.number="price.price"
|
2021-04-11 14:29:11 +00:00
|
|
|
class="col-3"
|
2021-04-09 21:49:49 +00:00
|
|
|
type="number"
|
|
|
|
min="0"
|
|
|
|
step="0.01"
|
|
|
|
suffix="€"
|
|
|
|
filled
|
|
|
|
dense
|
|
|
|
label="Preis"
|
2021-04-11 14:29:11 +00:00
|
|
|
@update:model-value="change"
|
2021-04-09 21:49:49 +00:00
|
|
|
/>
|
2021-04-11 14:29:11 +00:00
|
|
|
<div class="text-body1 col-2">
|
2021-04-03 20:39:06 +00:00
|
|
|
<q-toggle
|
2021-04-09 21:49:49 +00:00
|
|
|
v-model="price.public"
|
2021-04-14 20:42:09 +00:00
|
|
|
:disable="!editable || !hasPermission(PERMISSIONS.EDIT_PRICE)"
|
2021-04-03 20:39:06 +00:00
|
|
|
checked-icon="mdi-earth"
|
|
|
|
unchecked-icon="mdi-earth-off"
|
2021-04-11 14:29:11 +00:00
|
|
|
@update:model-value="change"
|
2021-04-03 20:39:06 +00:00
|
|
|
/>
|
|
|
|
</div>
|
2021-04-14 20:42:09 +00:00
|
|
|
<div
|
|
|
|
v-if="!editable || !hasPermission(PERMISSIONS.EDIT_PRICE)"
|
|
|
|
class="text-body1 col-5"
|
|
|
|
>
|
2021-04-03 20:39:06 +00:00
|
|
|
{{ price.description }}
|
|
|
|
</div>
|
2021-04-09 21:49:49 +00:00
|
|
|
<q-input
|
|
|
|
v-else
|
|
|
|
v-model="price.description"
|
2021-04-11 14:29:11 +00:00
|
|
|
class="col-5"
|
2021-04-09 21:49:49 +00:00
|
|
|
filled
|
|
|
|
dense
|
|
|
|
label="Beschreibung"
|
2021-04-11 14:29:11 +00:00
|
|
|
@update:model-value="change"
|
2021-04-09 21:49:49 +00:00
|
|
|
/>
|
2021-04-14 20:42:09 +00:00
|
|
|
<div v-if="editable && hasPermission(PERMISSIONS.DELETE_PRICE)" class="col-1">
|
2021-04-11 14:29:11 +00:00
|
|
|
<q-btn round icon="mdi-delete" color="negative" size="xs" @click="deletePrice(price)">
|
|
|
|
<q-tooltip> Preis entfernen </q-tooltip>
|
|
|
|
</q-btn>
|
|
|
|
</div>
|
2021-04-03 20:39:06 +00:00
|
|
|
</div>
|
|
|
|
<q-separator v-if="index < volume.prices.length - 1" />
|
|
|
|
</div>
|
2021-04-14 17:44:53 +00:00
|
|
|
<div
|
|
|
|
v-if="!public && !nodetails && isUnderMinPrice"
|
|
|
|
class="fit warning bg-red text-center text-white text-body1"
|
|
|
|
>
|
|
|
|
Einer der Preise ist unterhalb des niedrigsten minimal Preises.
|
|
|
|
</div>
|
2021-04-14 20:42:09 +00:00
|
|
|
<div
|
|
|
|
v-if="editable && hasPermission(PERMISSIONS.EDIT_PRICE)"
|
|
|
|
class="full-width row justify-end text-right"
|
|
|
|
>
|
2021-04-11 14:29:11 +00:00
|
|
|
<q-btn round icon="mdi-plus" size="sm" color="primary">
|
|
|
|
<q-tooltip> Preis hinzufügen </q-tooltip>
|
|
|
|
<q-menu anchor="center middle" self="center middle">
|
|
|
|
<new-price @save="addPrice" />
|
|
|
|
</q-menu>
|
|
|
|
</q-btn>
|
|
|
|
</div>
|
2021-04-03 20:39:06 +00:00
|
|
|
</div>
|
|
|
|
<div class="q-pa-sm">
|
2021-04-10 21:05:03 +00:00
|
|
|
<ingredients
|
2021-04-14 18:11:44 +00:00
|
|
|
v-if="!public && !costPerVolume"
|
2021-04-10 21:05:03 +00:00
|
|
|
v-model="volume.ingredients"
|
2021-04-14 20:42:09 +00:00
|
|
|
:editable="editable && hasPermission(PERMISSIONS.EDIT_INGREDIENTS_DRINK)"
|
2021-04-10 21:05:03 +00:00
|
|
|
@update="updateVolume(volume)"
|
2021-04-11 14:29:11 +00:00
|
|
|
@delete-ingredient="deleteIngredient"
|
2021-04-10 21:05:03 +00:00
|
|
|
/>
|
2021-04-03 20:39:06 +00:00
|
|
|
</div>
|
|
|
|
</q-carousel-slide>
|
|
|
|
</q-carousel>
|
2021-04-11 14:29:11 +00:00
|
|
|
<div class="full-width row justify-center q-pa-sm">
|
|
|
|
<div class="q-px-sm">
|
|
|
|
<q-btn-toggle v-model="volume" :options="options" />
|
|
|
|
</div>
|
|
|
|
<div v-if="editable" class="q-px-sm">
|
|
|
|
<q-btn class="q-px-sm" round icon="mdi-plus" color="primary" size="sm" @click="newVolume">
|
|
|
|
<q-tooltip> Abgabe hinzufügen </q-tooltip>
|
|
|
|
</q-btn>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-04-03 20:39:06 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
2021-04-11 14:29:11 +00:00
|
|
|
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
2021-04-09 21:49:49 +00:00
|
|
|
import { DrinkPriceVolume } from 'src/plugins/pricelist/store';
|
2021-04-03 20:39:06 +00:00
|
|
|
import Ingredients from 'src/plugins/pricelist/components/CalculationTable/Ingredients.vue';
|
2021-04-11 14:29:11 +00:00
|
|
|
import NewPrice from 'src/plugins/pricelist/components/CalculationTable/NewPrice.vue';
|
2021-04-10 21:05:03 +00:00
|
|
|
import { calc_volume, clone } from '../../utils/utils';
|
2021-04-14 20:42:09 +00:00
|
|
|
import { hasPermission } from 'src/utils/permission';
|
|
|
|
import { PERMISSIONS } from '../../permissions';
|
|
|
|
|
2021-04-03 20:39:06 +00:00
|
|
|
export default defineComponent({
|
|
|
|
name: 'DrinkPriceVolume',
|
2021-04-11 14:29:11 +00:00
|
|
|
components: { Ingredients, NewPrice },
|
2021-04-03 20:39:06 +00:00
|
|
|
props: {
|
2021-04-09 21:49:49 +00:00
|
|
|
modelValue: {
|
|
|
|
type: Array as PropType<Array<DrinkPriceVolume>>,
|
2021-04-03 20:39:06 +00:00
|
|
|
required: true,
|
|
|
|
},
|
2021-04-14 18:11:44 +00:00
|
|
|
costPerVolume: {
|
2021-04-14 17:44:53 +00:00
|
|
|
type: undefined,
|
2021-04-14 20:42:09 +00:00
|
|
|
default: undefined,
|
2021-04-14 17:13:47 +00:00
|
|
|
},
|
2021-04-09 21:49:49 +00:00
|
|
|
editable: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
2021-04-13 14:20:32 +00:00
|
|
|
public: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
|
|
|
},
|
|
|
|
nodetails: {
|
|
|
|
type: Boolean,
|
|
|
|
default: false,
|
2021-04-14 16:53:17 +00:00
|
|
|
},
|
2021-04-03 20:39:06 +00:00
|
|
|
},
|
2021-04-09 21:49:49 +00:00
|
|
|
emits: {
|
|
|
|
'update:modelValue': (val: Array<DrinkPriceVolume>) => val,
|
2021-04-11 14:29:11 +00:00
|
|
|
update: (val: number) => val,
|
|
|
|
'delete-volume': (val: DrinkPriceVolume) => val,
|
|
|
|
'delete-price': (val: FG.DrinkPrice) => val,
|
|
|
|
'delete-ingredient': (val: FG.Ingredient) => val,
|
2021-04-09 21:49:49 +00:00
|
|
|
},
|
|
|
|
setup(props, { emit }) {
|
|
|
|
onBeforeMount(() => {
|
2021-04-10 21:05:03 +00:00
|
|
|
//volumes.value = <Array<DrinkPriceVolume>>JSON.parse(JSON.stringify(props.modelValue));
|
|
|
|
volumes.value = clone(props.modelValue);
|
2021-04-09 21:49:49 +00:00
|
|
|
});
|
|
|
|
const volumes = ref<Array<DrinkPriceVolume>>([]);
|
|
|
|
const _volume = ref<number | undefined>();
|
|
|
|
const volume = computed<number | undefined>({
|
2021-04-03 20:39:06 +00:00
|
|
|
get: () => {
|
|
|
|
if (_volume.value !== undefined) {
|
|
|
|
return _volume.value;
|
|
|
|
}
|
2021-04-09 21:49:49 +00:00
|
|
|
if (volumes.value.length > 0) {
|
|
|
|
return volumes.value[0].id;
|
2021-04-03 20:39:06 +00:00
|
|
|
}
|
2021-04-04 21:20:53 +00:00
|
|
|
return undefined;
|
2021-04-03 20:39:06 +00:00
|
|
|
},
|
2021-04-09 21:49:49 +00:00
|
|
|
set: (val: number | undefined) => (_volume.value = val),
|
2021-04-03 20:39:06 +00:00
|
|
|
});
|
2021-04-11 14:29:11 +00:00
|
|
|
const edit_volume = computed(() => {
|
|
|
|
return volumes.value.find((a) => a.id === volume.value);
|
|
|
|
});
|
2021-04-09 21:49:49 +00:00
|
|
|
const options = computed<Array<{ label: string; value: number }>>(() => {
|
|
|
|
const retVal: Array<{ label: string; value: number }> = [];
|
|
|
|
volumes.value.forEach((volume: DrinkPriceVolume) => {
|
2021-04-11 14:29:11 +00:00
|
|
|
retVal.push({ label: `${(<number>volume.volume).toFixed(3)}L`, value: volume.id });
|
2021-04-09 21:49:49 +00:00
|
|
|
});
|
|
|
|
return retVal;
|
|
|
|
});
|
|
|
|
|
2021-04-10 21:05:03 +00:00
|
|
|
function updateVolume(_volume: DrinkPriceVolume) {
|
|
|
|
const index = volumes.value.findIndex((a) => a.id === _volume.id);
|
|
|
|
if (index > -1) {
|
|
|
|
volumes.value[index].volume = calc_volume(_volume);
|
|
|
|
}
|
2021-04-11 14:29:11 +00:00
|
|
|
change();
|
|
|
|
setTimeout(() => {
|
|
|
|
emit('update', index);
|
|
|
|
}, 50);
|
|
|
|
}
|
|
|
|
|
|
|
|
const volume_can_edit = computed(() => {
|
|
|
|
if (edit_volume.value) {
|
|
|
|
return !edit_volume.value.ingredients.some((ingredient) => ingredient.drink_ingredient);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
const newVolumeId = ref(-1);
|
|
|
|
|
|
|
|
function newVolume() {
|
|
|
|
const new_volume: DrinkPriceVolume = {
|
|
|
|
id: newVolumeId.value,
|
|
|
|
_volume: 0,
|
|
|
|
volume: 0,
|
|
|
|
prices: [],
|
|
|
|
ingredients: [],
|
|
|
|
min_prices: [],
|
|
|
|
};
|
|
|
|
newVolumeId.value--;
|
|
|
|
volumes.value.push(new_volume);
|
|
|
|
change();
|
|
|
|
_volume.value = volumes.value[volumes.value.length - 1].id;
|
|
|
|
}
|
|
|
|
|
|
|
|
function deleteVolume() {
|
|
|
|
if (edit_volume.value) {
|
|
|
|
if (edit_volume.value.id > 0) {
|
|
|
|
emit('delete-volume', edit_volume.value);
|
|
|
|
}
|
|
|
|
const index = volumes.value.findIndex((a) => a.id === edit_volume.value?.id);
|
|
|
|
if (index > -1) {
|
|
|
|
_volume.value = volumes.value[0].id;
|
|
|
|
volumes.value.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const deleteable = computed(() => {
|
|
|
|
if (edit_volume.value) {
|
|
|
|
const has_ingredients = edit_volume.value.ingredients.length > 0;
|
|
|
|
const has_prices = edit_volume.value.prices.length > 0;
|
|
|
|
|
|
|
|
return !(has_ingredients || has_prices);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
function addPrice(price: FG.DrinkPrice) {
|
|
|
|
if (edit_volume.value) {
|
|
|
|
edit_volume.value.prices.push(price);
|
|
|
|
change();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function deletePrice(price: FG.DrinkPrice) {
|
|
|
|
if (edit_volume.value) {
|
|
|
|
const index = edit_volume.value.prices.findIndex((a) => a.id === price.id);
|
|
|
|
if (index > -1) {
|
|
|
|
if (edit_volume.value.prices[index].id > 0) {
|
|
|
|
emit('delete-price', edit_volume.value.prices[index]);
|
|
|
|
change();
|
|
|
|
}
|
|
|
|
edit_volume.value.prices.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function deleteIngredient(ingredient: FG.Ingredient) {
|
|
|
|
emit('delete-ingredient', ingredient);
|
|
|
|
}
|
|
|
|
|
|
|
|
function change() {
|
|
|
|
emit('update:modelValue', volumes.value);
|
2021-04-09 21:49:49 +00:00
|
|
|
}
|
|
|
|
|
2021-04-14 17:39:05 +00:00
|
|
|
const isUnderMinPrice = computed(() => {
|
|
|
|
if (volumes.value) {
|
2021-04-14 17:44:53 +00:00
|
|
|
const this_volume = volumes.value.find((a) => a.id === volume.value);
|
2021-04-14 17:39:05 +00:00
|
|
|
if (this_volume) {
|
|
|
|
if (this_volume.min_prices.length > 0) {
|
|
|
|
const min_price = this_volume.min_prices.sort((a, b) => {
|
2021-04-14 17:44:53 +00:00
|
|
|
if (a.price > b.price) return 1;
|
|
|
|
if (a.price < b.price) return -1;
|
|
|
|
return 0;
|
|
|
|
})[0];
|
|
|
|
console.log('min_price', min_price);
|
|
|
|
return this_volume.prices.some((a) => a.price < min_price.price);
|
2021-04-14 17:39:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-14 17:44:53 +00:00
|
|
|
return false;
|
|
|
|
});
|
2021-04-14 17:39:05 +00:00
|
|
|
|
2021-04-11 14:29:11 +00:00
|
|
|
return {
|
|
|
|
volumes,
|
|
|
|
volume,
|
|
|
|
options,
|
|
|
|
updateVolume,
|
|
|
|
volume_can_edit,
|
|
|
|
newVolume,
|
|
|
|
deleteable,
|
|
|
|
addPrice,
|
|
|
|
deletePrice,
|
|
|
|
deleteVolume,
|
|
|
|
deleteIngredient,
|
|
|
|
change,
|
2021-04-14 17:44:53 +00:00
|
|
|
isUnderMinPrice,
|
2021-04-14 20:42:09 +00:00
|
|
|
hasPermission,
|
|
|
|
PERMISSIONS,
|
2021-04-11 14:29:11 +00:00
|
|
|
};
|
2021-04-03 20:39:06 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
2021-04-14 17:39:05 +00:00
|
|
|
<style scoped>
|
|
|
|
.warning {
|
|
|
|
border-radius: 5px;
|
|
|
|
}
|
|
|
|
</style>
|