flaschengeist/flaschengeist/plugins/pricelist/pricelist_controller.py

397 lines
10 KiB
Python

from werkzeug.exceptions import BadRequest, NotFound
from sqlalchemy.exc import IntegrityError
from flaschengeist import logger
from flaschengeist.config import config
from flaschengeist.database import db
from .models import Drink, DrinkPrice, Ingredient, Tag, DrinkType, DrinkPriceVolume, DrinkIngredient, ExtraIngredient
from flaschengeist.utils.picture import save_picture, get_picture, delete_picture
from uuid import uuid4
def update():
db.session.commit()
def get_tags():
return Tag.query.all()
def get_tag(identifier):
if isinstance(identifier, int):
retVal = Tag.query.get(identifier)
elif isinstance(identifier, str):
retVal = Tag.query.filter(Tag.name == identifier).one_or_none()
else:
logger.debug("Invalid identifier type for Tag")
raise BadRequest
if not retVal:
raise NotFound
return retVal
def create_tag(name):
try:
tag = Tag(name=name)
db.session.add(tag)
update()
return tag
except IntegrityError:
raise BadRequest("Name already exists")
def rename_tag(identifier, new_name):
tag = get_tag(identifier)
tag.name = new_name
try:
update()
except IntegrityError:
raise BadRequest("Name already exists")
def delete_tag(identifier):
tag = get_tag(identifier)
db.session.delete(tag)
try:
update()
except IntegrityError:
raise BadRequest("Tag still in use")
def get_drink_types():
return DrinkType.query.all()
def get_drink_type(identifier):
if isinstance(identifier, int):
retVal = DrinkType.query.get(identifier)
elif isinstance(identifier, str):
retVal = DrinkType.query.filter(Tag.name == identifier).one_or_none()
else:
logger.debug("Invalid identifier type for DrinkType")
raise BadRequest
if not retVal:
raise NotFound
return retVal
def create_drink_type(name):
try:
drinkType = DrinkType(name=name)
db.session.add(drinkType)
update()
return drinkType
except IntegrityError:
raise BadRequest("Name already exists")
def rename_drink_type(identifier, new_name):
drink_type = get_drink_type(identifier)
drink_type.name = new_name
try:
update()
except IntegrityError:
raise BadRequest("Name already exists")
return drink_type
def delete_drink_type(identifier):
drinkType = get_drink_type(identifier)
db.session.delete(drinkType)
try:
update()
except IntegrityError:
raise BadRequest("DrinkType still in use")
def get_drinks(name=None):
if name:
return Drink.query.filter(Drink.name.contains(name)).all()
return Drink.query.all()
def get_drink(identifier):
if isinstance(identifier, int):
return Drink.query.get(identifier)
elif isinstance(identifier, str):
return Drink.query.filter(Tag.name == identifier).one_or_none()
else:
logger.debug("Invalid identifier type for Drink")
raise BadRequest
raise NotFound
def set_drink(data):
return update_drink(-1, data)
def update_drink(identifier, data):
allowedKeys = Drink().serialize().keys()
if "id" in data:
data.pop("id")
if "volumes" in data:
volumes = data.pop("volumes")
if "tags" in data:
data.pop("tags")
type = None
if "type" in data:
_type = data.pop("type")
if isinstance(_type, dict) and "id" in _type:
type = get_drink_type(_type.get("id"))
if identifier == -1:
drink = Drink()
db.session.add(drink)
else:
drink = get_drink(identifier)
if not drink:
raise NotFound
for key, value in data.items():
if hasattr(drink, key):
setattr(drink, key, value if value != "" else None)
if type:
drink.type = type
if volumes:
set_volumes(volumes, drink)
db.session.commit()
return drink
def set_volumes(volumes, drink):
if isinstance(volumes, list):
_volumes = []
for _volume in volumes:
volume = set_volume(_volume)
_volumes.append(volume)
drink.volumes = _volumes
def delete_drink(identifier):
drink = get_drink(identifier)
db.session.delete(drink)
db.session.commit()
def get_volume(identifier):
return DrinkPriceVolume.query.get(identifier)
def get_volumes(drink_id=None):
if drink_id:
return DrinkPriceVolume.query.filter(DrinkPriceVolume.drink_id == drink_id).all()
return DrinkPriceVolume.query.all()
def set_volume(data):
allowed_keys = DrinkPriceVolume().serialize().keys()
values = {key: value for key, value in data.items() if key in allowed_keys}
prices = None
ingredients = None
if "prices" in values:
prices = values.pop("prices")
if "ingredients" in values:
ingredients = values.pop("ingredients")
id = None
if "id" in values:
id = values.pop("id")
volume = None
if id < 0:
volume = DrinkPriceVolume(**values)
db.session.add(volume)
else:
volume = get_volume(id)
if not volume:
raise NotFound
for key, value in values.items():
setattr(volume, key, value if value != "" else None)
if prices:
set_prices(prices, volume)
if ingredients:
set_ingredients(ingredients, volume)
return volume
def set_prices(prices, volume):
if isinstance(prices, list):
_prices = []
for _price in prices:
price = set_price(_price)
_prices.append(price)
volume.prices = _prices
def set_ingredients(ingredients, volume):
if isinstance(ingredients, list):
_ingredietns = []
for _ingredient in ingredients:
ingredient = set_ingredient(_ingredient)
_ingredietns.append(ingredient)
volume.ingredients = _ingredietns
def delete_volume(identifier):
volume = get_volume(identifier)
db.session.delete(volume)
db.session.commit()
def get_price(identifier):
if isinstance(identifier, int):
return DrinkPrice.query.get(identifier)
raise NotFound
def get_prices(volume_id=None):
if volume_id:
return DrinkPrice.query.filter(DrinkPrice.volume_id_ == volume_id).all()
return DrinkPrice.query.all()
def set_price(data):
allowed_keys = DrinkPrice().serialize().keys()
values = {key: value for key, value in data.items() if key in allowed_keys}
id = None
if "id" in values:
id = values.pop("id")
price = None
if id < 0:
price = DrinkPrice(**values)
db.session.add(price)
else:
price = get_price(id)
if not price:
raise NotFound
for key, value in values.items():
setattr(price, key, value)
return price
def delete_price(identifier):
price = get_price(identifier)
db.session.delete(price)
db.session.commit()
def set_drink_ingredient(data):
allowedKeys = DrinkIngredient().serialize().keys()
drink = None
values = {key: value for key, value in data.items() if key in allowedKeys}
id = None
if "id" in values:
id = values.pop("id")
if id < 0:
drink_ingredient = DrinkIngredient(**values)
db.session.add(drink_ingredient)
else:
drink_ingredient = DrinkIngredient.query.get(id)
if not drink_ingredient:
raise NotFound
for key, value in values.items():
setattr(drink_ingredient, key, value if value != "" else None)
return drink_ingredient
def get_ingredient(identifier):
return Ingredient.query.get(identifier)
def set_ingredient(data):
drink_ingredient_value = None
extra_ingredient_value = None
if "drink_ingredient" in data:
drink_ingredient_value = data.pop("drink_ingredient")
if "extra_ingredient" in data:
extra_ingredient_value = data.pop("extra_ingredient")
id = None
if "id" in data:
id = data.pop("id")
ingredient = None
if id < 0:
ingredient = Ingredient(**data)
db.session.add(ingredient)
else:
ingredient = get_ingredient(id)
if not ingredient:
raise NotFound
if drink_ingredient_value:
ingredient.drink_ingredient = set_drink_ingredient(drink_ingredient_value)
if extra_ingredient_value:
if "id" in extra_ingredient_value:
ingredient.extra_ingredient = get_extra_ingredient(extra_ingredient_value.get("id"))
return ingredient
def delete_ingredient(identifier):
ingredient = get_ingredient(identifier)
if ingredient.drink_ingredient:
db.session.delete(ingredient.drink_ingredient)
db.session.delete(ingredient)
db.session.commit()
def get_extra_ingredients():
return ExtraIngredient.query.all()
def get_extra_ingredient(identifier):
return ExtraIngredient.query.get(identifier)
def set_extra_ingredient(data):
allowedKeys = ExtraIngredient().serialize().keys()
if "id" in data:
data.pop("id")
values = {key: value for key, value in data.items() if key in allowedKeys}
extra_ingredient = ExtraIngredient(**values)
db.session.add(extra_ingredient)
db.session.commit()
return extra_ingredient
def update_extra_ingredient(identifier, data):
allowedKeys = ExtraIngredient().serialize().keys()
if "id" in data:
data.pop("id")
values = {key: value for key, value in data.items() if key in allowedKeys}
extra_ingredient = get_extra_ingredient(identifier)
if extra_ingredient:
for key, value in values.items():
setattr(extra_ingredient, key, value)
db.session.commit()
return extra_ingredient
def delete_extra_ingredient(identifier):
extra_ingredient = get_extra_ingredient(identifier)
db.session.delete(extra_ingredient)
db.session.commit()
def save_drink_picture(identifier, file):
drink = get_drink(identifier)
if not drink.uuid:
drink.uuid = str(uuid4())
db.session.commit()
path = config["pricelist"]["path"]
save_picture(file, f"{path}/{drink.uuid}")
def get_drink_picture(identifier, size=None):
drink = get_drink(identifier)
if not drink.uuid:
raise FileNotFoundError
path = config["pricelist"]["path"]
return get_picture(f"{path}/{drink.uuid}")
def delete_drink_picture(identifier):
drink = get_drink(identifier)
if not drink.uuid:
delete_picture(f"{config['pricelist']['path']}/{drink.uuid}")
drink.uuid = None
db.session.commit()