761 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			761 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
| """Pricelist plugin"""
 | |
| 
 | |
| import pathlib
 | |
| from flask import Blueprint, jsonify, request, current_app
 | |
| from werkzeug.local import LocalProxy
 | |
| from werkzeug.exceptions import BadRequest, Forbidden, NotFound, Unauthorized
 | |
| 
 | |
| from flaschengeist import logger
 | |
| from flaschengeist.controller import userController
 | |
| from flaschengeist.controller.imageController import send_image, send_thumbnail
 | |
| from flaschengeist.plugins import Plugin
 | |
| from flaschengeist.utils.decorators import login_required, extract_session, headers
 | |
| from flaschengeist.utils.HTTP import no_content
 | |
| 
 | |
| from . import models
 | |
| from . import pricelist_controller, permissions
 | |
| 
 | |
| 
 | |
| blueprint = Blueprint("pricelist", __name__, url_prefix="/pricelist")
 | |
| 
 | |
| 
 | |
| class PriceListPlugin(Plugin):
 | |
|     permissions = permissions.permissions
 | |
|     plugin = LocalProxy(lambda: current_app.config["FG_PLUGINS"][PriceListPlugin.name])
 | |
|     models = models
 | |
| 
 | |
|     def __init__(self, entry_point, config=None):
 | |
|         super().__init__(entry_point, config)
 | |
|         self.blueprint = blueprint
 | |
|         self.migrations_path = (pathlib.Path(__file__).parent / "migrations").resolve()
 | |
|         config = {"discount": 0}
 | |
|         config.update(config)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drink-types", methods=["GET"])
 | |
| @blueprint.route("/drink-types/<int:identifier>", methods=["GET"])
 | |
| def get_drink_types(identifier=None):
 | |
|     """Get DrinkType(s)
 | |
| 
 | |
|     Route: ``/pricelist/drink-types`` | Method: ``GET``
 | |
|     Route: ``/pricelist/drink-types/<identifier>`` | Method: ``GET``
 | |
| 
 | |
|     Args:
 | |
|         identifier: If querying a spicific DrinkType
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded (list of) DrinkType(s) or HTTP-error
 | |
|     """
 | |
|     if identifier is None:
 | |
|         result = pricelist_controller.get_drink_types()
 | |
|     else:
 | |
|         result = pricelist_controller.get_drink_type(identifier)
 | |
|     return jsonify(result)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drink-types", methods=["POST"])
 | |
| @login_required(permission=permissions.CREATE_TYPE)
 | |
| def new_drink_type(current_session):
 | |
|     """Create new DrinkType
 | |
| 
 | |
|     Route ``/pricelist/drink-types`` | Method: ``POST``
 | |
| 
 | |
|     POST-data: ``{name: string}``
 | |
| 
 | |
|     Args:
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded DrinkType or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     if "name" not in data:
 | |
|         raise BadRequest
 | |
|     drink_type = pricelist_controller.create_drink_type(data["name"])
 | |
|     return jsonify(drink_type)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drink-types/<int:identifier>", methods=["PUT"])
 | |
| @login_required(permission=permissions.EDIT_TYPE)
 | |
| def update_drink_type(identifier, current_session):
 | |
|     """Modify DrinkType
 | |
| 
 | |
|     Route ``/pricelist/drink-types/<identifier>`` | METHOD ``PUT``
 | |
| 
 | |
|     POST-data: ``{name: string}``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of DrinkType
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded DrinkType or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     if "name" not in data:
 | |
|         raise BadRequest
 | |
|     drink_type = pricelist_controller.rename_drink_type(identifier, data["name"])
 | |
|     return jsonify(drink_type)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drink-types/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE_TYPE)
 | |
| def delete_drink_type(identifier, current_session):
 | |
|     """Delete DrinkType
 | |
| 
 | |
|     Route: ``/pricelist/drink-types/<identifier>`` | Method: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of DrinkType
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_drink_type(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/tags", methods=["GET"])
 | |
| @blueprint.route("/tags/<int:identifier>", methods=["GET"])
 | |
| def get_tags(identifier=None):
 | |
|     """Get Tag(s)
 | |
