[pricelist] modify, delete and add for ExtraIngredients
This commit is contained in:
parent
57f21936c0
commit
20191be5dc
|
@ -607,12 +607,6 @@ export default defineComponent({
|
|||
name: 'CalculationTable',
|
||||
components: { PriceTable, Ingredients },
|
||||
setup() {
|
||||
onBeforeMount(() => {
|
||||
store.actions.getDrinks();
|
||||
store.actions.getExtraIngredients();
|
||||
store.actions.getDrinkTypes();
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'name',
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class="text-h4">Neues Getränk</div>
|
||||
</q-card-section>
|
||||
<q-form @submit="save">
|
||||
<q-card-section>
|
||||
<div class="text-h5">Getränkinformationen</div>
|
||||
<div class="row">
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="drink.name"
|
||||
filled
|
||||
label="Name"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="drink.volume"
|
||||
filled
|
||||
label="Inhalt in Liter"
|
||||
type="number"
|
||||
step="0.01"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="drink.cost_price"
|
||||
filled
|
||||
label="Einkaufspreis"
|
||||
type="number"
|
||||
step="0.01"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="drink.discount"
|
||||
filled
|
||||
label="Aufschlag in Prozent"
|
||||
type="number"
|
||||
hint="Wenn nicht gesetzt wird default-wert genommen."
|
||||
step="0.01"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="drink.extra_charge"
|
||||
filled
|
||||
label="Extra Aufschlag in Euro"
|
||||
type="number"
|
||||
step="0.1"
|
||||
/>
|
||||
|
||||
<q-input class="col-12 col-sm-6 q-px-sm q-py-md" filled label="Tags" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row justify-between">
|
||||
<div class="text-h5">
|
||||
Preise
|
||||
</div>
|
||||
<q-btn round icon="mdi-plus" @click="addPrice" color="primary" />
|
||||
</div>
|
||||
<q-card class="q-ma-sm" v-for="(price, index) in drink.prices" :key="index">
|
||||
<div class="row">
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="price.volume"
|
||||
label="Inhalt in Liter"
|
||||
filled
|
||||
type="number"
|
||||
step="0.01"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="price.price"
|
||||
label="Preis in €"
|
||||
filled
|
||||
:disable="price.no_auto"
|
||||
type="number"
|
||||
step="0.1"
|
||||
/>
|
||||
<q-toggle
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="price.no_auto"
|
||||
label="Automatische Preiskalkulation"
|
||||
color="primary"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="price.round_step"
|
||||
label="Rundungsschritt"
|
||||
type="number"
|
||||
filled
|
||||
step="0.1"
|
||||
/>
|
||||
<q-toggle
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="price.public"
|
||||
label="Öffentlich"
|
||||
color="primary"
|
||||
/>
|
||||
<q-input
|
||||
class="col-12 col-sm-6 q-px-sm q-py-md"
|
||||
v-model="price.description"
|
||||
label="Beschreibung"
|
||||
filled
|
||||
/>
|
||||
</div>
|
||||
</q-card>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row justify-between">
|
||||
<div class="text-h5">
|
||||
Zutaten
|
||||
</div>
|
||||
<q-btn round icon="mdi-plus" color="primary" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn type="submit" label="Speichern" color="primary" />
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed } from '@vue/composition-api';
|
||||
import { StateInterface } from 'src/store';
|
||||
import { Store } from 'vuex';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Drink',
|
||||
setup(_, { root }) {
|
||||
const store = <Store<StateInterface>>root.$store;
|
||||
interface EmptyDrink {
|
||||
name: string;
|
||||
volume: number | null;
|
||||
cost_price: number | null;
|
||||
discount: number | null;
|
||||
extra_charge: number | null;
|
||||
prices: EmptyPrice[];
|
||||
ingredients: [];
|
||||
}
|
||||
const emptyDrink: EmptyDrink = {
|
||||
name: '',
|
||||
volume: null,
|
||||
cost_price: null,
|
||||
discount: null,
|
||||
extra_charge: null,
|
||||
prices: [],
|
||||
ingredients: []
|
||||
};
|
||||
const drink = ref<EmptyDrink>(emptyDrink);
|
||||
interface EmptyPrice {
|
||||
volume: string;
|
||||
price: number | null;
|
||||
description: string;
|
||||
no_auto: boolean;
|
||||
round_step: number | null;
|
||||
public: boolean;
|
||||
}
|
||||
const emptyPrice: EmptyPrice = {
|
||||
volume: '',
|
||||
price: null,
|
||||
description: '',
|
||||
no_auto: false,
|
||||
round_step: null,
|
||||
public: true
|
||||
};
|
||||
|
||||
function addPrice() {
|
||||
const test = { ...emptyPrice };
|
||||
drink.value.prices.unshift(test);
|
||||
}
|
||||
function save() {
|
||||
console.log(drink);
|
||||
|
||||
drink.value.prices.forEach((price: EmptyPrice) => {
|
||||
price.no_auto = !price.no_auto;
|
||||
});
|
||||
void store.dispatch('drink/createDrink', drink.value);
|
||||
}
|
||||
return { drink, addPrice, save };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<div>
|
||||
<q-dialog v-model="edittype">
|
||||
<q-card>
|
||||
<q-card-section>
|
||||
<div class="text-h6">Editere Extrazutaten {{ actualExtraIngredient.name }}</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input dense label="Name" filled v-model="actualExtraIngredient.name" />
|
||||
<q-input
|
||||
dense
|
||||
label="Preis"
|
||||
filled
|
||||
v-model.number="actualExtraIngredient.price"
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.1"
|
||||
suffix="€"
|
||||
/>
|
||||
</q-card-section>
|
||||
<q-card-actions>
|
||||
<q-btn flat color="danger" label="Abbrechen" @click="discardChanges()" />
|
||||
<q-btn flat color="primary" label="Speichern" @click="saveChanges()" />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-page padding>
|
||||
<q-table title="Getränkearten" :data="rows" :row-key="row => row.id" :columns="columns">
|
||||
<template v-slot:top-right>
|
||||
<q-input
|
||||
class="q-px-sm"
|
||||
dense
|
||||
v-model="newExtraIngredient.name"
|
||||
placeholder="Neue Zutatenbezeichnung"
|
||||
label="Neue Zutatenbezeichnung"
|
||||
filled
|
||||
/>
|
||||
<q-input
|
||||
class="q-px-sm"
|
||||
dense
|
||||
v-model.number="newExtraIngredient.price"
|
||||
placeholder="Preis"
|
||||
label="Preis"
|
||||
filled
|
||||
type="number"
|
||||
min="0"
|
||||
step="0.1"
|
||||
suffix="€"
|
||||
/>
|
||||
<q-btn color="primary" icon="mdi-plus" label="Hinzufügen" @click="addExtraIngredient" />
|
||||
</template>
|
||||
<template v-slot:body-cell-actions="props">
|
||||
<q-td :props="props" align="right" :auto-width="true">
|
||||
<q-btn round flat icon="mdi-pencil" @click="editType(props.row)" />
|
||||
<q-btn round flat icon="mdi-delete" @click="deleteType(props.row)" />
|
||||
</q-td>
|
||||
</template>
|
||||
</q-table>
|
||||
</q-page>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, onBeforeMount, ref } from '@vue/composition-api';
|
||||
import store from '../store/altStore';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'DrinkTypes',
|
||||
setup(_, { root }) {
|
||||
const emptyExtraIngredient: FG.ExtraIngredient = {
|
||||
name: '',
|
||||
price: 0,
|
||||
id: -1
|
||||
};
|
||||
const newExtraIngredient = ref(emptyExtraIngredient);
|
||||
const newDrinkTypeName = ref('');
|
||||
const edittype = ref(false);
|
||||
const actualExtraIngredient = ref(emptyExtraIngredient);
|
||||
|
||||
const rows = computed(() => store.state.extraIngredients);
|
||||
const columns = [
|
||||
{
|
||||
name: 'name',
|
||||
label: 'Bezeichnung',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
name: 'price',
|
||||
label: 'Preis',
|
||||
field: 'price',
|
||||
sortable: true,
|
||||
format: (val: number) => `${val.toFixed(2)}€`
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Aktionen',
|
||||
field: 'actions',
|
||||
align: 'right'
|
||||
}
|
||||
];
|
||||
|
||||
function addExtraIngredient() {
|
||||
store.actions.setExtraIngredient(newExtraIngredient.value);
|
||||
newExtraIngredient.value = emptyExtraIngredient;
|
||||
}
|
||||
|
||||
function editType(extraIngredient: FG.ExtraIngredient) {
|
||||
edittype.value = true;
|
||||
actualExtraIngredient.value = extraIngredient;
|
||||
}
|
||||
|
||||
function saveChanges() {
|
||||
store.actions.updateExtraIngredient(actualExtraIngredient.value);
|
||||
setTimeout(() => discardChanges(), 200);
|
||||
}
|
||||
|
||||
function discardChanges() {
|
||||
actualExtraIngredient.value = emptyExtraIngredient;
|
||||
newExtraIngredient.value = emptyExtraIngredient;
|
||||
edittype.value = false;
|
||||
}
|
||||
|
||||
function deleteType(extraIngredient: FG.ExtraIngredient) {
|
||||
store.actions.deleteExtraIngredient(extraIngredient);
|
||||
}
|
||||
|
||||
return {
|
||||
columns,
|
||||
rows,
|
||||
addExtraIngredient,
|
||||
newExtraIngredient,
|
||||
deleteType,
|
||||
edittype,
|
||||
editType,
|
||||
actualExtraIngredient,
|
||||
discardChanges,
|
||||
saveChanges
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -21,9 +21,10 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from '@vue/composition-api';
|
||||
import { computed, defineComponent, onBeforeMount } from '@vue/composition-api';
|
||||
import EssentialLink from 'src/components/navigation/EssentialLink.vue';
|
||||
import mainRoutes from '../routes';
|
||||
import store from '../store/altStore';
|
||||
export default defineComponent({
|
||||
// name: 'PageName'
|
||||
components: { EssentialLink },
|
||||
|
@ -31,6 +32,12 @@ export default defineComponent({
|
|||
const checkMain = computed(() => {
|
||||
return root.$route.matched.length == 2;
|
||||
});
|
||||
onBeforeMount(() => {
|
||||
store.actions.getDrinks();
|
||||
store.actions.getExtraIngredients();
|
||||
store.actions.getDrinkTypes();
|
||||
});
|
||||
|
||||
return { checkMain, mainRoutes };
|
||||
}
|
||||
});
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
<q-tab-panel name="pricelist">
|
||||
<CalculationTable />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="new_drink">
|
||||
<Drink />
|
||||
<q-tab-panel name="extra_ingredients">
|
||||
<extra-ingredients />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="drink_types">
|
||||
<DrinkTypes />
|
||||
|
@ -49,11 +49,11 @@
|
|||
import { computed, defineComponent, ref } from '@vue/composition-api';
|
||||
import { Screen } from 'quasar';
|
||||
import DrinkTypes from 'src/plugins/pricelist/components/DrinkTypes.vue';
|
||||
import Drink from 'src/plugins/pricelist/components/Drink.vue';
|
||||
import CalculationTable from 'src/plugins/pricelist/components/CalculationTable.vue';
|
||||
import ExtraIngredients from 'src/plugins/pricelist/components/ExtraIngredients.vue';
|
||||
export default defineComponent({
|
||||
name: 'Settings',
|
||||
components: { DrinkTypes, Drink, CalculationTable },
|
||||
components: { DrinkTypes, ExtraIngredients, CalculationTable },
|
||||
setup(_) {
|
||||
interface Tab {
|
||||
name: string;
|
||||
|
@ -73,7 +73,7 @@ export default defineComponent({
|
|||
|
||||
const tabs: Tab[] = [
|
||||
{ name: 'pricelist', label: 'Getränke' },
|
||||
{ name: 'new_drink', label: 'Neues Getränk' },
|
||||
{ name: 'extra_ingredients', label: 'Zutaten' },
|
||||
{ name: 'drink_types', label: 'Getränketypen' }
|
||||
];
|
||||
|
||||
|
|
|
@ -268,6 +268,38 @@ const actions = {
|
|||
}
|
||||
})
|
||||
.catch(err => console.warn(err));
|
||||
},
|
||||
setExtraIngredient(ingredient: FG.ExtraIngredient) {
|
||||
axios
|
||||
.post(`pricelist/ingredients/extraIngredients`, ingredient)
|
||||
.then((response: AxiosResponse<FG.ExtraIngredient>) => {
|
||||
state.extraIngredients.push(response.data);
|
||||
})
|
||||
.catch(err => console.warn(err));
|
||||
},
|
||||
updateExtraIngredient(ingredient: FG.ExtraIngredient) {
|
||||
axios
|
||||
.put(`pricelist/ingredients/extraIngredients/${ingredient.id}`, ingredient)
|
||||
.then((response: AxiosResponse<FG.ExtraIngredient>) => {
|
||||
const index = state.extraIngredients.findIndex(a => a.id === ingredient.id);
|
||||
if (index > -1) {
|
||||
state.extraIngredients[index] = response.data;
|
||||
} else {
|
||||
state.extraIngredients.push(response.data);
|
||||
}
|
||||
})
|
||||
.catch(err => console.warn(err));
|
||||
},
|
||||
deleteExtraIngredient(ingredient: FG.ExtraIngredient) {
|
||||
axios
|
||||
.delete(`pricelist/ingredients/extraIngredients/${ingredient.id}`)
|
||||
.then(() => {
|
||||
const index = state.extraIngredients.findIndex(a => a.id === ingredient.id);
|
||||
if (index > -1) {
|
||||
state.extraIngredients.splice(index, 1);
|
||||
}
|
||||
})
|
||||
.catch(err => console.warn(err));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -298,9 +330,10 @@ function create_min_prices(drink: Drink, volume: DrinkPriceVolume, percentage: n
|
|||
let retVal = 0;
|
||||
volume.ingredients.forEach(ingredient => {
|
||||
if (ingredient.drink_ingredient) {
|
||||
retVal +=
|
||||
ingredient.drink_ingredient.volume *
|
||||
(ingredient.drink_ingredient.drink_ingredient?.cost_price_pro_volume || 0);
|
||||
const _drink = state.drinks.find(
|
||||
a => a.id === ingredient.drink_ingredient?.drink_ingredient?.id
|
||||
);
|
||||
retVal += ingredient.drink_ingredient.volume * (_drink?.cost_price_pro_volume.value || 0);
|
||||
}
|
||||
if (ingredient.extra_ingredient) {
|
||||
retVal += ingredient.extra_ingredient.price;
|
||||
|
|
Loading…
Reference in New Issue