release v2.0.0 #4
|
@ -1,101 +1,121 @@
|
||||||
declare namespace FG {
|
declare namespace FG {
|
||||||
interface Session {
|
interface Session {
|
||||||
expires: Date;
|
expires: Date;
|
||||||
token: string;
|
token: string;
|
||||||
lifetime: number;
|
lifetime: number;
|
||||||
browser: string;
|
browser: string;
|
||||||
platform: string;
|
platform: string;
|
||||||
userid: string;
|
userid: string;
|
||||||
}
|
}
|
||||||
interface User {
|
interface User {
|
||||||
userid: string;
|
userid: string;
|
||||||
display_name: string;
|
display_name: string;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
lastname: string;
|
lastname: string;
|
||||||
mail: string;
|
mail: string;
|
||||||
birthday?: any;
|
birthday?: Date;
|
||||||
roles: Array<string>;
|
roles: Array<string>;
|
||||||
permissions?: any;
|
permissions?: string[];
|
||||||
avatar_url?: any;
|
avatar_url?: string;
|
||||||
}
|
}
|
||||||
type Permission = string;
|
type Permission = string;
|
||||||
interface Role {
|
interface Role {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
permissions: Array<Permission>;
|
permissions: Array<Permission>;
|
||||||
}
|
}
|
||||||
interface Transaction {
|
interface Transaction {
|
||||||
id: number;
|
id: number;
|
||||||
time: Date;
|
time: Date;
|
||||||
amount: number;
|
amount: number;
|
||||||
reversal_id: number;
|
reversal_id: number;
|
||||||
sender_id?: any;
|
sender_id?: number;
|
||||||
receiver_id?: any;
|
receiver_id?: number;
|
||||||
author_id?: any;
|
author_id?: number;
|
||||||
original_id?: any;
|
original_id?: number;
|
||||||
}
|
}
|
||||||
interface Drink {
|
interface Drink {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
article_id?: string;
|
||||||
volume: number;
|
package_size?: number;
|
||||||
cost_price: number;
|
name: string;
|
||||||
discount: number;
|
volume?: number;
|
||||||
extra_charge?: any;
|
cost_price_pro_volume?: number;
|
||||||
prices: Array<DrinkPrice>;
|
cost_price_package_netto?: number;
|
||||||
ingredients: Array<Ingredient>;
|
tags: Array<Tag>;
|
||||||
tags: Array<any>;
|
type: DrinkType;
|
||||||
}
|
volumes: DrinkPriceVolume[];
|
||||||
interface DrinkPrice {
|
}
|
||||||
id: number;
|
interface DrinkIngredient {
|
||||||
volume: number;
|
id: number;
|
||||||
price: number;
|
volume: number;
|
||||||
no_auto: boolean;
|
drink_ingredient_id: number;
|
||||||
public: boolean;
|
drink_ingredient?: Drink;
|
||||||
description?: any;
|
price: number;
|
||||||
round_step: number;
|
}
|
||||||
}
|
interface DrinkPrice {
|
||||||
interface DrinkType {
|
id: number;
|
||||||
id: number;
|
price: number;
|
||||||
name: string;
|
public: boolean;
|
||||||
}
|
description?: string;
|
||||||
interface Ingredient {
|
}
|
||||||
id: number;
|
interface DrinkMinPrice {
|
||||||
volume: number;
|
percentage: number;
|
||||||
drink_parent_id: number;
|
price: number;
|
||||||
drink_ingredient_id: number;
|
}
|
||||||
drink_ingredient?: any;
|
interface DrinkPriceVolume {
|
||||||
}
|
id: number;
|
||||||
interface Tag {
|
volume: number;
|
||||||
id: number;
|
min_prices: DrinkMinPrice[];
|
||||||
name: string;
|
prices: Array<DrinkPrice>;
|
||||||
}
|
ingredients: Array<DrinkIngredient & ExtraIngredient>;
|
||||||
interface Event {
|
}
|
||||||
id: number;
|
interface DrinkType {
|
||||||
start: Date;
|
id: number;
|
||||||
end: Date;
|
name: string;
|
||||||
description?: any;
|
}
|
||||||
type: EventType;
|
interface ExtraIngredient {
|
||||||
jobs: Array<Job>;
|
id: number;
|
||||||
}
|
name: string;
|
||||||
interface EventType {
|
price: number;
|
||||||
id: number;
|
}
|
||||||
name: string;
|
interface Ingredient {
|
||||||
}
|
id: number;
|
||||||
interface Job {
|
volume_id: number;
|
||||||
id: number;
|
drink_ingredient: DrinkIngredient | null;
|
||||||
start: Date;
|
extra_ingredient: ExtraIngredient | null;
|
||||||
end?: any;
|
}
|
||||||
comment: string;
|
interface Tag {
|
||||||
type: JobType;
|
id: number;
|
||||||
services: Array<Service>;
|
name: string;
|
||||||
required_services: number;
|
}
|
||||||
}
|
interface Event {
|
||||||
interface JobType {
|
id: number;
|
||||||
id: number;
|
start: Date;
|
||||||
name: string;
|
end: Date;
|
||||||
}
|
description?: string;
|
||||||
interface Service {
|
type: EventType;
|
||||||
userid: string;
|
jobs: Array<Job>;
|
||||||
value: number;
|
}
|
||||||
}
|
interface EventType {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
interface Job {
|
||||||
|
id: number;
|
||||||
|
start: Date;
|
||||||
|
end?: Date;
|
||||||
|
comment: string;
|
||||||
|
type: JobType;
|
||||||
|
services: Array<Service>;
|
||||||
|
required_services: number;
|
||||||
|
}
|
||||||
|
interface JobType {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
interface Service {
|
||||||
|
userid: string;
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<q-table
|
<q-table
|
||||||
title="Kalkulationstabelle"
|
title="Kalkulationstabelle"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="test"
|
:data="drinks"
|
||||||
:visible-columns="visibleColumn"
|
:visible-columns="visibleColumn"
|
||||||
:dense="$q.screen.lt.md"
|
:dense="$q.screen.lt.md"
|
||||||
>
|
>
|
||||||
|
@ -22,10 +22,10 @@
|
||||||
options-cover
|
options-cover
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:body-cell-price_calc="price_calc">
|
<template v-slot:body-cell-volumes="volumes">
|
||||||
<q-table
|
<q-table
|
||||||
:columns="column_calc"
|
:columns="column_calc"
|
||||||
:data="price_calc.value"
|
:data="volumes.value"
|
||||||
dense
|
dense
|
||||||
:visible-columns="visibleColumn"
|
:visible-columns="visibleColumn"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
|
@ -34,8 +34,8 @@
|
||||||
<template v-slot:header="props">
|
<template v-slot:header="props">
|
||||||
<q-tr :props="props">
|
<q-tr :props="props">
|
||||||
<q-th auto-width />
|
<q-th auto-width />
|
||||||
<q-th v-for="(col, index) in props.cols" :key="col + index" :props="props">
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
{{ col }}
|
{{ col.label }}
|
||||||
</q-th>
|
</q-th>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<q-badge color="primary">{{ min_price.percentage }}%</q-badge>
|
<q-badge color="primary">{{ min_price.percentage }}%</q-badge>
|
||||||
</div>
|
</div>
|
||||||
<div class="col" style="text-align: end;">
|
<div class="col" style="text-align: end">
|
||||||
{{ parseFloat(min_price.price).toFixed(3) }}€
|
{{ parseFloat(min_price.price).toFixed(3) }}€
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -83,30 +83,67 @@
|
||||||
:key="col.name"
|
:key="col.name"
|
||||||
:props="prices_props"
|
:props="prices_props"
|
||||||
>
|
>
|
||||||
{{ col.value }}
|
<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>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td>
|
<q-td>
|
||||||
<q-btn
|
<q-btn
|
||||||
color="negative"
|
color="negative"
|
||||||
|
padding="xs"
|
||||||
round
|
round
|
||||||
size="xs"
|
size="xs"
|
||||||
icon="mdi-delete"
|
icon="mdi-delete"
|
||||||
@click="deletePrice(prices_props.row)"
|
@click="deletePrice(prices_props.row, props.row)"
|
||||||
v-if="!prices_props.row.to_delete"
|
|
||||||
/>
|
/>
|
||||||
<q-btn color="positive" size="xs" label="Speichern" v-else />
|
|
||||||
</q-td>
|
</q-td>
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:bottom>
|
<template v-slot:bottom>
|
||||||
<div class="full-width row justify-end">
|
<div class="full-width row justify-end">
|
||||||
<q-btn
|
<q-btn size="xs" icon-right="add" color="positive" label="Preis hinzufügen">
|
||||||
size="xs"
|
<q-menu anchor="center middle" self="center middle">
|
||||||
icon-right="add"
|
<div class="row justify-around q-pa-sm">
|
||||||
color="positive"
|
<q-input
|
||||||
label="Preis hinzufügen"
|
v-model.number="newPrice.price"
|
||||||
@click="addPrice(col.value)"
|
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>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:no-data class="justify-end">
|
<template v-slot:no-data class="justify-end">
|
||||||
|
@ -130,31 +167,39 @@
|
||||||
<q-tr v-show="props.expand" :props="props">
|
<q-tr v-show="props.expand" :props="props">
|
||||||
<q-td colspan="100%">
|
<q-td colspan="100%">
|
||||||
<div
|
<div
|
||||||
v-for="(ingredient, index) in props.row.ingredients"
|
v-for="ingredient in props.row.ingredients"
|
||||||
:key="`${props.key}_${index}`"
|
:key="`volume:${props.row.id},ingredient:${ingredient.id}`"
|
||||||
class="full-width row justify-evenly q-py-xs"
|
class="full-width row justify-evenly q-py-xs"
|
||||||
>
|
>
|
||||||
<q-select
|
<div
|
||||||
class="col q-px-sm"
|
class="full-width row justify-evenly q-py-xs"
|
||||||
label="Getränk"
|
v-if="ingredient.drink_ingredient"
|
||||||
filled
|
>
|
||||||
dense
|
<q-select
|
||||||
:options="test"
|
class="col q-px-sm"
|
||||||
option-label="name"
|
label="Getränk"
|
||||||
v-model="ingredient.drink"
|
filled
|
||||||
@input="calc_min_prices(props.row)"
|
dense
|
||||||
/>
|
:options="drinks"
|
||||||
<q-input
|
option-label="name"
|
||||||
class="col q-px-sm"
|
v-model="ingredient.drink_ingredient"
|
||||||
label="Volume in L"
|
@input="calc_min_prices(props.row)"
|
||||||
type="number"
|
/>
|
||||||
filled
|
<q-input
|
||||||
dense
|
class="col q-px-sm"
|
||||||
v-model="ingredient.volume"
|
label="Volume in L"
|
||||||
@change="calc_min_prices(props.row)"
|
type="number"
|
||||||
step="0.01"
|
filled
|
||||||
min="0"
|
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>
|
||||||
</div>
|
</div>
|
||||||
<div class="full-width row justify-end q-py-xs">
|
<div class="full-width row justify-end q-py-xs">
|
||||||
<q-btn
|
<q-btn
|
||||||
|
@ -162,7 +207,7 @@
|
||||||
icon-right="add"
|
icon-right="add"
|
||||||
color="positive"
|
color="positive"
|
||||||
label="Zutat hinzufügen"
|
label="Zutat hinzufügen"
|
||||||
@click="addIngredient(props.row.ingredients)"
|
@click="addIngredient(props.row.ingredients, props.row.id)"
|
||||||
@change="calc_min_prices(props.row)"
|
@change="calc_min_prices(props.row)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -176,7 +221,7 @@
|
||||||
icon-right="add"
|
icon-right="add"
|
||||||
label="Abgabe hinzufügen"
|
label="Abgabe hinzufügen"
|
||||||
size="xs"
|
size="xs"
|
||||||
@click="addVolume(price_calc.value)"
|
@click="addVolume(volumes.value)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -187,280 +232,181 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onBeforeMount, ref } from '@vue/composition-api';
|
import { defineComponent, onBeforeMount, ref, computed } from '@vue/composition-api';
|
||||||
import { Store } from 'vuex';
|
import store, { calc_min_prices } from '../store/altStore';
|
||||||
import { StateInterface } from '../../../store';
|
|
||||||
import { DrinkInterface } from '../store/drinks';
|
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'CalculationTable',
|
name: 'CalculationTable',
|
||||||
setup(_, { root }) {
|
setup(_, { root }) {
|
||||||
const store = <Store<StateInterface>>root.$store;
|
|
||||||
const state = <DrinkInterface>store.state.drink;
|
|
||||||
const drinks = ref();
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
void store
|
store.actions.getDrinks();
|
||||||
.dispatch('drink/getDrinks')
|
|
||||||
.then(() => (drinks.value = drinks.value = state.drinks));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: 'Getränkename',
|
label: 'Getränkename',
|
||||||
field: 'name'
|
field: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'article_id',
|
name: 'article_id',
|
||||||
label: 'Artikelnummer',
|
label: 'Artikelnummer',
|
||||||
field: 'article_id'
|
field: 'article_id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'drink_kind',
|
name: 'drink_type',
|
||||||
label: 'Kategorie',
|
label: 'Kategorie',
|
||||||
field: 'drink_kind'
|
field: 'type',
|
||||||
|
format: (val: FG.DrinkType) => `${val.name}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'volume_package',
|
name: 'volume_package',
|
||||||
label: 'Inhalt in l des Gebinde',
|
label: 'Inhalt in l des Gebinde',
|
||||||
field: 'volume_package'
|
field: 'volume',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'package_size',
|
name: 'package_size',
|
||||||
label: 'Gebindegröße',
|
label: 'Gebindegröße',
|
||||||
field: 'package_size'
|
field: 'package_size',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'cost_price_package_netto',
|
name: 'cost_price_package_netto',
|
||||||
label: 'Preis Netto/Gebinde',
|
label: 'Preis Netto/Gebinde',
|
||||||
field: 'cost_price_package_netto',
|
field: 'cost_price_package_netto',
|
||||||
format: (val: number) => `${val.toFixed(3)}€`
|
format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'cost_price_pro_volume',
|
name: 'cost_price_pro_volume',
|
||||||
label: 'Preis mit 19%/Liter',
|
label: 'Preis mit 19%/Liter',
|
||||||
field: 'cost_price_pro_volume',
|
field: 'cost_price_pro_volume',
|
||||||
format: (val: number) => `${val.toFixed(3)}€`
|
format: (val: number | null) => (val ? `${val.toFixed(3)}€` : ''),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'price_calc',
|
name: 'volumes',
|
||||||
label: 'Preiskalkulation',
|
label: 'Preiskalkulation',
|
||||||
field: 'price_calc'
|
field: 'volumes',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
const column_calc = [
|
const column_calc = [
|
||||||
{
|
{
|
||||||
name: 'volume',
|
name: 'volume',
|
||||||
label: 'Abgabe in l',
|
label: 'Abgabe in l',
|
||||||
field: 'volume',
|
field: 'volume',
|
||||||
format: (val: number) => `${val} L`
|
format: (val: number) => `${val} L`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'min_prices',
|
name: 'min_prices',
|
||||||
label: 'Minimal Preise',
|
label: 'Minimal Preise',
|
||||||
field: 'min_prices'
|
field: 'min_prices',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'prices',
|
name: 'prices',
|
||||||
label: 'Preise',
|
label: 'Preise',
|
||||||
field: 'prices'
|
field: 'prices',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
const column_prices = [
|
const column_prices = [
|
||||||
{
|
{
|
||||||
name: 'price',
|
name: 'price',
|
||||||
label: 'Preis',
|
label: 'Preis',
|
||||||
field: 'price',
|
field: 'price',
|
||||||
format: (val: number) => `${val.toFixed(2)}€`
|
format: (val: number) => `${val.toFixed(2)}€`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'description',
|
name: 'description',
|
||||||
label: 'Beschreibung',
|
label: 'Beschreibung',
|
||||||
field: 'description'
|
field: 'description',
|
||||||
}
|
|
||||||
];
|
|
||||||
const test = ref([
|
|
||||||
{
|
|
||||||
name: 'Elbhang Rot',
|
|
||||||
article_id: 41807,
|
|
||||||
drink_kind: 'Bier',
|
|
||||||
volume_package: 50,
|
|
||||||
package_size: 1,
|
|
||||||
cost_price_package_netto: 97,
|
|
||||||
cost_price_pro_volume: 2.309,
|
|
||||||
price_calc: [
|
|
||||||
{
|
|
||||||
id: v4(),
|
|
||||||
volume: 0.5,
|
|
||||||
min_prices: [
|
|
||||||
{
|
|
||||||
percentage: 100,
|
|
||||||
price: 1.15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
percentage: 250,
|
|
||||||
price: 2.875
|
|
||||||
},
|
|
||||||
{
|
|
||||||
percentage: 300,
|
|
||||||
price: 3.45
|
|
||||||
}
|
|
||||||
],
|
|
||||||
prices: [
|
|
||||||
{ price: 2, description: '', to_delete: false },
|
|
||||||
{ price: 1.4, description: 'Club intern', to_delete: false },
|
|
||||||
{
|
|
||||||
price: 1.6,
|
|
||||||
description: 'Club extern',
|
|
||||||
to_delete: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Sinalco Cola',
|
name: 'public',
|
||||||
article_id: 443,
|
label: 'Öffentlich',
|
||||||
drink_kind: 'AFG',
|
field: 'public',
|
||||||
volume_package: 1,
|
},
|
||||||
package_size: 12,
|
];
|
||||||
cost_price_package_netto: 7.28,
|
|
||||||
cost_price_pro_volume: 0.722,
|
|
||||||
price_calc: [
|
|
||||||
{
|
|
||||||
id: v4(),
|
|
||||||
volume: 0.2,
|
|
||||||
min_prices: [
|
|
||||||
{
|
|
||||||
percentage: 100,
|
|
||||||
price: 0.14
|
|
||||||
},
|
|
||||||
{
|
|
||||||
percentage: 250,
|
|
||||||
price: 0.35
|
|
||||||
},
|
|
||||||
{
|
|
||||||
percentage: 300,
|
|
||||||
price: 0.42
|
|
||||||
}
|
|
||||||
],
|
|
||||||
prices: [
|
|
||||||
{
|
|
||||||
price: 1,
|
|
||||||
description: 'klein',
|
|
||||||
to_delete: false
|
|
||||||
},
|
|
||||||
{ price: 0.5, description: 'klein club intern', to_delete: false }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: v4(),
|
|
||||||
volume: 0.4,
|
|
||||||
min_prices: [
|
|
||||||
{
|
|
||||||
percentage: 100,
|
|
||||||
price: 0.289
|
|
||||||
},
|
|
||||||
{
|
|
||||||
percentage: 250,
|
|
||||||
price: 0.722
|
|
||||||
},
|
|
||||||
{
|
|
||||||
percentage: 300,
|
|
||||||
price: 0.866
|
|
||||||
}
|
|
||||||
],
|
|
||||||
prices: [
|
|
||||||
{
|
|
||||||
price: 1.8,
|
|
||||||
description: 'groß',
|
|
||||||
to_delet: false
|
|
||||||
},
|
|
||||||
{ price: 1, description: 'groß club intern', to_delete: false }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
const visibleColumn = ref([
|
const visibleColumn = ref([
|
||||||
'name',
|
'name',
|
||||||
'drink_kind',
|
'drink_kind',
|
||||||
'cost_price_pro_volumne',
|
'cost_price_pro_volumne',
|
||||||
'price_calc',
|
'volumes',
|
||||||
'volume',
|
'volume',
|
||||||
'min_prices',
|
'min_prices',
|
||||||
'prices',
|
'prices',
|
||||||
'price',
|
'price',
|
||||||
'description'
|
'description',
|
||||||
|
'public',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function deletePrice(row) {
|
function deletePrice(row: FG.DrinkPrice) {
|
||||||
console.log(row);
|
console.log(row);
|
||||||
row.to_delete = true;
|
|
||||||
}
|
}
|
||||||
function addPrice(table) {
|
const emptyPrice = {
|
||||||
console.log(table);
|
price: 0,
|
||||||
table.push({
|
description: '',
|
||||||
price: 20,
|
public: true,
|
||||||
description: 'test',
|
};
|
||||||
to_delete: false
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVolume(table) {
|
function addVolume(table: FG.DrinkPriceVolume[]) {
|
||||||
table.push({
|
table.push({
|
||||||
id: v4(),
|
id: v4(),
|
||||||
volume: null,
|
volume: null,
|
||||||
min_prices: [
|
min_prices: [
|
||||||
{
|
{
|
||||||
percentage: 100,
|
percentage: 100,
|
||||||
price: null
|
price: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
percentage: 250,
|
percentage: 250,
|
||||||
price: null
|
price: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
percentage: 300,
|
percentage: 300,
|
||||||
price: null
|
price: 0,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
prices: [],
|
prices: [],
|
||||||
ingredients: []
|
ingredients: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addIngredient(ingredients) {
|
function addIngredient(ingredients: FG.Ingredient[]) {
|
||||||
ingredients.push({ drink: null, volume: null });
|
ingredients.push({ id: -1, volume_id: 0, drink_ingredient: null, extra_ingredient: null });
|
||||||
}
|
|
||||||
function calc_min_prices(row) {
|
|
||||||
console.log(row.ingredients);
|
|
||||||
row.volume = 0;
|
|
||||||
let cost_price = 0;
|
|
||||||
row.ingredients.forEach(ingredient => {
|
|
||||||
row.volume = row.volume + Number.parseFloat(ingredient.volume);
|
|
||||||
cost_price = Number.parseFloat(ingredient.volume) * ingredient.drink.cost_price_pro_volume;
|
|
||||||
});
|
|
||||||
console.log(row.volume, cost_price);
|
|
||||||
row.min_prices.forEach(min_price => {
|
|
||||||
min_price.price = (cost_price * min_price.percentage) / 100;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
drinks,
|
drinks: computed({ get: () => store.state.drinks, set: (val) => console.log(val) }),
|
||||||
columns,
|
columns,
|
||||||
test,
|
|
||||||
column_calc,
|
column_calc,
|
||||||
column_prices,
|
column_prices,
|
||||||
visibleColumn,
|
visibleColumn,
|
||||||
deletePrice,
|
deletePrice,
|
||||||
|
newPrice,
|
||||||
addPrice,
|
addPrice,
|
||||||
|
updatePrice,
|
||||||
|
deletePrice,
|
||||||
|
cancelAddPrice,
|
||||||
addVolume,
|
addVolume,
|
||||||
addIngredient,
|
addIngredient,
|
||||||
calc_min_prices
|
calc_min_prices,
|
||||||
|
console,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
import { reactive } from '@vue/composition-api';
|
||||||
|
import { axios } from 'src/boot/axios';
|
||||||
|
import { AxiosResponse } from 'axios';
|
||||||
|
import ExtraIngredient = FG.ExtraIngredient;
|
||||||
|
|
||||||
|
const state = reactive<{ drinks: FG.Drink[]; tags: FG.Tag[]; drinkTypes: FG.DrinkType[] }>({
|
||||||
|
drinks: [],
|
||||||
|
tags: [],
|
||||||
|
drinkTypes: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
getDrinks() {
|
||||||
|
axios
|
||||||
|
.get('pricelist/drinks')
|
||||||
|
.then((response: AxiosResponse<FG.Drink[]>) => {
|
||||||
|
state.drinks = response.data;
|
||||||
|
console.log(state.drinks);
|
||||||
|
state.drinks.forEach((drink: FG.Drink) => {
|
||||||
|
drink.volumes.forEach((volume: FG.DrinkPriceVolume) => {
|
||||||
|
volume.min_prices = [
|
||||||
|
{ percentage: 100, price: (drink.cost_price_pro_volume || 0) * volume.volume * 1 },
|
||||||
|
{ percentage: 250, price: (drink.cost_price_pro_volume || 0) * volume.volume * 2.5 },
|
||||||
|
{ percentage: 300, price: (drink.cost_price_pro_volume || 0) * volume.volume * 3 },
|
||||||
|
];
|
||||||
|
if (volume.ingredients.length > 0) {
|
||||||
|
calc_min_prices(volume);
|
||||||
|
}
|
||||||
|
this.sortPrices(volume);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => console.warn(err));
|
||||||
|
},
|
||||||
|
setPrice(price: FG.DrinkPrice, volume: FG.DrinkPriceVolume) {
|
||||||
|
axios
|
||||||
|
.post(`pricelist/prices/volumes/${volume.id}`, price)
|
||||||
|
.then((response: AxiosResponse<FG.DrinkPrice>) => {
|
||||||
|
volume.prices.push(response.data);
|
||||||
|
this.sortPrices(volume);
|
||||||
|
})
|
||||||
|
.catch((err) => console.warn(err));
|
||||||
|
},
|
||||||
|
sortPrices(volume: FG.DrinkPriceVolume) {
|
||||||
|
volume.prices.sort((a, b) => {
|
||||||
|
if (a.price > b.price) return 1;
|
||||||
|
if (b.price > a.price) return -1;
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
deletePrice(price: FG.DrinkPrice, volume: FG.DrinkPriceVolume) {
|
||||||
|
axios
|
||||||
|
.delete(`pricelist/prices/${price.id}`)
|
||||||
|
.then(() => {
|
||||||
|
const index = volume.prices.findIndex((a) => a.id == price.id);
|
||||||
|
if (index > -1) {
|
||||||
|
volume.prices.splice(index, 1);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => console.warn(err));
|
||||||
|
},
|
||||||
|
updatePrice(price: FG.DrinkPrice, volume: FG.DrinkPriceVolume) {
|
||||||
|
axios
|
||||||
|
.put(`pricelist/prices/${price.id}`, price)
|
||||||
|
.then((response: AxiosResponse<FG.DrinkPrice>) => {
|
||||||
|
const index = volume.prices.findIndex((a) => a.id === price.id);
|
||||||
|
if (index > -1) {
|
||||||
|
volume.prices[index] = response.data;
|
||||||
|
this.sortPrices(volume);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => console.log(err));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters = {};
|
||||||
|
|
||||||
|
function calc_min_prices(row: FG.DrinkPriceVolume) {
|
||||||
|
row.volume = 0;
|
||||||
|
let cost_price = 0;
|
||||||
|
row.ingredients.forEach((ingredient: FG.DrinkIngredient & FG.ExtraIngredient) => {
|
||||||
|
console.log(ingredient);
|
||||||
|
if (ingredient.drink_ingredient) {
|
||||||
|
row.volume = row.volume + ingredient.volume;
|
||||||
|
cost_price += ingredient.volume * (ingredient.drink_ingredient.cost_price_pro_volume || 0);
|
||||||
|
} else if (ingredient.name && ingredient.price) {
|
||||||
|
cost_price += ingredient.price;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
row.min_prices.forEach((min_price) => {
|
||||||
|
min_price.price = (cost_price * min_price.percentage) / 100;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export { calc_min_prices };
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
actions,
|
||||||
|
getters,
|
||||||
|
};
|
Loading…
Reference in New Issue