| 
 | |
|     Route: ``/pricelist/tags`` | Method: ``GET``
 | |
|     Route: ``/pricelist/tags/<identifier>`` | Method: ``GET``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Tag
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded (list of) Tag(s) or HTTP-error
 | |
|     """
 | |
|     if identifier:
 | |
|         result = pricelist_controller.get_tag(identifier)
 | |
|     else:
 | |
|         result = pricelist_controller.get_tags()
 | |
|     return jsonify(result)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/tags", methods=["POST"])
 | |
| @login_required(permission=permissions.CREATE_TAG)
 | |
| def new_tag(current_session):
 | |
|     """Create Tag
 | |
| 
 | |
|     Route: ``/pricelist/tags`` | Method: ``POST``
 | |
| 
 | |
|     POST-data: ``{name: string, color: string}``
 | |
| 
 | |
|     Args:
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded Tag or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     drink_type = pricelist_controller.create_tag(data)
 | |
|     return jsonify(drink_type)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/tags/<int:identifier>", methods=["PUT"])
 | |
| @login_required(permission=permissions.EDIT_TAG)
 | |
| def update_tag(identifier, current_session):
 | |
|     """Modify Tag
 | |
| 
 | |
|     Route: ``/pricelist/tags/<identifier>`` | Methods: ``PUT``
 | |
| 
 | |
|     POST-data: ``{name: string, color: string}``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Tag
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded Tag or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     tag = pricelist_controller.update_tag(identifier, data)
 | |
|     return jsonify(tag)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/tags/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE_TAG)
 | |
| def delete_tag(identifier, current_session):
 | |
|     """Delete Tag
 | |
| 
 | |
