[pricelist] modify, delete and add for ExtraIngredients

This commit is contained in:
Tim Gröger 2021-03-17 22:49:23 +01:00
parent 57f21936c0
commit 20191be5dc
6 changed files with 195 additions and 202 deletions

View File

@ -607,12 +607,6 @@ export default defineComponent({
name: 'CalculationTable', name: 'CalculationTable',
components: { PriceTable, Ingredients }, components: { PriceTable, Ingredients },
setup() { setup() {
onBeforeMount(() => {
store.actions.getDrinks();
store.actions.getExtraIngredients();
store.actions.getDrinkTypes();
});
const columns = [ const columns = [
{ {
name: 'name', name: 'name',

View File

@ -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>

View File

@ -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>

View File

@ -21,9 +21,10 @@
</template> </template>
<script lang="ts"> <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 EssentialLink from 'src/components/navigation/EssentialLink.vue';
import mainRoutes from '../routes'; import mainRoutes from '../routes';
import store from '../store/altStore';
export default defineComponent({ export default defineComponent({
// name: 'PageName' // name: 'PageName'
components: { EssentialLink }, components: { EssentialLink },
@ -31,6 +32,12 @@ export default defineComponent({
const checkMain = computed(() => { const checkMain = computed(() => {
return root.$route.matched.length == 2; return root.$route.matched.length == 2;
}); });
onBeforeMount(() => {
store.actions.getDrinks();
store.actions.getExtraIngredients();
store.actions.getDrinkTypes();
});
return { checkMain, mainRoutes }; return { checkMain, mainRoutes };
} }
}); });

View File

@ -34,8 +34,8 @@
<q-tab-panel name="pricelist"> <q-tab-panel name="pricelist">
<CalculationTable /> <CalculationTable />
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="new_drink"> <q-tab-panel name="extra_ingredients">
<Drink /> <extra-ingredients />
</q-tab-panel> </q-tab-panel>
<q-tab-panel name="drink_types"> <q-tab-panel name="drink_types">
<DrinkTypes /> <DrinkTypes />
@ -49,11 +49,11 @@
import { computed, defineComponent, ref } from '@vue/composition-api'; import { computed, defineComponent, ref } from '@vue/composition-api';
import { Screen } from 'quasar'; import { Screen } from 'quasar';
import DrinkTypes from 'src/plugins/pricelist/components/DrinkTypes.vue'; 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 CalculationTable from 'src/plugins/pricelist/components/CalculationTable.vue';
import ExtraIngredients from 'src/plugins/pricelist/components/ExtraIngredients.vue';
export default defineComponent({ export default defineComponent({
name: 'Settings', name: 'Settings',
components: { DrinkTypes, Drink, CalculationTable }, components: { DrinkTypes, ExtraIngredients, CalculationTable },
setup(_) { setup(_) {
interface Tab { interface Tab {
name: string; name: string;
@ -73,7 +73,7 @@ export default defineComponent({
const tabs: Tab[] = [ const tabs: Tab[] = [
{ name: 'pricelist', label: 'Getränke' }, { name: 'pricelist', label: 'Getränke' },
{ name: 'new_drink', label: 'Neues Getränk' }, { name: 'extra_ingredients', label: 'Zutaten' },
{ name: 'drink_types', label: 'Getränketypen' } { name: 'drink_types', label: 'Getränketypen' }
]; ];

View File

@ -268,6 +268,38 @@ const actions = {
} }
}) })
.catch(err => console.warn(err)); .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; let retVal = 0;
volume.ingredients.forEach(ingredient => { volume.ingredients.forEach(ingredient => {
if (ingredient.drink_ingredient) { if (ingredient.drink_ingredient) {
retVal += const _drink = state.drinks.find(
ingredient.drink_ingredient.volume * a => a.id === ingredient.drink_ingredient?.drink_ingredient?.id
(ingredient.drink_ingredient.drink_ingredient?.cost_price_pro_volume || 0); );
retVal += ingredient.drink_ingredient.volume * (_drink?.cost_price_pro_volume.value || 0);
} }
if (ingredient.extra_ingredient) { if (ingredient.extra_ingredient) {
retVal += ingredient.extra_ingredient.price; retVal += ingredient.extra_ingredient.price;