import { reactive, computed, ComputedRef, WritableComputedRef } from '@vue/composition-api'; import { axios } from 'src/boot/axios'; import { AxiosResponse } from 'axios'; const state = reactive<{ drinks: Drink[]; tags: FG.Tag[]; drinkTypes: FG.DrinkType[]; extraIngredients: FG.ExtraIngredient[]; }>({ drinks: [], tags: [], drinkTypes: [], extraIngredients: [], }); interface MinPrice extends Omit { price: WritableComputedRef | null; } interface DrinkPriceVolume extends Omit, 'min_prices'> { _volume: number; volume: WritableComputedRef | null; min_prices: MinPrice[]; } interface Drink extends Omit, 'volumes'> { volumes: DrinkPriceVolume[]; cost_price_pro_volume: WritableComputedRef; _cost_price_pro_volume?: number; } class DrinkPriceVolume { constructor({ id, volume, min_prices, prices, ingredients }: FG.DrinkPriceVolume, drink: Drink) { this.id = id; this._volume = volume; this.prices = prices; this.ingredients = ingredients; this.min_prices = [ { percentage: 100, price: create_min_prices(drink, this, 100), }, { percentage: 250, price: create_min_prices(drink, this, 250), }, { percentage: 300, price: create_min_prices(drink, this, 300), }, ]; this.volume = computed({ get: () => { if (this.ingredients.some((ingredient) => !!ingredient.drink_ingredient)) { let retVal = 0; this.ingredients.forEach((ingredient) => { if (ingredient.drink_ingredient?.volume) { retVal += ingredient.drink_ingredient.volume; } }); this._volume = retVal; return retVal; } else { return this._volume; } }, set: (val) => (this._volume = val), }); } } class Drink { constructor({ id, article_id, package_size, name, volume, cost_price_pro_volume, cost_price_package_netto, tags, type, volumes, }: FG.Drink) { this.id = id; this.article_id = article_id; this.package_size = package_size; this.name = name; this.volume = volume; this.cost_price_package_netto = cost_price_package_netto; this._cost_price_pro_volume = cost_price_pro_volume; this.cost_price_pro_volume = computed({ get: () => { if (!!this.volume && !!this.package_size && !!this.cost_price_package_netto) { const retVal = ((this.cost_price_package_netto || 0) / ((this.volume || 0) * (this.package_size || 0))) * 1.19; this._cost_price_pro_volume = Math.round(retVal * 1000) / 1000; } return this._cost_price_pro_volume; }, set: (val) => (this._cost_price_pro_volume = val), }); this.tags = tags; this.type = type; this.volumes = []; /*volumes.forEach(volume => { this.volumes.push(new DrinkPriceVolume(volume, this)); });*/ } } const actions = { getDrinks() { axios .get('pricelist/drinks') .then((response: AxiosResponse) => { state.drinks = []; response.data.forEach((drink) => { state.drinks.push(new Drink(drink)); }); state.drinks.forEach((drink) => { const _drink = response.data.find((a) => a.id === drink.id); _drink?.volumes.forEach((volume) => { drink.volumes.push(new DrinkPriceVolume(volume, drink)); }); }); }) .catch((err) => console.warn(err)); }, setPrice(price: FG.DrinkPrice, volume: DrinkPriceVolume) { axios .post(`pricelist/volumes/${volume.id}/prices`, price) .then((response: AxiosResponse) => { volume.prices.push(response.data); this.sortPrices(volume); }) .catch((err) => console.warn(err)); }, sortPrices(volume: 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: DrinkPriceVolume) { axios .put(`pricelist/prices/${price.id}`, price) .then((response: AxiosResponse) => { const index = volume.prices.findIndex((a) => a.id === price.id); if (index > -1) { this.sortPrices(volume); } }) .catch((err) => console.log(err)); }, setVolume(volume: DrinkPriceVolume, drink: Drink) { console.log(volume); axios .post(`pricelist/drinks/${drink.id}/volumes`, { ...volume, volume: volume.volume, }) .then((response: AxiosResponse) => { drink.volumes.push(new DrinkPriceVolume(response.data, drink)); }) .catch((err) => console.warn(err)); }, updateVolume(volume: DrinkPriceVolume, drink: Drink) { axios .put(`pricelist/volumes/${volume.id}`, { ...volume, volume: volume.volume?.value, }) .catch((err) => console.warn(err)); }, deleteVolume(volume: FG.DrinkPriceVolume, drink: FG.Drink) { axios .delete(`pricelist/volumes/${volume.id}`) .then(() => { const index = drink.volumes.findIndex((a) => a.id === volume.id); if (index > -1) { drink.volumes.splice(index, 1); } }) .catch((err) => console.warn(err)); }, getExtraIngredients() { axios .get('pricelist/ingredients/extraIngredients') .then((response: AxiosResponse) => { state.extraIngredients = response.data; }) .catch((err) => console.log(err)); }, setIngredient(ingredient: FG.Ingredient, volume: DrinkPriceVolume) { axios .post(`pricelist/volumes/${volume.id}/ingredients`, ingredient) .then((response: AxiosResponse) => { volume.ingredients.push(response.data); }) .catch((err) => console.warn(err)); }, updateIngredient(ingredient: FG.Ingredient, volume: DrinkPriceVolume) { axios .put(`pricelist/ingredients/${ingredient.id}`, ingredient) .then((response: AxiosResponse) => { const index = volume.ingredients.findIndex((a) => a.id === response.data.id); if (index > -1) { volume.ingredients[index] = response.data; } }) .catch((err) => console.warn(err)); }, deleteIngredient(ingredient: FG.Ingredient, volume: DrinkPriceVolume) { axios .delete(`pricelist/ingredients/${ingredient.id}`) .then(() => { const index = volume.ingredients.findIndex((a) => a.id === ingredient.id); if (index > -1) { volume.ingredients.splice(index, 1); } }) .catch((err) => console.warn(err)); }, getDrinkTypes() { axios .get('pricelist/drink-types') .then((response: AxiosResponse) => { state.drinkTypes = response.data; }) .catch((err) => console.warn(err)); }, setDrink(drink: FG.Drink) { axios .post('pricelist/drinks', drink) .then((response: AxiosResponse) => { state.drinks.push(new Drink(response.data)); const drink = state.drinks.find((a) => a.id === response.data.id); response.data.volumes.forEach((volume) => { drink?.volumes.push(new DrinkPriceVolume(volume, drink)); }); }) .catch((err) => console.warn(err)); }, updateDrink(drink: Drink) { axios .put(`pricelist/drinks/${drink.id}`, { ...drink, cost_price_pro_volume: drink.cost_price_pro_volume?.value, }) .catch((err) => console.warn(err)); }, deleteDrink(drink: Drink) { axios .delete(`pricelist/drinks/${drink.id}`) .then(() => { const index = state.drinks.findIndex((a) => a.id === drink.id); if (index > -1) { state.drinks.splice(index, 1); } }) .catch((err) => console.warn(err)); }, setExtraIngredient(ingredient: FG.ExtraIngredient) { axios .post(`pricelist/ingredients/extraIngredients`, ingredient) .then((response: AxiosResponse) => { 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) => { 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)); }, }; const getters = {}; function create_min_prices(drink: Drink, volume: DrinkPriceVolume, percentage: number) { if (drink.cost_price_pro_volume?.value) { if (volume.ingredients.every((ingredient) => !!ingredient.drink_ingredient)) { return computed(() => { let retVal = (drink.cost_price_pro_volume?.value || 0) * (volume.volume?.value || 0); volume.ingredients.forEach((ingredient) => { if (ingredient.extra_ingredient) { retVal += ingredient.extra_ingredient.price; } }); retVal = (retVal * percentage) / 100; return retVal; }); } else { return computed( () => ((drink.cost_price_pro_volume?.value || 0) * (volume.volume?.value || 0) * percentage) / 100 ); } } else { return computed(() => { let retVal = 0; volume.ingredients.forEach((ingredient) => { if (ingredient.drink_ingredient) { const _drink = state.drinks.find( (a) => a.id === ingredient.drink_ingredient?.drink_ingredient?.id ); retVal += ingredient.drink_ingredient.volume * (_drink?.cost_price_pro_volume.value || 0); } if (ingredient.extra_ingredient) { retVal += ingredient.extra_ingredient.price; } }); console.log(volume); return (retVal * percentage) / 100; }); } } export { create_min_prices, DrinkPriceVolume, MinPrice, Drink }; export default { state, actions, getters, };