|     Route: ``/pricelist/tags/<identifier>`` | Methods: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Tag
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_tag(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks", methods=["GET"])
 | |
| @blueprint.route("/drinks/<int:identifier>", methods=["GET"])
 | |
| def get_drinks(identifier=None):
 | |
|     """Get Drink(s)
 | |
| 
 | |
|     Route: ``/pricelist/drinks`` | Method: ``GET``
 | |
|     Route: ``/pricelist/drinks/<identifier>`` | Method: ``GET``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Drink
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded (list of) Drink(s) or HTTP-error
 | |
|     """
 | |
|     public = True
 | |
|     try:
 | |
|         extract_session()
 | |
|         public = False
 | |
|     except Unauthorized:
 | |
|         public = True
 | |
| 
 | |
|     if identifier:
 | |
|         result = pricelist_controller.get_drink(identifier, public=public)
 | |
|         return jsonify(result)
 | |
|     else:
 | |
|         limit = request.args.get("limit")
 | |
|         offset = request.args.get("offset")
 | |
|         search_name = request.args.get("search_name")
 | |
|         search_key = request.args.get("search_key")
 | |
|         ingredient = request.args.get("ingredient", type=bool)
 | |
|         receipt = request.args.get("receipt", type=bool)
 | |
|         try:
 | |
|             if limit is not None:
 | |
|                 limit = int(limit)
 | |
|             if offset is not None:
 | |
|                 offset = int(offset)
 | |
|             if ingredient is not None:
 | |
|                 ingredient = bool(ingredient)
 | |
|             if receipt is not None:
 | |
|                 receipt = bool(receipt)
 | |
|         except ValueError:
 | |
|             raise BadRequest
 | |
|         drinks, count = pricelist_controller.get_drinks(
 | |
|             public=public,
 | |
|             limit=limit,
 | |
|             offset=offset,
 | |
|             search_name=search_name,
 | |
|             search_key=search_key,
 | |
|             ingredient=ingredient,
 | |
|             receipt=receipt,
 | |
|         )
 | |
|     mop = drinks.copy()
 | |
|     logger.debug(f"GET drink {drinks}, {count}")
 | |
|     # return jsonify({"drinks": drinks, "count": count})
 | |
|     return jsonify({"drinks": drinks, "count": count})
 | |
| 
 | |
| 
 | |
| @blueprint.route("/list", methods=["GET"])
 | |
| def get_pricelist():
 | |
|     """Get Priclist
 | |
|     Route: ``/pricelist/list`` | Method: ``GET``
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded list of DrinkPrices or HTTP-KeyError
 | |
|     """
 | |
|     public = True
 | |
|     try:
 | |
|         extract_session()
 | |
|         public = False
 | |
|     except Unauthorized:
 | |
|         public = True
 | |
| 
 | |
|     limit = request.args.get("limit")
 | |
|     offset = request.args.get("offset")
 | |
|     search_name = request.args.get("search_name")
 | |
|     search_key = request.args.get("search_key")
 | |
|     ingredient = request.args.get("ingredient", type=bool)
 | |
|     receipt = request.args.get("receipt", type=bool)
 | |
|     descending = request.args.get("descending", type=bool)
 | |
|     sortBy = request.args.get("sortBy")
 | |
|     try:
 | |
|         if limit is not None:
 | |
|             limit = int(limit)
 | |
|         if offset is not None:
 | |
|             offset = int(offset)
 | |
|         if ingredient is not None:
 | |
|             ingredient = bool(ingredient)
 | |
|         if receipt is not None:
 | |
|             receipt = bool(receipt)
 | |
|         if descending is not None:
 | |
|             descending = bool(descending)
 | |
|     except ValueError:
 | |
|         raise BadRequest
 | |
|     pricelist, count = pricelist_controller.get_pricelist(
 | |
|         public=public,
 | |
|         limit=limit,
 | |
|         offset=offset,
 | |
|         search_name=search_name,
 | |
|         search_key=search_key,
 | |
|         descending=descending,
 | |
|         sortBy=sortBy,
 | |
|     )
 | |
|     logger.debug(f"GET pricelist {pricelist}, {count}")
 | |
|     return jsonify({"pricelist": pricelist, "count": count})
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks/search/<string:name>", methods=["GET"])
 | |
| def search_drinks(name):
 | |
|     """Search Drink
 | |
| 
 | |
|     Route: ``/pricelist/drinks/search/<name>`` | Method: ``GET``
 | |
| 
 | |
|     Args:
 | |
|         name: Name to search
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded list of Drinks or HTTP-error
 | |
|     """
 | |
|     public = True
 | |
|     try:
 | |
|         extract_session()
 | |
|         public = False
 | |
|     except Unauthorized:
 | |
|         public = True
 | |
|     return jsonify(pricelist_controller.get_drinks(name, public=public))
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks", methods=["POST"])
 | |
| @login_required(permission=permissions.CREATE)
 | |
| def create_drink(current_session):
 | |
|     """Create Drink
 | |
| 
 | |
|         Route: ``/pricelist/drinks`` | Method: ``POST``
 | |
| 
 | |
|         POST-data :
 | |
|     ``{
 | |
|         article_id?: string
 | |
|         cost_per_package?: float,
 | |
|         cost_per_volume?: float,
 | |
|         name: string,
 | |
|         package_size?: number,
 | |
|         receipt?: list[string],
 | |
|         tags?: list[Tag],
 | |
|         type: DrinkType,
 | |
|         uuid?: string,
 | |
|         volume?: float,
 | |
|         volumes?: list[
 | |
|             {
 | |
|                 ingredients?: list[{
 | |
|                     id: int
 | |
|                     drink_ingredient?: {
 | |
|                         ingredient_id: int,
 | |
|                         volume: float
 | |
|                     },
 | |
|                     extra_ingredient?: {
 | |
|                         id: number,
 | |
|                     }
 | |
|                 }],
 | |
|                 prices?: list[
 | |
|                     {
 | |
|                         price: float
 | |
|                         public: boolean
 | |
|                     }
 | |
|                 ],
 | |
|                 volume: float
 | |
|             }
 | |
|         ]
 | |
|     }``
 | |
| 
 | |
|         Args:
 | |
|             current_session: Session sent with Authorization Header
 | |
| 
 | |
|         Returns:
 | |
|             JSON encoded Drink or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     return jsonify(pricelist_controller.set_drink(data))
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks/<int:identifier>", methods=["PUT"])
 | |
| @login_required(permission=permissions.EDIT)
 | |
| def update_drink(identifier, current_session):
 | |
|     """Modify Drink
 | |
| 
 | |
|         Route: ``/pricelist/drinks/<identifier>`` | Method: ``PUT``
 | |
| 
 | |
|         POST-data :
 | |
|     ``{
 | |
|         article_id?: string
 | |
|         cost_per_package?: float,
 | |
|         cost_per_volume?: float,
 | |
|         name: string,
 | |
|         package_size?: number,
 | |
|         receipt?: list[string],
 | |
|         tags?: list[Tag],
 | |
|         type: DrinkType,
 | |
|         uuid?: string,
 | |
|         volume?: float,
 | |
|         volumes?: list[
 | |
|             {
 | |
|                 ingredients?: list[{
 | |
|                     id: int
 | |
|                     drink_ingredient?: {
 | |
|                         ingredient_id: int,
 | |
|                         volume: float
 | |
|                     },
 | |
|                     extra_ingredient?: {
 | |
|                         id: number,
 | |
|                     }
 | |
|                 }],
 | |
|                 prices?: list[
 | |
|                     {
 | |
|                         price: float
 | |
|                         public: boolean
 | |
|                     }
 | |
|                 ],
 | |
|                 volume: float
 | |
|             }
 | |
|         ]
 | |
|     }``
 | |
| 
 | |
|         Args:
 | |
|             identifier: Identifier of Drink
 | |
|             current_session: Session sent with Authorization Header
 | |
| 
 | |
|         Returns:
 | |
|             JSON encoded Drink or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     logger.debug(f"update drink {data}")
 | |
|     return jsonify(pricelist_controller.update_drink(identifier, data))
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE)
 | |
