[pricelist] cleanup some code
This commit is contained in:
parent
1c64dbbaf6
commit
7a3a151688
|
@ -371,8 +371,13 @@
|
||||||
props.row.uuid ? `/api/pricelist/picture/${props.row.uuid}?size=256` : 'no-image.svg'
|
props.row.uuid ? `/api/pricelist/picture/${props.row.uuid}?size=256` : 'no-image.svg'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class='absolute-top-right justify-end' style='background-color: transparent;'>
|
<div class="absolute-top-right justify-end" style="background-color: transparent">
|
||||||
<q-btn @click="console.log('hallo')" round icon='mdi-pencil' style='background-color: rgba(0,0,0,0.5)'/>
|
<q-btn
|
||||||
|
round
|
||||||
|
icon="mdi-pencil"
|
||||||
|
style="background-color: rgba(0, 0, 0, 0.5)"
|
||||||
|
@click="editDrink = props.row"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute-bottom-right justify-end">
|
<div class="absolute-bottom-right justify-end">
|
||||||
<div class="text-subtitle1 text-right">
|
<div class="text-subtitle1 text-right">
|
||||||
|
@ -447,14 +452,20 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
||||||
<q-card-section v-if="props.row.volumes.length > 0">
|
<q-card-section v-if="props.row.volumes.length > 0">
|
||||||
<drink-price-volumes :props="props.row" />
|
<drink-price-volumes v-model="props.row.volumes" />
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</q-table>
|
</q-table>
|
||||||
|
<q-dialog :model-value="editDrink !== undefined" persistent>
|
||||||
|
<drink-modify
|
||||||
|
:drink="editDrink"
|
||||||
|
@save="editDrink = undefined"
|
||||||
|
@cancel="editDrink = undefined"
|
||||||
|
/>
|
||||||
|
</q-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -467,6 +478,7 @@ import NewDrink from 'src/plugins/pricelist/components/CalculationTable/NewDrink
|
||||||
import BuildManual from 'src/plugins/pricelist/components/CalculationTable/BuildManual.vue';
|
import BuildManual from 'src/plugins/pricelist/components/CalculationTable/BuildManual.vue';
|
||||||
import SearchInput from './SearchInput.vue';
|
import SearchInput from './SearchInput.vue';
|
||||||
import DrinkPriceVolumes from 'src/plugins/pricelist/components/CalculationTable/DrinkPriceVolumes.vue';
|
import DrinkPriceVolumes from 'src/plugins/pricelist/components/CalculationTable/DrinkPriceVolumes.vue';
|
||||||
|
import DrinkModify from './DrinkModify.vue';
|
||||||
import { filter, Search } from '../utils/filter';
|
import { filter, Search } from '../utils/filter';
|
||||||
import { Notify } from 'quasar';
|
import { Notify } from 'quasar';
|
||||||
import { sort } from '../utils/sort';
|
import { sort } from '../utils/sort';
|
||||||
|
@ -480,6 +492,7 @@ export default defineComponent({
|
||||||
BuildManual,
|
BuildManual,
|
||||||
DrinkPriceVolumesTable,
|
DrinkPriceVolumesTable,
|
||||||
DrinkPriceVolumes,
|
DrinkPriceVolumes,
|
||||||
|
DrinkModify,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const mainStore = useMainStore();
|
const mainStore = useMainStore();
|
||||||
|
@ -715,6 +728,7 @@ export default defineComponent({
|
||||||
label: '',
|
label: '',
|
||||||
});
|
});
|
||||||
const grid = ref(true);
|
const grid = ref(true);
|
||||||
|
const editDrink = ref();
|
||||||
return {
|
return {
|
||||||
drinks: computed(() => store.drinks),
|
drinks: computed(() => store.drinks),
|
||||||
pagination,
|
pagination,
|
||||||
|
@ -737,6 +751,7 @@ export default defineComponent({
|
||||||
search_keys,
|
search_keys,
|
||||||
grid,
|
grid,
|
||||||
tags: computed(() => store.tags),
|
tags: computed(() => store.tags),
|
||||||
|
editDrink,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,7 +37,7 @@ export default defineComponent({
|
||||||
const emptyVolume: DrinkPriceVolume = {
|
const emptyVolume: DrinkPriceVolume = {
|
||||||
id: -1,
|
id: -1,
|
||||||
_volume: 0,
|
_volume: 0,
|
||||||
min_prices: [{ percentage: 100 }, { percentage: 250 }, { percentage: 300 }],
|
min_prices: [],
|
||||||
prices: [],
|
prices: [],
|
||||||
ingredients: [],
|
ingredients: [],
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,17 +9,20 @@
|
||||||
navigation
|
navigation
|
||||||
arrows
|
arrows
|
||||||
>
|
>
|
||||||
<q-carousel-slide v-for="volume in props.volumes" :key="volume.id" :name="volume.id">
|
<q-carousel-slide v-for="volume in volumes" :key="volume.id" :name="volume.id">
|
||||||
<q-input
|
<q-input
|
||||||
|
v-model.number="volume.volume"
|
||||||
class="q-pa-sm"
|
class="q-pa-sm"
|
||||||
:model-value="volume.volume"
|
:outlined="!editable"
|
||||||
outlined
|
:filled="editable"
|
||||||
readonly
|
:readonly="!editable"
|
||||||
dense
|
dense
|
||||||
label="Inhalt"
|
label="Inhalt"
|
||||||
mask="#.###"
|
mask="#.###"
|
||||||
fill-mask="0"
|
fill-mask="0"
|
||||||
suffix="L"
|
suffix="L"
|
||||||
|
min="0"
|
||||||
|
step="0.001"
|
||||||
/>
|
/>
|
||||||
<div class="full-width row q-gutter-sm q-pa-sm justify-around">
|
<div class="full-width row q-gutter-sm q-pa-sm justify-around">
|
||||||
<div v-for="(min_price, index) in volume.min_prices" :key="index">
|
<div v-for="(min_price, index) in volume.min_prices" :key="index">
|
||||||
|
@ -30,58 +33,104 @@
|
||||||
<div class="q-pa-sm">
|
<div class="q-pa-sm">
|
||||||
<div v-for="(price, index) in volume.prices" :key="price.id">
|
<div v-for="(price, index) in volume.prices" :key="price.id">
|
||||||
<div class="fit row justify-around q-py-sm">
|
<div class="fit row justify-around q-py-sm">
|
||||||
<div class="text-body1 col-xs-12 col-md-4">{{ price.price.toFixed(2) }}€</div>
|
<div v-if="!editable" class="text-body1 col-xs-12 col-md-3">
|
||||||
<div class="text-body1 col-xs-12 col-md-4">
|
{{ price.price.toFixed(2) }}€
|
||||||
|
</div>
|
||||||
|
<q-input
|
||||||
|
v-else
|
||||||
|
v-model.number="price.price"
|
||||||
|
class="col-xs-12 col-md-3"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="0.01"
|
||||||
|
suffix="€"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
label="Preis"
|
||||||
|
/>
|
||||||
|
<div class="text-body1 col-xs-12 col-md-2">
|
||||||
<q-toggle
|
<q-toggle
|
||||||
:model-value="price.public"
|
v-model="price.public"
|
||||||
disable
|
:disable="!editable"
|
||||||
checked-icon="mdi-earth"
|
checked-icon="mdi-earth"
|
||||||
unchecked-icon="mdi-earth-off"
|
unchecked-icon="mdi-earth-off"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-body1 col-xs-12 col-md-4">
|
<div v-if="!editable" class="text-body1 col-xs-12 col-md-5">
|
||||||
{{ price.description }}
|
{{ price.description }}
|
||||||
</div>
|
</div>
|
||||||
|
<q-input
|
||||||
|
v-else
|
||||||
|
v-model="price.description"
|
||||||
|
class="col-xs-12 col-md-5"
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
label="Beschreibung"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<q-separator v-if="index < volume.prices.length - 1" />
|
<q-separator v-if="index < volume.prices.length - 1" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="q-pa-sm">
|
<div class="q-pa-sm">
|
||||||
<ingredients :ingredients="volume.ingredients" :volume="volume" />
|
<ingredients v-model="volume.ingredients" :editable="editable" />
|
||||||
</div>
|
</div>
|
||||||
</q-carousel-slide>
|
</q-carousel-slide>
|
||||||
</q-carousel>
|
</q-carousel>
|
||||||
|
<q-btn-toggle v-model="volume" :options="options" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType, ref } from 'vue';
|
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
||||||
import { Drink } from 'src/plugins/pricelist/store';
|
import { DrinkPriceVolume } from 'src/plugins/pricelist/store';
|
||||||
import Ingredients from 'src/plugins/pricelist/components/CalculationTable/Ingredients.vue';
|
import Ingredients from 'src/plugins/pricelist/components/CalculationTable/Ingredients.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DrinkPriceVolume',
|
name: 'DrinkPriceVolume',
|
||||||
components: { Ingredients },
|
components: { Ingredients },
|
||||||
props: {
|
props: {
|
||||||
props: {
|
modelValue: {
|
||||||
type: Object as PropType<Drink>,
|
type: Array as PropType<Array<DrinkPriceVolume>>,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
editable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
},
|
},
|
||||||
setup(props) {
|
},
|
||||||
const _volume = ref<number|undefined>();
|
emits: {
|
||||||
const volume = computed<number|undefined>({
|
'update:modelValue': (val: Array<DrinkPriceVolume>) => val,
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
onBeforeMount(() => {
|
||||||
|
volumes.value = <Array<DrinkPriceVolume>>[...props.modelValue];
|
||||||
|
});
|
||||||
|
const volumes = ref<Array<DrinkPriceVolume>>([]);
|
||||||
|
const _volume = ref<number | undefined>();
|
||||||
|
const volume = computed<number | undefined>({
|
||||||
get: () => {
|
get: () => {
|
||||||
if (_volume.value !== undefined) {
|
if (_volume.value !== undefined) {
|
||||||
return _volume.value;
|
return _volume.value;
|
||||||
}
|
}
|
||||||
if (props.props.volumes.length > 0) {
|
if (volumes.value.length > 0) {
|
||||||
return props.props.volumes[0].id;
|
return volumes.value[0].id;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
set: (val: number|undefined) => (_volume.value = val),
|
set: (val: number | undefined) => (_volume.value = val),
|
||||||
});
|
});
|
||||||
return { volume };
|
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}L`, value: volume.id });
|
||||||
|
});
|
||||||
|
return retVal;
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateVolume() {
|
||||||
|
emit('update:modelValue', volumes.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { volumes, volume, options, updateVolume };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="full-width">
|
<div class="full-width">
|
||||||
<div
|
<div
|
||||||
v-for="ingredient in ingredients"
|
v-for="ingredient in edit_ingredients"
|
||||||
:key="`volume:${volume.id},ingredient:${ingredient.id}`"
|
:key="`ingredient:${ingredient.id}`"
|
||||||
class="full-width row justify-evenly q-py-xs"
|
class="full-width row justify-evenly q-py-xs"
|
||||||
>
|
>
|
||||||
<div class="full-width row justify-evenly">
|
<div class="full-width row justify-evenly">
|
||||||
|
@ -11,14 +11,16 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{{ get_drink_ingredient_name(ingredient.drink_ingredient.ingredient_id) }}
|
{{ get_drink_ingredient_name(ingredient.drink_ingredient.ingredient_id) }}
|
||||||
<q-popup-edit
|
<q-popup-edit
|
||||||
|
v-if="editable"
|
||||||
|
v-slot="scope"
|
||||||
v-model="ingredient.drink_ingredient.ingredient_id"
|
v-model="ingredient.drink_ingredient.ingredient_id"
|
||||||
buttons
|
buttons
|
||||||
label-cancel="Abbrechen"
|
label-cancel="Abbrechen"
|
||||||
label-set="Speichern"
|
label-set="Speichern"
|
||||||
@save="updateDrink"
|
@save="updateValue"
|
||||||
>
|
>
|
||||||
<q-select
|
<q-select
|
||||||
v-model="ingredient.drink_ingredient.ingredient_id"
|
v-model="scope.ingredient_id"
|
||||||
class="col q-px-sm"
|
class="col q-px-sm"
|
||||||
label="Getränk"
|
label="Getränk"
|
||||||
filled
|
filled
|
||||||
|
@ -34,14 +36,16 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{{ ingredient.drink_ingredient.volume.toFixed(3) }}L
|
{{ ingredient.drink_ingredient.volume.toFixed(3) }}L
|
||||||
<q-popup-edit
|
<q-popup-edit
|
||||||
|
v-if="editable"
|
||||||
|
v-slot="scope"
|
||||||
v-model="ingredient.drink_ingredient.volume"
|
v-model="ingredient.drink_ingredient.volume"
|
||||||
buttons
|
buttons
|
||||||
label-cancel="Abbrechen"
|
label-cancel="Abbrechen"
|
||||||
label-set="Speichern"
|
label-set="Speichern"
|
||||||
@save="updateDrink"
|
@save="updateValue"
|
||||||
>
|
>
|
||||||
<q-input
|
<q-input
|
||||||
v-model.number="ingredient.drink_ingredient.volume"
|
v-model.number="scope.value"
|
||||||
class="col q-px-sm"
|
class="col q-px-sm"
|
||||||
label="Volume"
|
label="Volume"
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -63,11 +67,12 @@
|
||||||
<div class="col">{{ ingredient.extra_ingredient.price.toFixed(3) }}€</div>
|
<div class="col">{{ ingredient.extra_ingredient.price.toFixed(3) }}€</div>
|
||||||
</div>
|
</div>
|
||||||
<q-popup-edit
|
<q-popup-edit
|
||||||
|
v-if="editable"
|
||||||
v-model="ingredient.extra_ingredient"
|
v-model="ingredient.extra_ingredient"
|
||||||
buttons
|
buttons
|
||||||
label-cancel="Abbrechen"
|
label-cancel="Abbrechen"
|
||||||
label-set="Speichern"
|
label-set="Speichern"
|
||||||
@save="updateDrink"
|
@save="updateValue"
|
||||||
>
|
>
|
||||||
<q-select
|
<q-select
|
||||||
v-model="ingredient.extra_ingredient"
|
v-model="ingredient.extra_ingredient"
|
||||||
|
@ -78,19 +83,19 @@
|
||||||
/>
|
/>
|
||||||
</q-popup-edit>
|
</q-popup-edit>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-1 row justify-end q-pa-xs">
|
<div v-if="editable" class="col-1 row justify-end q-pa-xs">
|
||||||
<q-btn
|
<q-btn
|
||||||
icon="mdi-delete"
|
icon="mdi-delete"
|
||||||
round
|
round
|
||||||
size="xs"
|
size="xs"
|
||||||
color="negative"
|
color="negative"
|
||||||
@click="deleteIngredient(ingredient, volume)"
|
@click="deleteIngredient(ingredient)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-separator />
|
<q-separator />
|
||||||
</div>
|
</div>
|
||||||
<div class="full-width row justify-end q-py-xs">
|
<div v-if="editable" class="full-width row justify-end q-py-xs">
|
||||||
<q-btn size="sm" icon-right="mdi-plus" color="positive" label="Zutat hinzufügen">
|
<q-btn size="sm" icon-right="mdi-plus" color="positive" label="Zutat hinzufügen">
|
||||||
<q-menu anchor="center middle" self="center middle">
|
<q-menu anchor="center middle" self="center middle">
|
||||||
<div class="full-width row justify-around q-gutter-sm q-pa-sm">
|
<div class="full-width row justify-around q-gutter-sm q-pa-sm">
|
||||||
|
@ -133,12 +138,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="full-width row jusitfy-between q-gutter-sm q-pa-sm">
|
<div class="full-width row jusitfy-between q-gutter-sm q-pa-sm">
|
||||||
<q-btn v-close-popup label="Abbrechen" @click="cancelAddIngredient" />
|
<q-btn v-close-popup label="Abbrechen" @click="cancelAddIngredient" />
|
||||||
<q-btn
|
<q-btn v-close-popup label="Speichern" color="positive" @click="addIngredient" />
|
||||||
v-close-popup
|
|
||||||
label="Speichern"
|
|
||||||
color="positive"
|
|
||||||
@click="addIngredient(volume)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</q-menu>
|
</q-menu>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
|
@ -147,34 +147,39 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType, ref } from 'vue';
|
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
||||||
import { DrinkPriceVolume, usePricelistStore } from '../../store';
|
import { usePricelistStore } from '../../store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Ingredients',
|
name: 'Ingredients',
|
||||||
props: {
|
props: {
|
||||||
ingredients: {
|
modelValue: {
|
||||||
type: Array as PropType<FG.Ingredient[]>,
|
type: Object as PropType<Array<FG.Ingredient>>,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
volume: {
|
editable: {
|
||||||
type: Object /*as PropType<DrinkPriceVolume>*/,
|
type: Boolean,
|
||||||
required: true,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
updateDrink: () => true,
|
'update:modelValue': (val: Array<FG.Ingredient>) => val,
|
||||||
addIngredient: (val: FG.Ingredient, volume: DrinkPriceVolume) =>
|
|
||||||
(val.drink_ingredient || val.extra_ingredient) && volume,
|
|
||||||
deleteIngredient: (ingredient: FG.Ingredient, volume: DrinkPriceVolume) =>
|
|
||||||
(ingredient.drink_ingredient || ingredient.extra_ingredient) && volume,
|
|
||||||
},
|
},
|
||||||
setup(_, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
onBeforeMount(() => {
|
||||||
|
edit_ingredients.value = [];
|
||||||
|
props.modelValue.forEach((a) => {
|
||||||
|
edit_ingredients.value.push(Object.assign({}, a));
|
||||||
|
});
|
||||||
|
console.log(edit_ingredients);
|
||||||
|
});
|
||||||
|
|
||||||
const store = usePricelistStore();
|
const store = usePricelistStore();
|
||||||
|
|
||||||
|
const edit_ingredients = ref<Array<FG.Ingredient>>([]);
|
||||||
const newIngredient = ref<FG.Drink | FG.ExtraIngredient>();
|
const newIngredient = ref<FG.Drink | FG.ExtraIngredient>();
|
||||||
const newIngredientVolume = ref<number>(0);
|
const newIngredientVolume = ref<number>(0);
|
||||||
function addIngredient(volume: DrinkPriceVolume) {
|
function addIngredient() {
|
||||||
let _ingredient: FG.Ingredient;
|
let _ingredient: FG.Ingredient;
|
||||||
if ((<FG.Drink>newIngredient.value)?.volume && newIngredient.value) {
|
if ((<FG.Drink>newIngredient.value)?.volume && newIngredient.value) {
|
||||||
_ingredient = {
|
_ingredient = {
|
||||||
|
@ -193,20 +198,27 @@ export default defineComponent({
|
||||||
extra_ingredient: <FG.ExtraIngredient>newIngredient.value,
|
extra_ingredient: <FG.ExtraIngredient>newIngredient.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
emit('addIngredient', _ingredient, volume);
|
edit_ingredients.value.push(_ingredient);
|
||||||
|
emit('update:modelValue', edit_ingredients.value);
|
||||||
cancelAddIngredient();
|
cancelAddIngredient();
|
||||||
}
|
}
|
||||||
function updateDrink() {
|
|
||||||
console.log('updateDrink from Ingredients');
|
function updateValue(value: number, initValue: number) {
|
||||||
emit('updateDrink');
|
console.log('updateValue', value, initValue);
|
||||||
|
emit('update:modelValue', edit_ingredients.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancelAddIngredient() {
|
function cancelAddIngredient() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
(newIngredient.value = undefined), (newIngredientVolume.value = 0);
|
(newIngredient.value = undefined), (newIngredientVolume.value = 0);
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
function deleteIngredient(ingredient: FG.Ingredient, volume: DrinkPriceVolume) {
|
function deleteIngredient(ingredient: FG.Ingredient) {
|
||||||
emit('deleteIngredient', ingredient, volume);
|
const index = edit_ingredients.value.findIndex((a) => a.id === ingredient.id);
|
||||||
|
if (index > -1) {
|
||||||
|
edit_ingredients.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
emit('update:modelValue', edit_ingredients.value);
|
||||||
}
|
}
|
||||||
const drinks = computed(() =>
|
const drinks = computed(() =>
|
||||||
store.drinks.filter((drink) => {
|
store.drinks.filter((drink) => {
|
||||||
|
@ -227,9 +239,10 @@ export default defineComponent({
|
||||||
newIngredient,
|
newIngredient,
|
||||||
newIngredientVolume,
|
newIngredientVolume,
|
||||||
cancelAddIngredient,
|
cancelAddIngredient,
|
||||||
updateDrink,
|
updateValue,
|
||||||
deleteIngredient,
|
deleteIngredient,
|
||||||
get_drink_ingredient_name,
|
get_drink_ingredient_name,
|
||||||
|
edit_ingredients,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
<template>
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6">Getränk Bearbeiten</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="fit row">
|
||||||
|
<q-input
|
||||||
|
v-model="edit_drink.article_id"
|
||||||
|
class="col-xs-12 col-sm-6 q-pa-sm"
|
||||||
|
filled
|
||||||
|
label="Artikelnummer"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
<q-input
|
||||||
|
v-model="edit_drink.volume"
|
||||||
|
class="col-xs-12 col-sm-6 q-pa-sm"
|
||||||
|
filled
|
||||||
|
label="Inhalt"
|
||||||
|
dense
|
||||||
|
suffix="L"
|
||||||
|
/>
|
||||||
|
<q-input
|
||||||
|
v-model="edit_drink.package_size"
|
||||||
|
class="col-xs-12 col-sm-6 q-pa-sm"
|
||||||
|
filled
|
||||||
|
label="Gebindegröße"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
<q-input
|
||||||
|
v-model="edit_drink.cost_per_package"
|
||||||
|
class="col-xs-12 col-sm-6 q-pa-sm"
|
||||||
|
filled
|
||||||
|
label="Preis Gebinde"
|
||||||
|
suffix="€"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
<q-input
|
||||||
|
v-model="edit_drink.cost_per_volume"
|
||||||
|
class="col-xs-12 col-sm-6 q-pa-sm q-pb-lg"
|
||||||
|
filled
|
||||||
|
label="Preis pro L"
|
||||||
|
hint="Inkl. 19% Mehrwertsteuer"
|
||||||
|
suffix="€"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section>
|
||||||
|
<drink-price-volumes v-model="edit_drink.volumes" editable />
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-actions class="justify-around">
|
||||||
|
<q-btn label="Abbrechen" @click="cancel" />
|
||||||
|
<q-btn label="Speichern" color="primary" @click="save" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
||||||
|
import { Drink, DrinkPriceVolume } from '../store';
|
||||||
|
import DrinkPriceVolumes from './CalculationTable/DrinkPriceVolumes.vue';
|
||||||
|
import { calc_volume } from 'src/plugins/pricelist/utils/utils';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'DrinkModify',
|
||||||
|
components: { DrinkPriceVolumes },
|
||||||
|
props: {
|
||||||
|
drink: {
|
||||||
|
type: Object as PropType<Drink>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: { save: () => true, cancel: () => true },
|
||||||
|
setup(props, { emit }) {
|
||||||
|
onBeforeMount(() => {
|
||||||
|
edit_drink.value = Object.assign({}, props.drink);
|
||||||
|
});
|
||||||
|
|
||||||
|
const edit_drink = ref<Drink>();
|
||||||
|
function save() {
|
||||||
|
emit('save');
|
||||||
|
}
|
||||||
|
function cancel() {
|
||||||
|
emit('cancel');
|
||||||
|
}
|
||||||
|
function updateVolume(volume: DrinkPriceVolume) {
|
||||||
|
if (volume) {
|
||||||
|
console.log('edit_volume', volume);
|
||||||
|
volume.volume = calc_volume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { edit_drink, save, cancel, updateVolume };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -27,7 +27,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
|
import { defineComponent, onBeforeMount, ref } from 'vue';
|
||||||
import Ingredients from 'src/plugins/pricelist/components/CalculationTable/Ingredients.vue';
|
import Ingredients from 'src/plugins/pricelist/components/CalculationTable/Ingredients.vue';
|
||||||
import { DrinkPriceVolume, usePricelistStore } from 'src/plugins/pricelist/store';
|
import { DrinkPriceVolume, usePricelistStore } from 'src/plugins/pricelist/store';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -39,7 +39,7 @@ export default defineComponent({
|
||||||
store.min_prices.forEach((min_price) => {
|
store.min_prices.forEach((min_price) => {
|
||||||
(<DrinkPriceVolume>volume.value).min_prices.push({
|
(<DrinkPriceVolume>volume.value).min_prices.push({
|
||||||
percentage: min_price,
|
percentage: min_price,
|
||||||
price: computed<number>(() => {
|
price: /*computed<number>(() => {
|
||||||
let retVal = 0;
|
let retVal = 0;
|
||||||
let extraIngredientPrice = 0;
|
let extraIngredientPrice = 0;
|
||||||
volume.value.ingredients.forEach((ingredient) => {
|
volume.value.ingredients.forEach((ingredient) => {
|
||||||
|
@ -55,7 +55,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return (retVal * min_price) / 100 + extraIngredientPrice;
|
return (retVal * min_price) / 100 + extraIngredientPrice;
|
||||||
}),
|
}) */ 0,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
import { api } from 'src/boot/axios';
|
import { api } from 'src/boot/axios';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { AxiosResponse } from 'axios';
|
import { AxiosResponse } from 'axios';
|
||||||
import { computed, ComputedRef, WritableComputedRef } from 'vue';
|
import {
|
||||||
|
calc_volume,
|
||||||
|
calc_cost_per_volume,
|
||||||
|
calc_all_min_prices,
|
||||||
|
} from 'src/plugins/pricelist/utils/utils';
|
||||||
|
|
||||||
interface MinPrice extends Omit<FG.MinPrices, 'price'> {
|
interface DrinkPriceVolume extends Omit<FG.DrinkPriceVolume, 'volume'> {
|
||||||
price?: WritableComputedRef<number>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DrinkPriceVolume extends Omit<Omit<FG.DrinkPriceVolume, 'volume'>, 'min_prices'> {
|
|
||||||
_volume: number;
|
_volume: number;
|
||||||
volume?: WritableComputedRef<number>;
|
volume?: number;
|
||||||
min_prices: MinPrice[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Drink extends Omit<Omit<FG.Drink, 'cost_per_volume'>, 'volumes'> {
|
interface Drink extends Omit<Omit<FG.Drink, 'cost_per_volume'>, 'volumes'> {
|
||||||
volumes: DrinkPriceVolume[];
|
volumes: DrinkPriceVolume[];
|
||||||
cost_per_volume: WritableComputedRef<number | undefined>;
|
cost_per_volume?: number;
|
||||||
_cost_per_volume?: number;
|
_cost_per_volume?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,23 +25,7 @@ class DrinkPriceVolume implements DrinkPriceVolume {
|
||||||
this.prices = prices;
|
this.prices = prices;
|
||||||
this.ingredients = ingredients;
|
this.ingredients = ingredients;
|
||||||
this.min_prices = [];
|
this.min_prices = [];
|
||||||
this.volume = computed<number>({
|
this.volume = calc_volume(this);
|
||||||
get: () => {
|
|
||||||
if (this.ingredients.some((ingredient) => !!ingredient.drink_ingredient)) {
|
|
||||||
let retVal = 0;
|
|
||||||
this.ingredients.forEach((ingredient) => {
|
|
||||||
if (ingredient.drink_ingredient?.volume) {
|
|
||||||
retVal += ingredient.drink_ingredient.volume;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._volume = retVal;
|
|
||||||
return retVal;
|
|
||||||
} else {
|
|
||||||
return this._volume;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set: (val) => (this._volume = val),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,18 +50,7 @@ class Drink {
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
this.cost_per_package = cost_per_package;
|
this.cost_per_package = cost_per_package;
|
||||||
this._cost_per_volume = cost_per_volume;
|
this._cost_per_volume = cost_per_volume;
|
||||||
this.cost_per_volume = computed({
|
this.cost_per_volume = calc_cost_per_volume(this);
|
||||||
get: () => {
|
|
||||||
if (!!this.volume && !!this.package_size && !!this.cost_per_package) {
|
|
||||||
const retVal =
|
|
||||||
((this.cost_per_package || 0) / ((this.volume || 0) * (this.package_size || 0))) * 1.19;
|
|
||||||
this._cost_per_volume = Math.round(retVal * 1000) / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._cost_per_volume;
|
|
||||||
},
|
|
||||||
set: (val) => (this._cost_per_volume = val),
|
|
||||||
});
|
|
||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.volumes = [];
|
this.volumes = [];
|
||||||
|
@ -164,7 +136,7 @@ export const usePricelistStore = defineStore({
|
||||||
});
|
});
|
||||||
this.drinks.push(_drink);
|
this.drinks.push(_drink);
|
||||||
});
|
});
|
||||||
this.create_min_prices();
|
calc_all_min_prices(this.drinks, this.min_prices);
|
||||||
console.log(this.drinks);
|
console.log(this.drinks);
|
||||||
},
|
},
|
||||||
sortPrices(volume: DrinkPriceVolume) {
|
sortPrices(volume: DrinkPriceVolume) {
|
||||||
|
@ -217,7 +189,7 @@ export const usePricelistStore = defineStore({
|
||||||
_drink.volumes.push(_volume);
|
_drink.volumes.push(_volume);
|
||||||
});
|
});
|
||||||
this.drinks.push(_drink);
|
this.drinks.push(_drink);
|
||||||
this.create_min_prices();
|
calc_all_min_prices(this.drinks, this.min_prices);
|
||||||
},
|
},
|
||||||
async updateDrink(drink: Drink) {
|
async updateDrink(drink: Drink) {
|
||||||
console.log(drink);
|
console.log(drink);
|
||||||
|
@ -234,7 +206,7 @@ export const usePricelistStore = defineStore({
|
||||||
});
|
});
|
||||||
this.drinks[index] = _drink;
|
this.drinks[index] = _drink;
|
||||||
}
|
}
|
||||||
this.create_min_prices();
|
calc_all_min_prices(this.drinks, this.min_prices);
|
||||||
},
|
},
|
||||||
deleteDrink(drink: Drink) {
|
deleteDrink(drink: Drink) {
|
||||||
api
|
api
|
||||||
|
@ -271,46 +243,7 @@ export const usePricelistStore = defineStore({
|
||||||
},
|
},
|
||||||
async set_min_prices() {
|
async set_min_prices() {
|
||||||
await api.post<Array<number>>('pricelist/settings/min_prices', this.min_prices);
|
await api.post<Array<number>>('pricelist/settings/min_prices', this.min_prices);
|
||||||
this.create_min_prices();
|
calc_all_min_prices(this.drinks, this.min_prices);
|
||||||
},
|
|
||||||
create_min_prices() {
|
|
||||||
this.drinks.forEach((drink) => {
|
|
||||||
drink.volumes.forEach((volume) => {
|
|
||||||
volume.min_prices = [];
|
|
||||||
this.min_prices.forEach((min_price) => {
|
|
||||||
let computedMinPrice: ComputedRef;
|
|
||||||
if (drink.cost_per_volume) {
|
|
||||||
computedMinPrice = computed<number>(
|
|
||||||
() =>
|
|
||||||
(<number>(<unknown>drink.cost_per_volume) *
|
|
||||||
<number>(<unknown>volume.volume) *
|
|
||||||
min_price) /
|
|
||||||
100
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
computedMinPrice = computed<number>(() => {
|
|
||||||
let retVal = 0;
|
|
||||||
let extraIngredientPrice = 0;
|
|
||||||
volume.ingredients.forEach((ingredient) => {
|
|
||||||
if (ingredient.drink_ingredient) {
|
|
||||||
const _drink = usePricelistStore().drinks.find(
|
|
||||||
(a) => a.id === ingredient.drink_ingredient?.ingredient_id
|
|
||||||
);
|
|
||||||
retVal +=
|
|
||||||
ingredient.drink_ingredient.volume *
|
|
||||||
<number>(<unknown>_drink?.cost_per_volume);
|
|
||||||
}
|
|
||||||
if (ingredient.extra_ingredient) {
|
|
||||||
extraIngredientPrice += ingredient.extra_ingredient.price;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return (retVal * min_price) / 100 + extraIngredientPrice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
volume.min_prices.push({ percentage: min_price, price: computedMinPrice });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
async upload_drink_picture(drink: Drink, file: File) {
|
async upload_drink_picture(drink: Drink, file: File) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
@ -351,4 +284,4 @@ export const usePricelistStore = defineStore({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export { DrinkPriceVolume, MinPrice, Drink };
|
export { DrinkPriceVolume, Drink };
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { Drink, DrinkPriceVolume, usePricelistStore } from 'src/plugins/pricelist/store';
|
||||||
|
|
||||||
|
function calc_volume(volume: DrinkPriceVolume) {
|
||||||
|
if (volume.ingredients.some((ingredient) => !!ingredient.drink_ingredient)) {
|
||||||
|
let retVal = 0;
|
||||||
|
volume.ingredients.forEach((ingredient) => {
|
||||||
|
if (ingredient.drink_ingredient?.volume) {
|
||||||
|
retVal += ingredient.drink_ingredient.volume;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return retVal;
|
||||||
|
} else {
|
||||||
|
return volume._volume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calc_cost_per_volume(drink: Drink) {
|
||||||
|
let retVal = drink._cost_per_volume;
|
||||||
|
if (!!drink.volume && !!drink.package_size && !!drink.cost_per_package) {
|
||||||
|
retVal =
|
||||||
|
((drink.cost_per_package || 0) / ((drink.volume || 0) * (drink.package_size || 0))) * 1.19;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal ? Math.round(retVal * 1000) / 1000 : retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calc_all_min_prices(drinks: Array<Drink>, min_prices: Array<number>) {
|
||||||
|
drinks.forEach((drink) => {
|
||||||
|
drink.volumes.forEach((volume) => {
|
||||||
|
volume.min_prices = calc_min_prices(volume, drink.cost_per_volume, min_prices);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function helper(volume: DrinkPriceVolume, min_price: number) {
|
||||||
|
let retVal = 0;
|
||||||
|
let extraIngredientPrice = 0;
|
||||||
|
volume.ingredients.forEach((ingredient) => {
|
||||||
|
if (ingredient.drink_ingredient) {
|
||||||
|
const _drink = usePricelistStore().drinks.find(
|
||||||
|
(a) => a.id === ingredient.drink_ingredient?.ingredient_id
|
||||||
|
);
|
||||||
|
retVal += ingredient.drink_ingredient.volume * <number>(<unknown>_drink?.cost_per_volume);
|
||||||
|
}
|
||||||
|
if (ingredient.extra_ingredient) {
|
||||||
|
extraIngredientPrice += ingredient.extra_ingredient.price;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (retVal * min_price) / 100 + extraIngredientPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calc_min_prices(
|
||||||
|
volume: DrinkPriceVolume,
|
||||||
|
cost_per_volume: number | undefined,
|
||||||
|
min_prices: Array<number>
|
||||||
|
) {
|
||||||
|
const retVal: Array<FG.MinPrices> = [];
|
||||||
|
volume.min_prices = [];
|
||||||
|
min_prices.forEach((min_price) => {
|
||||||
|
let computedMinPrice: number;
|
||||||
|
if (cost_per_volume) {
|
||||||
|
computedMinPrice = (cost_per_volume * <number>volume.volume * min_price) / 100;
|
||||||
|
} else {
|
||||||
|
computedMinPrice = helper(volume, min_price);
|
||||||
|
}
|
||||||
|
retVal.push({ percentage: min_price, price: computedMinPrice });
|
||||||
|
});
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { calc_volume, calc_cost_per_volume, calc_all_min_prices, calc_min_prices };
|
Loading…
Reference in New Issue