flaschengeist-frontend/src/plugins/pricelist/components/CalculationTable/DrinkPriceVolumes.vue

288 lines
8.7 KiB
Vue
Raw Normal View History

<template>
<q-carousel
v-model="volume"
transition-prev="slide-right"
transition-next="slide-left"
animated
swipeable
control-color="primary"
arrows
:keep-alive="false"
>
2021-04-09 21:49:49 +00:00
<q-carousel-slide v-for="volume in volumes" :key="volume.id" :name="volume.id">
<div class="full-width row">
<q-input
v-model.number="volume._volume"
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"
@update:model-value="updateVolume(volume)"
/>
<div v-if="deleteable && editable" class="q-pa-sm col-2 text-right">
<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">
<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">
<div v-if="!editable" 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"
class="col-3"
2021-04-09 21:49:49 +00:00
type="number"
min="0"
step="0.01"
suffix="€"
filled
dense
label="Preis"
@update:model-value="change"
2021-04-09 21:49:49 +00:00
/>
<div class="text-body1 col-2">
<q-toggle
2021-04-09 21:49:49 +00:00
v-model="price.public"
:disable="!editable"
checked-icon="mdi-earth"
unchecked-icon="mdi-earth-off"
@update:model-value="change"
/>
</div>
<div v-if="!editable" class="text-body1 col-5">
{{ price.description }}
</div>
2021-04-09 21:49:49 +00:00
<q-input
v-else
v-model="price.description"
class="col-5"
2021-04-09 21:49:49 +00:00
filled
dense
label="Beschreibung"
@update:model-value="change"
2021-04-09 21:49:49 +00:00
/>
<div v-if="editable" class="col-1">
<q-btn round icon="mdi-delete" color="negative" size="xs" @click="deletePrice(price)">
<q-tooltip> Preis entfernen </q-tooltip>
</q-btn>
</div>
</div>
<q-separator v-if="index < volume.prices.length - 1" />
</div>
<div v-if="editable" class="full-width row justify-end text-right">
<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>
</div>
<div class="q-pa-sm">
<ingredients
v-if="!public"
v-model="volume.ingredients"
:editable="editable"
@update="updateVolume(volume)"
@delete-ingredient="deleteIngredient"
/>
</div>
</q-carousel-slide>
</q-carousel>
<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>
</template>
<script lang="ts">
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
2021-04-09 21:49:49 +00:00
import { DrinkPriceVolume } from 'src/plugins/pricelist/store';
import Ingredients from 'src/plugins/pricelist/components/CalculationTable/Ingredients.vue';
import NewPrice from 'src/plugins/pricelist/components/CalculationTable/NewPrice.vue';
import { calc_volume, clone } from '../../utils/utils';
export default defineComponent({
name: 'DrinkPriceVolume',
components: { Ingredients, NewPrice },
props: {
2021-04-09 21:49:49 +00:00
modelValue: {
type: Array as PropType<Array<DrinkPriceVolume>>,
required: true,
},
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-09 21:49:49 +00:00
emits: {
'update:modelValue': (val: Array<DrinkPriceVolume>) => val,
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(() => {
//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>({
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;
}
return undefined;
},
2021-04-09 21:49:49 +00:00
set: (val: number | undefined) => (_volume.value = val),
});
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) => {
retVal.push({ label: `${(<number>volume.volume).toFixed(3)}L`, value: volume.id });
2021-04-09 21:49:49 +00:00
});
return retVal;
});
function updateVolume(_volume: DrinkPriceVolume) {
const index = volumes.value.findIndex((a) => a.id === _volume.id);
if (index > -1) {
volumes.value[index].volume = calc_volume(_volume);
}
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
}
return {
volumes,
volume,
options,
updateVolume,
volume_can_edit,
newVolume,
deleteable,
addPrice,
deletePrice,
deleteVolume,
deleteIngredient,
change,
};
},
});
</script>
<style scoped></style>