| def delete_drink(identifier, current_session):
 | |
|     """Delete Drink
 | |
| 
 | |
|     Route: ``/pricelist/drinks/<identifier>`` | Method: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Drink
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_drink(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/prices/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE_PRICE)
 | |
| def delete_price(identifier, current_session):
 | |
|     """Delete Price
 | |
| 
 | |
|     Route: ``/pricelist/prices/<identifier>`` | Methods: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identiefer of Price
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_price(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/volumes/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE_VOLUME)
 | |
| def delete_volume(identifier, current_session):
 | |
|     """Delete DrinkPriceVolume
 | |
| 
 | |
|     Route: ``/pricelist/volumes/<identifier>`` | Method: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of DrinkPriceVolume
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_volume(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/ingredients/extraIngredients", methods=["GET"])
 | |
| @login_required()
 | |
| def get_extra_ingredients(current_session):
 | |
|     """Get ExtraIngredients
 | |
| 
 | |
|     Route: ``/pricelist/ingredients/extraIngredients`` | Method: ``GET``
 | |
| 
 | |
|     Args:
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded list of ExtraIngredients or HTTP-error
 | |
|     """
 | |
|     return jsonify(pricelist_controller.get_extra_ingredients())
 | |
| 
 | |
| 
 | |
| @blueprint.route("/ingredients/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE_INGREDIENTS_DRINK)
 | |
| def delete_ingredient(identifier, current_session):
 | |
|     """Delete Ingredient
 | |
| 
 | |
|     Route: ``/pricelist/ingredients/<identifier>`` | Method: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Ingredient
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_ingredient(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/ingredients/extraIngredients", methods=["POST"])
 | |
| @login_required(permission=permissions.EDIT_INGREDIENTS)
 | |
| def set_extra_ingredient(current_session):
 | |
|     """Create ExtraIngredient
 | |
| 
 | |
|     Route: ``/pricelist/ingredients/extraIngredients`` | Method: ``POST``
 | |
| 
 | |
|     POST-data: ``{ name: string, price: float }``
 | |
| 
 | |
|     Args:
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded ExtraIngredient or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     return jsonify(pricelist_controller.set_extra_ingredient(data))
 | |
| 
 | |
| 
 | |
| @blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["PUT"])
 | |
| @login_required(permission=permissions.EDIT_INGREDIENTS)
 | |
| def update_extra_ingredient(identifier, current_session):
 | |
|     """Modify ExtraIngredient
 | |
| 
 | |
|     Route: ``/pricelist/ingredients/extraIngredients`` | Method: ``PUT``
 | |
| 
 | |
|     POST-data: ``{ name: string, price: float }``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of ExtraIngredient
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded ExtraIngredient or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     return jsonify(pricelist_controller.update_extra_ingredient(identifier, data))
 | |
| 
 | |
| 
 | |
| @blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["DELETE"])
 | |
| @login_required(permission=permissions.DELETE_INGREDIENTS)
 | |
| def delete_extra_ingredient(identifier, current_session):
 | |
|     """Delete ExtraIngredient
 | |
| 
 | |
|     Route: ``/pricelist/ingredients/extraIngredients`` | Method: ``DELETE``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of ExtraIngredient
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     pricelist_controller.delete_extra_ingredient(identifier)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/settings/min_prices", methods=["GET"])
 | |
| @login_required()
 | |
| def get_pricelist_settings_min_prices(current_session):
 | |
|     """Get MinPrices
 | |
| 
 | |
|     Route: ``/pricelist/settings/min_prices`` | Method: ``GET``
 | |
| 
 | |
|     Args:
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         JSON encoded list of MinPrices
 | |
|     """
 | |
|     # TODO: Handle if no prices are set!
 | |
|     try:
 | |
|         min_prices = PriceListPlugin.plugin.get_setting("min_prices")
 | |
|     except KeyError:
 | |
|         min_prices = []
 | |
|     return jsonify(min_prices)
 | |
| 
 | |
| 
 | |
| @blueprint.route("/settings/min_prices", methods=["POST"])
 | |
| @login_required(permission=permissions.EDIT_MIN_PRICES)
 | |
| def post_pricelist_settings_min_prices(current_session):
 | |
|     """Create MinPrices
 | |
| 
 | |
|     Route: ``/pricelist/settings/min_prices`` | Method: ``POST``
 | |
| 
 | |
|     POST-data: ``list[int]``
 | |
| 
 | |
|     Args:
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         HTTP-NoContent or HTTP-error
 | |
|     """
 | |
|     data = request.get_json()
 | |
|     if not isinstance(data, list) or not all(isinstance(n, int) for n in data):
 | |
|         raise BadRequest
 | |
|     data.sort()
 | |
|     PriceListPlugin.plugin.set_setting("min_prices", data)
 | |
|     return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/users/<userid>/pricecalc_columns", methods=["GET", "PUT"])
 | |
| @login_required()
 | |
| def get_columns(userid, current_session):
 | |
|     """Get pricecalc_columns of an user
 | |
| 
 | |
|     Route: ``/users/<userid>/pricelist/pricecac_columns`` | Method: ``GET`` or ``PUT``
 | |
|     POST-data: On ``PUT`` json encoded array of floats
 | |
| 
 | |
|     Args:
 | |
|         userid: Userid identifying the user
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         GET: JSON object containing the shortcuts as float array or HTTP error
 | |
|         PUT: HTTP-created or HTTP error
 | |
|     """
 | |
|     if userid != current_session.user_.userid:
 | |
|         raise Forbidden
 | |
| 
 | |
|     user = userController.get_user(userid)
 | |
|     if request.method == "GET":
 | |
|         return jsonify(user.get_attribute("pricecalc_columns", []))
 | |
|     else:
 | |
|         data = request.get_json()
 | |
|         if not isinstance(data, list) or not all(isinstance(n, str) for n in data):
 | |
|             raise BadRequest
 | |
|         data.sort(reverse=True)
 | |
|         user.set_attribute("pricecalc_columns", data)
 | |
|         userController.persist()
 | |
|         return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/users/<userid>/pricecalc_columns_order", methods=["GET", "PUT"])
 | |
| @login_required()
 | |
| def get_columns_order(userid, current_session):
 | |
|     """Get pricecalc_columns_order of an user
 | |
| 
 | |
|     Route: ``/users/<userid>/pricelist/pricecac_columns_order`` | Method: ``GET`` or ``PUT``
 | |
|     POST-data: On ``PUT`` json encoded array of floats
 | |
