release v2.0.0 #4
|
@ -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>;
|
||||
|
|
|
@ -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>
|
|
@ -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('');
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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>
|
|
@ -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';
|
||||
|
|
|
@ -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'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue