flaschengeist-frontend/src/plugins/pricelist/components/CalculationTable.vue

414 lines
13 KiB
Vue
Raw Normal View History

2021-03-14 19:37:41 +00:00
<template>
<div>
<q-table
title="Kalkulationstabelle"
:columns="columns"
:data="drinks"
2021-03-14 19:37:41 +00:00
:visible-columns="visibleColumn"
:dense="$q.screen.lt.md"
>
<template v-slot:top-right>
<q-select
v-model="visibleColumn"
multiple
filled
dense
options-dense
display-value="Sichtbarkeit"
emit-value
map-options
:options="[...columns, ...column_calc, ...column_prices]"
option-value="name"
options-cover
/>
</template>
<template v-slot:body-cell-volumes="volumes">
2021-03-14 19:37:41 +00:00
<q-table
:columns="column_calc"
:data="volumes.value"
2021-03-14 19:37:41 +00:00
dense
:visible-columns="visibleColumn"
row-key="id"
flat
>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width />
<q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label }}
2021-03-14 19:37:41 +00:00
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props">
<q-td auto-width>
<q-btn
size="sm"
color="accent"
round
dense
@click="props.expand = !props.expand"
:icon="props.expand ? 'mdi-chevron-up' : 'mdi-chevron-down'"
/>
</q-td>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
<div v-if="col.name == 'min_prices'">
<div
v-for="(min_price, index) in col.value"
:key="col.name + index"
class="row justify-between"
>
<div class="col">
<q-badge color="primary">{{ min_price.percentage }}%</q-badge>
</div>
<div class="col" style="text-align: end">
2021-03-14 19:37:41 +00:00
{{ parseFloat(min_price.price).toFixed(3) }}
</div>
</div>
</div>
<div v-else-if="col.name == 'prices'">
<q-table
dense
hide-header
:columns="column_prices"
:data="col.value"
:visible-columns="visibleColumn"
flat
>
<template v-slot:body="prices_props">
<q-tr :props="prices_props">
<q-td
v-for="col in prices_props.cols"
:key="col.name"
:props="prices_props"
>
<div v-if="col.name == 'public'" class="full-width">
<q-toggle
v-model="col.value"
dense
@input="updatePrice(prices_props.row, props.row)"
/>
</div>
<div v-else class="full-width">
{{ col.value }}
</div>
2021-03-14 19:37:41 +00:00
</q-td>
<q-td>
<q-btn
color="negative"
padding="xs"
2021-03-14 19:37:41 +00:00
round
size="xs"
icon="mdi-delete"
@click="deletePrice(prices_props.row, props.row)"
2021-03-14 19:37:41 +00:00
/>
</q-td>
</q-tr>
</template>
<template v-slot:bottom>
<div class="full-width row justify-end">
<q-btn size="xs" icon-right="add" color="positive" label="Preis hinzufügen">
<q-menu anchor="center middle" self="center middle">
<div class="row justify-around q-pa-sm">
<q-input
v-model.number="newPrice.price"
dense
filled
class="q-px-sm"
type="number"
label="Preis"
/>
<q-input
v-model="newPrice.description"
dense
filled
class="q-px-sm"
label="Beschreibung"
/>
<q-toggle
v-model="newPrice.public"
dense
class="q-px-sm"
label="Öffentlich"
/>
</div>
<div class="row justify-between q-pa-sm">
<q-btn label="Abbrechen" @click="cancelAddPrice" v-close-popup />
<q-btn
label="Speichern"
color="primary"
@click="addPrice(props.row)"
v-close-popup
/>
</div>
</q-menu>
</q-btn>
2021-03-14 19:37:41 +00:00
</div>
</template>
<template v-slot:no-data class="justify-end">
<div class="full-width row justify-end">
<q-btn
size="xs"
icon-right="add"
color="positive"
label="Preis hinzufügen"
@click="addPrice(col.value)"
/>
</div>
</template>
</q-table>
</div>
<div v-else>
{{ col.value }}
</div>
</q-td>
</q-tr>
<q-tr v-show="props.expand" :props="props">
<q-td colspan="100%">
<div
v-for="ingredient in props.row.ingredients"
:key="`volume:${props.row.id},ingredient:${ingredient.id}`"
2021-03-14 19:37:41 +00:00
class="full-width row justify-evenly q-py-xs"
>
<div
class="full-width row justify-evenly q-py-xs"
v-if="ingredient.drink_ingredient"
>
<q-select
class="col q-px-sm"
label="Getränk"
filled
dense
:options="drinks"
option-label="name"
v-model="ingredient.drink_ingredient"
@input="calc_min_prices(props.row)"
/>
<q-input
class="col q-px-sm"
label="Volume in L"
type="number"
filled
dense
v-model.number="ingredient.volume"
@change="calc_min_prices(props.row)"
step="0.01"
min="0"
/>
</div>
<div v-else-if="ingredient.name">
{{ ingredient.name }} {{ ingredient.price }}
</div>
2021-03-14 19:37:41 +00:00
</div>
<div class="full-width row justify-end q-py-xs">
<q-btn
size="sm"
icon-right="add"
color="positive"
label="Zutat hinzufügen"
@click="addIngredient(props.row.ingredients, props.row.id)"
2021-03-14 19:37:41 +00:00
@change="calc_min_prices(props.row)"
/>
</div>
</q-td>
</q-tr>
</template>
<template v-slot:bottom>
<div class="full-width row justify-end">
<q-btn
color="positive"
icon-right="add"
label="Abgabe hinzufügen"
size="xs"
@click="addVolume(volumes.value)"
2021-03-14 19:37:41 +00:00
/>
</div>
</template>
</q-table>
</template>
</q-table>
</div>
</template>
<script lang="ts">
import { defineComponent, onBeforeMount, ref, computed } from '@vue/composition-api';
import store, { calc_min_prices } from '../store/altStore';
2021-03-14 19:37:41 +00:00
import { v4 } from 'uuid';
export default defineComponent({
name: 'CalculationTable',
setup(_, { root }) {
onBeforeMount(() => {
store.actions.getDrinks();
2021-03-14 19:37:41 +00:00
});
const columns = [
{
name: 'name',
label: 'Getränkename',
field: 'name',
2021-03-14 19:37:41 +00:00
},
{
name: 'article_id',
label: 'Artikelnummer',
field: 'article_id',
2021-03-14 19:37:41 +00:00
},
{
name: 'drink_type',
2021-03-14 19:37:41 +00:00
label: 'Kategorie',
field: 'type',
format: (val: FG.DrinkType) => `${val.name}`,
2021-03-14 19:37:41 +00:00
},
{
name: 'volume_package',
label: 'Inhalt in l des Gebinde',
field: 'volume',
2021-03-14 19:37:41 +00:00
},
{
name: 'package_size',
label: 'Gebindegröße',
field: 'package_size',
2021-03-14 19:37:41 +00:00
},
{
name: 'cost_price_package_netto',
label: 'Preis Netto/Gebinde',
field: 'cost_price_package_netto',
format: (val: number | null) => (val ? `${val.toFixed(3)}` : ''),
2021-03-14 19:37:41 +00:00
},
{
name: 'cost_price_pro_volume',
label: 'Preis mit 19%/Liter',
field: 'cost_price_pro_volume',
format: (val: number | null) => (val ? `${val.toFixed(3)}` : ''),
2021-03-14 19:37:41 +00:00
},
{
name: 'volumes',
2021-03-14 19:37:41 +00:00
label: 'Preiskalkulation',
field: 'volumes',
},
2021-03-14 19:37:41 +00:00
];
const column_calc = [
{
name: 'volume',
label: 'Abgabe in l',
field: 'volume',
format: (val: number) => `${val} L`,
2021-03-14 19:37:41 +00:00
},
{
name: 'min_prices',
label: 'Minimal Preise',
field: 'min_prices',
2021-03-14 19:37:41 +00:00
},
{
name: 'prices',
label: 'Preise',
field: 'prices',
},
2021-03-14 19:37:41 +00:00
];
const column_prices = [
{
name: 'price',
label: 'Preis',
field: 'price',
format: (val: number) => `${val.toFixed(2)}`,
2021-03-14 19:37:41 +00:00
},
{
name: 'description',
label: 'Beschreibung',
field: 'description',
2021-03-14 19:37:41 +00:00
},
{
name: 'public',
label: 'Öffentlich',
field: 'public',
},
];
2021-03-14 19:37:41 +00:00
const visibleColumn = ref([
'name',
'drink_kind',
'cost_price_pro_volumne',
'volumes',
2021-03-14 19:37:41 +00:00
'volume',
'min_prices',
'prices',
'price',
'description',
'public',
2021-03-14 19:37:41 +00:00
]);
function deletePrice(row: FG.DrinkPrice) {
2021-03-14 19:37:41 +00:00
console.log(row);
}
const emptyPrice = {
price: 0,
description: '',
public: true,
};
const newPrice = ref(emptyPrice);
function addPrice(volume: FG.DrinkPriceVolume) {
store.actions.setPrice({ ...newPrice.value }, volume);
cancelAddPrice();
}
function cancelAddPrice() {
setTimeout(() => {
addPrice.value = emptyPrice;
}, 200);
}
function updatePrice(price: FG.DrinkPrice, volume: FG.DrinkPriceVolume) {
store.actions.updatePrice(price, volume);
}
function deletePrice(price: FG.DrinkPrice, volume: FG.DrinkPriceVolume) {
console.log(price, volume);
store.actions.deletePrice(price, volume);
2021-03-14 19:37:41 +00:00
}
function addVolume(table: FG.DrinkPriceVolume[]) {
2021-03-14 19:37:41 +00:00
table.push({
id: v4(),
volume: null,
min_prices: [
{
percentage: 100,
price: 0,
2021-03-14 19:37:41 +00:00
},
{
percentage: 250,
price: 0,
2021-03-14 19:37:41 +00:00
},
{
percentage: 300,
price: 0,
},
2021-03-14 19:37:41 +00:00
],
prices: [],
ingredients: [],
2021-03-14 19:37:41 +00:00
});
}
function addIngredient(ingredients: FG.Ingredient[]) {
ingredients.push({ id: -1, volume_id: 0, drink_ingredient: null, extra_ingredient: null });
2021-03-14 19:37:41 +00:00
}
return {
drinks: computed({ get: () => store.state.drinks, set: (val) => console.log(val) }),
2021-03-14 19:37:41 +00:00
columns,
column_calc,
column_prices,
visibleColumn,
deletePrice,
newPrice,
2021-03-14 19:37:41 +00:00
addPrice,
updatePrice,
deletePrice,
cancelAddPrice,
2021-03-14 19:37:41 +00:00
addVolume,
addIngredient,
calc_min_prices,
console,
2021-03-14 19:37:41 +00:00
};
},
2021-03-14 19:37:41 +00:00
});
</script>
<style scoped></style>