| 
 | |
|     Args:
 | |
|         userid: Userid identifying the user
 | |
|         current_session: Session sent with Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         GET: JSON object containing the shortcuts as object array or HTTP error
 | |
|         PUT: HTTP-created or HTTP error
 | |
|     """
 | |
|     if userid != current_session.user_.userid:
 | |
|         raise Forbidden
 | |
| 
 | |
|     user = userController.get_user(userid)
 | |
|     if request.method == "GET":
 | |
|         return jsonify(user.get_attribute("pricecalc_columns_order", []))
 | |
|     else:
 | |
|         data = request.get_json()
 | |
|         if not isinstance(data, list) or not all(isinstance(n, str) for mop in data for n in mop.values()):
 | |
|             raise BadRequest
 | |
|         user.set_attribute("pricecalc_columns_order", data)
 | |
|         userController.persist()
 | |
|         return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/users/<userid>/pricelist", methods=["GET", "PUT"])
 | |
| @login_required()
 | |
| def get_priclist_setting(userid, current_session):
 | |
|     """Get pricelistsetting of an user
 | |
| 
 | |
|     Route: ``/pricelist/user/<userid>/pricelist`` | Method: ``GET`` or ``PUT``
 | |
| 
 | |
|     POST-data: on ``PUT`` ``{value: boolean}``
 | |
| 
 | |
|     Args:
 | |
|         userid: Userid identifying the user
 | |
|         current_session: Session sent wth Authorization Header
 | |
| 
 | |
|     Returns:
 | |
|         GET: JSON object containing the value as boolean or HTTP-error
 | |
|         PUT: HTTP-NoContent or HTTP-error
 | |
|     """
 | |
| 
 | |
|     if userid != current_session.user_.userid:
 | |
|         raise Forbidden
 | |
| 
 | |
|     user = userController.get_user(userid)
 | |
|     if request.method == "GET":
 | |
|         return jsonify(user.get_attribute("pricelist_view", {"value": False}))
 | |
|     else:
 | |
|         data = request.get_json()
 | |
|         if not isinstance(data, dict) or not "value" in data or not isinstance(data["value"], bool):
 | |
|             raise BadRequest
 | |
|         user.set_attribute("pricelist_view", data)
 | |
|         userController.persist()
 | |
|         return no_content()
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks/<int:identifier>/picture", methods=["POST", "DELETE"])
 | |
| @login_required(permission=permissions.EDIT)
 | |
| def set_picture(identifier, current_session):
 | |
|     """Get, Create, Delete Drink Picture
 | |
| 
 | |
|     Route: ``/pricelist/<identifier>/picture`` | Method: ``GET,POST,DELETE``
 | |
| 
 | |
|     POST-data: (if remaining) ``Form-Data: mime: 'image/*'``
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Drink
 | |
|         current_session: Session sent with Authorization
 | |
| 
 | |
|     Returns:
 | |
|         Picture or HTTP-error
 | |
|     """
 | |
|     if request.method == "DELETE":
 | |
|         pricelist_controller.delete_drink_picture(identifier)
 | |
|         return no_content()
 | |
| 
 | |
|     file = request.files.get("file")
 | |
|     if file:
 | |
|         return jsonify(pricelist_controller.save_drink_picture(identifier, file))
 | |
|     else:
 | |
|         raise BadRequest
 | |
| 
 | |
| 
 | |
| @blueprint.route("/drinks/<int:identifier>/picture", methods=["GET"])
 | |
| # @headers({"Cache-Control": "private, must-revalidate"})
 | |
| def _get_picture(identifier):
 | |
|     """Get Picture
 | |
| 
 | |
|     Args:
 | |
|         identifier: Identifier of Drink
 | |
| 
 | |
|     Returns:
 | |
|         Picture or HTTP-error
 | |
|     """
 | |
|     drink = pricelist_controller.get_drink(identifier)
 | |
|     if drink.has_image:
 | |
|         if request.args.get("thumbnail"):
 | |
|             return send_thumbnail(image=drink.image_)
 | |
|         return send_image(image=drink.image_)
 | |
|     raise NotFound
 |