[Vue3] Fixed pricelist

This commit is contained in:
Ferdinand Thiessen 2021-03-14 13:52:58 +01:00
parent 62aa627f0c
commit 5153f074b5
7 changed files with 224 additions and 117 deletions

View File

@ -13,10 +13,10 @@ declare namespace FG {
firstname: string;
lastname: string;
mail: string;
birthday?: Date;
birthday?: any;
roles: Array<string>;
permissions?: Array<string>;
avatar_url?: string;
permissions?: any;
avatar_url?: any;
}
type Permission = string;
interface Role {
@ -29,58 +29,41 @@ declare namespace FG {
time: Date;
amount: number;
reversal_id: number;
sender_id?: string;
receiver_id?: string;
author_id?: string;
original_id?: number;
sender_id?: any;
receiver_id?: any;
author_id?: any;
original_id?: any;
}
interface Drink {
id: number;
article_id?: string;
package_size?: number;
name: string;
volume?: number;
cost_price_pro_volume?: number;
cost_price_package_netto?: number;
tags?: Array<Tag>;
type?: DrinkType;
volumes: Array<DrinkPriceVolume>;
}
interface DrinkIngredient {
id: number;
volume: number;
drink_ingredient_id: number;
cost_price: number;
discount: number;
extra_charge?: any;
prices: Array<DrinkPrice>;
ingredients: Array<Ingredient>;
tags: Array<any>;
}
interface DrinkPrice {
id: number;
price: number;
public: boolean;
description?: string;
}
interface DrinkPriceVolume {
id: number;
volume: number;
min_prices: Array<MinPrices>;
prices: Array<DrinkPrice>;
ingredients: Array<Ingredient>;
price: number;
no_auto: boolean;
public: boolean;
description?: any;
round_step: number;
}
interface DrinkType {
id: number;
name: string;
}
interface ExtraIngredient {
id: number;
name: string;
price: number;
}
interface Ingredient {
id: number;
drink_ingredient?: DrinkIngredient;
extra_ingredient?: ExtraIngredient;
}
interface MinPrices {
percentage: number;
price: number;
volume: number;
drink_parent_id: number;
drink_ingredient_id: number;
drink_ingredient?: any;
}
interface Tag {
id: number;
@ -90,7 +73,7 @@ declare namespace FG {
id: number;
start: Date;
end: Date;
description?: string;
description?: any;
type: EventType;
jobs: Array<Job>;
}
@ -101,7 +84,7 @@ declare namespace FG {
interface Job {
id: number;
start: Date;
end?: Date;
end?: any;
comment: string;
type: JobType;
services: Array<Service>;

View File

@ -0,0 +1,162 @@
<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
v-model="drink.name"
class="col-12 col-sm-6 q-px-sm q-py-md"
filled
label="Name"
/>
<q-input
v-model="drink.volume"
class="col-12 col-sm-6 q-px-sm q-py-md"
filled
label="Inhalt in Liter"
type="number"
step="0.01"
/>
<q-input
v-model="drink.cost_price"
class="col-12 col-sm-6 q-px-sm q-py-md"
filled
label="Einkaufspreis"
type="number"
step="0.01"
/>
<q-input
v-model="drink.discount"
class="col-12 col-sm-6 q-px-sm q-py-md"
filled
label="Aufschlag in Prozent"
type="number"
hint="Wenn nicht gesetzt wird default-wert genommen."
step="0.01"
/>
<q-input
v-model="drink.extra_charge"
class="col-12 col-sm-6 q-px-sm q-py-md"
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" color="primary" @click="addPrice" />
</div>
<q-card v-for="(price, index) in drink.prices" :key="index" class="q-ma-sm">
<div class="row">
<q-input
v-model="price.volume"
class="col-12 col-sm-6 q-px-sm q-py-md"
label="Inhalt in Liter"
filled
type="number"
step="0.01"
/>
<q-input
v-model="price.price"
class="col-12 col-sm-6 q-px-sm q-py-md"
label="Preis in €"
filled
:disable="price.no_auto"
type="number"
step="0.1"
/>
<q-toggle
v-model="price.no_auto"
class="col-12 col-sm-6 q-px-sm q-py-md"
label="Automatische Preiskalkulation"
color="primary"
/>
<q-input
v-model="price.round_step"
class="col-12 col-sm-6 q-px-sm q-py-md"
label="Rundungsschritt"
type="number"
filled
step="0.1"
/>
<q-toggle
v-model="price.public"
class="col-12 col-sm-6 q-px-sm q-py-md"
label="Öffentlich"
color="primary"
/>
<q-input
v-model="price.description"
class="col-12 col-sm-6 q-px-sm q-py-md"
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 } from 'vue';
import { useStore } from 'vuex';
export default defineComponent({
name: 'Drink',
setup() {
const store = useStore();
const drink = ref({
name: '',
volume: '',
cost_price: '',
discount: '',
extra_charge: '',
prices: [],
ingredients: [],
});
const emptyPrice = {
volume: '',
price: '',
description: '',
no_auto: false,
round_step: '',
public: true,
};
function addPrice() {
drink.value.prices.unshift({ ...emptyPrice });
}
function save() {
console.log(drink);
drink.value.prices.forEach((price: FG.DrinkPrice) => {
price.no_auto = !price.no_auto;
});
void store.dispatch('drink/createDrink', drink.value);
}
return { drink, addPrice, save };
},
});
</script>
<style scoped></style>

View File

@ -6,7 +6,7 @@
<div class="text-h6">Editere Getränkeart {{ actualDrinkType.name }}</div>
</q-card-section>
<q-card-section>
<q-input dense label="name" filled v-model="newDrinkTypeName" />
<q-input v-model="newDrinkTypeName" dense label="name" filled />
</q-card-section>
<q-card-actions>
<q-btn flat color="danger" label="Abbrechen" @click="discardChanges()" />
@ -17,11 +17,11 @@
<q-page padding>
<q-table title="Getränkearten" :data="rows" :row-key="(row) => row.id" :columns="columns">
<template v-slot:top-right>
<template #top-right>
<q-input
v-model="newDrinkType"
class="q-px-sm"
dense
v-model="newDrinkType"
placeholder="Neue Getränkeart"
filled
/>
@ -29,7 +29,7 @@
<div></div>
<q-btn color="primary" icon="mdi-plus" label="Hinzufügen" @click="addType" />
</template>
<template v-slot:body-cell-actions="props">
<template #body-cell-actions="props">
<q-td :props="props" align="right" :auto-width="true">
<q-btn
round
@ -46,15 +46,14 @@
</template>
<script lang="ts">
import { computed, defineComponent, onBeforeMount, ref } from '@vue/composition-api';
import { Store } from 'vuex';
import { StateInterface } from 'src/store';
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
import { useStore } from 'vuex';
import { DrinkInterface } from 'src/plugins/pricelist/store/drinks';
export default defineComponent({
name: 'DrinkTypes',
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
setup() {
const store = useStore();
const state = <DrinkInterface>store.state.drink;
const newDrinkType = ref('');
const newDrinkTypeName = ref('');

View File

@ -1,14 +1,14 @@
<template>
<div>
<q-table title="Getränke" :columns="columns" :data="drinks" row-key="name">
<template v-slot:body-cell-prices="{ row: { prices } }">
<template #body-cell-prices="{ row: { prices } }">
<q-td>
<div v-for="price in prices" :key="price.id" class="row">
<div class="col">
{{ price.volume | setVolume }}
{{ setVolume(price.volume) }}
</div>
<div class="col">
{{ price.price | setCurrency }}
{{ setCurrency(price.price) }}
</div>
<div class="col">
{{ price.description }}
@ -20,10 +20,11 @@
</div>
</template>
<script lang="ts">
import { defineComponent, onBeforeMount, ref } from '@vue/composition-api';
import { defineComponent, onBeforeMount, ref } from 'vue';
import { StateInterface } from 'src/store';
import { DrinkInterface } from '../store/drinks';
import { Store } from 'vuex';
import { useStore } from 'vuex';
export default defineComponent({
name: 'Pricelist',
filters: {
@ -37,8 +38,8 @@ export default defineComponent({
return `${price.toFixed(2)}`;
},
},
setup(_, { root }) {
const store = <Store<StateInterface>>root.$store;
setup() {
const store = useStore();
const state = <DrinkInterface>store.state.drink;
const drinks = ref(state.drinks);
onBeforeMount(() => {

View File

@ -1,44 +0,0 @@
<template>
<div>
<q-page padding v-if="checkMain">
<q-card>
<q-card-section>
<q-list v-for="(mainRoute, index) in mainRoutes" :key="'mainRoute' + index">
<essential-link
v-for="(route, index2) in mainRoute.children"
:key="'route' + index2"
:title="route.title"
:icon="route.icon"
:link="route.name"
:permissions="route.meta.permissions"
/>
</q-list>
</q-card-section>
</q-card>
</q-page>
<router-view />
</div>
</template>
<script lang="ts">
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 },
setup(_, { root }) {
const checkMain = computed(() => {
return root.$route.matched.length == 2;
});
onBeforeMount(() => {
store.actions.getDrinks();
store.actions.getExtraIngredients();
store.actions.getDrinkTypes();
});
return { checkMain, mainRoutes };
},
});
</script>

View File

@ -1,6 +1,6 @@
<template>
<div>
<q-tabs v-model="tab" v-if="$q.screen.gt.sm">
<q-tabs v-if="$q.screen.gt.sm" v-model="tab">
<q-tab
v-for="(tabindex, index) in tabs"
:key="'tab' + index"
@ -8,10 +8,10 @@
:label="tabindex.label"
/>
</q-tabs>
<div class="fit row justify-end" v-else>
<div v-else class="fit row justify-end">
<q-btn flat round icon="mdi-menu" @click="showDrawer = !showDrawer"></q-btn>
</div>
<q-drawer side="right" v-model="showDrawer" @click="showDrawer = !showDrawer" behavior="mobile">
<q-drawer v-model="showDrawer" side="right" behavior="mobile" @click="showDrawer = !showDrawer">
<q-list v-model="tab">
<q-item
v-for="(tabindex, index) in tabs"
@ -46,7 +46,7 @@
</template>
<script lang="ts">
import { computed, defineComponent, ref } from '@vue/composition-api';
import { computed, defineComponent, ref } from 'vue';
import { Screen } from 'quasar';
import DrinkTypes from 'src/plugins/pricelist/components/DrinkTypes.vue';
import CalculationTable from 'src/plugins/pricelist/components/CalculationTable.vue';

View File

@ -3,29 +3,35 @@ const mainRoutes: FG_Plugin.PluginRouteConfig[] = [
{
title: 'Getränke',
icon: 'mdi-glass-mug-variant',
route: {
path: 'drinks',
name: 'drinks',
component: () => import('../pages/MainPage.vue'),
meta: { permissions: ['user'] },
redirect: { name: 'drinks-pricelist' },
},
permissions: ['user'],
children: [
{
title: 'Preisliste',
icon: 'mdi-cash-100',
shortcut: true,
permissions: ['user'],
route: {
path: 'pricelist',
name: 'drinks-pricelist',
shortcut: true,
meta: { permissions: ['user'] },
component: () => import('../pages/Pricelist.vue'),
},
},
{
title: 'Einstellungen',
icon: 'mdi-coffee-to-go',
shortcut: false,
permissions: ['pricelist_settings'],
route: {
path: 'settings',
name: 'drinks-settings',
shortcut: false,
meta: { permissions: ['users_edit_other'] },
component: () => import('../pages/Settings.vue'),
},
},
],
},
];