From e7b978ae3c6fc57288e21204b7fb1a1f8b042401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Wed, 30 Jun 2021 10:45:41 +0200 Subject: [PATCH 1/8] better drink dependency drink_ingredient has name and cost_per_volume https://flaschengeist.dev/Flaschengeist/flaschengeist-pricelist/issues/2 --- flaschengeist/plugins/pricelist/models.py | 17 +++++++++-------- .../plugins/pricelist/pricelist_controller.py | 4 ++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/flaschengeist/plugins/pricelist/models.py b/flaschengeist/plugins/pricelist/models.py index ffde797..f6d68f9 100644 --- a/flaschengeist/plugins/pricelist/models.py +++ b/flaschengeist/plugins/pricelist/models.py @@ -76,16 +76,17 @@ class DrinkIngredient(db.Model, ModelSerializeMixin): id: int = db.Column("id", db.Integer, primary_key=True) volume: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False), nullable=False) ingredient_id: int = db.Column(db.Integer, db.ForeignKey("drink.id")) - # drink_ingredient: Drink = db.relationship("Drink") - # price: float = 0 + cost_per_volume: float + name: str + _drink_ingredient: Drink = db.relationship("Drink") + @property + def cost_per_volume(self): + return self._drink_ingredient.cost_per_volume if self._drink_ingredient else None -# @property -# def price(self): -# try: -# return self.drink_ingredient.cost_price_pro_volume * self.volume -# except AttributeError: -# pass + @property + def name(self): + return self._drink_ingredient.name if self._drink_ingredient else None class Ingredient(db.Model, ModelSerializeMixin): diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index 1c1491e..c89dc2d 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -315,6 +315,10 @@ def delete_price(identifier): def set_drink_ingredient(data): allowed_keys = DrinkIngredient().serialize().keys() values = {key: value for key, value in data.items() if key in allowed_keys} + if "cost_per_volume" in values: + values.pop("cost_per_volume") + if "name" in values: + values.pop("name") ingredient_id = values.pop("id", -1) if ingredient_id < 0: drink_ingredient = DrinkIngredient(**values) -- 2.40.1 From 26a00ed6a6b5a709960fe0d6c78eb4f4de6829cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Fri, 12 Nov 2021 22:09:16 +0100 Subject: [PATCH 2/8] [pricelist] add serverside pagination of drinks --- flaschengeist/plugins/pricelist/__init__.py | 17 +++++++++++--- .../plugins/pricelist/pricelist_controller.py | 22 ++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index b4df1ac..67c92db 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -214,10 +214,21 @@ def get_drinks(identifier=None): if identifier: result = pricelist_controller.get_drink(identifier, public=public) + return jsonify(result) else: - result = pricelist_controller.get_drinks(public=public) - logger.debug(f"GET drink {result}") - return jsonify(result) + limit = request.args.get("limit") + offset = request.args.get("offset") + try: + if limit is not None: + limit = int(limit) + if offset is not None: + offset = int(offset) + except ValueError: + raise BadRequest + drinks, count = pricelist_controller.get_drinks(public=public, limit=limit, offset=offset) + logger.debug(f"GET drink {drinks}, {count}") + # return jsonify({"drinks": drinks, "count": count}) + return jsonify({"drinks": drinks, "count": count}) @PriceListPlugin.blueprint.route("/drinks/search/", methods=["GET"]) diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index c89dc2d..6ea9b87 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -131,13 +131,22 @@ def _create_public_drink(drink): return None -def get_drinks(name=None, public=False): +def get_drinks(name=None, public=False, limit=None, offset=None): + count = None if name: - drinks = Drink.query.filter(Drink.name.contains(name)).all() - drinks = Drink.query.all() + query = Drink.query.filter(Drink.name.contains(name)) + else: + query = Drink.query + + if limit is not None: + count = query.count() + query = query.limit(limit) + if offset is not None: + query = query.offset(offset) + drinks = query.all() if public: - return [_create_public_drink(drink) for drink in drinks if _create_public_drink(drink)] - return drinks + return [_create_public_drink(drink) for drink in drinks if _create_public_drink(drink)], count + return drinks, count def get_drink(identifier, public=False): @@ -209,6 +218,9 @@ def set_volumes(volumes): def delete_drink(identifier): drink = get_drink(identifier) + if drink.uuid: + path = config["pricelist"]["path"] + delete_picture(f"{path}/{drink.uuid}") db.session.delete(drink) db.session.commit() -- 2.40.1 From 8fb74358e7d69048e2e95bd15ab25b1d5cc7e19f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Sat, 13 Nov 2021 13:23:04 +0100 Subject: [PATCH 3/8] [pricelist] add serverside filtering for getDrinks --- flaschengeist/plugins/pricelist/__init__.py | 6 +++++- .../plugins/pricelist/pricelist_controller.py | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index 67c92db..3e4c71b 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -218,6 +218,8 @@ def get_drinks(identifier=None): 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") try: if limit is not None: limit = int(limit) @@ -225,7 +227,9 @@ def get_drinks(identifier=None): offset = int(offset) except ValueError: raise BadRequest - drinks, count = pricelist_controller.get_drinks(public=public, limit=limit, offset=offset) + drinks, count = pricelist_controller.get_drinks( + public=public, limit=limit, offset=offset, search_name=search_name, search_key=search_key + ) logger.debug(f"GET drink {drinks}, {count}") # return jsonify({"drinks": drinks, "count": count}) return jsonify({"drinks": drinks, "count": count}) diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index 6ea9b87..5f8154c 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -131,12 +131,28 @@ def _create_public_drink(drink): return None -def get_drinks(name=None, public=False, limit=None, offset=None): +def get_drinks(name=None, public=False, limit=None, offset=None, search_name=None, search_key=None): count = None if name: query = Drink.query.filter(Drink.name.contains(name)) else: query = Drink.query + if search_name: + if search_key == "name": + query = query.filter(Drink.name.contains(search_name)) + elif search_key == "article_id": + query = query.filter(Drink.article_id.contains(search_name)) + elif search_key == "drink_type": + query = query.filter(Drink.type.has(DrinkType.name.contains(search_name))) + elif search_key == "tags": + query = query.filter(Drink.tags.any(Tag.name.contains(search_name))) + else: + query = query.filter( + (Drink.name.contains(search_name)) + | (Drink.article_id.contains(search_name)) + | (Drink.type.has(DrinkType.name.contains(search_name))) + | (Drink.tags.any(Tag.name.contains(search_name))) + ) if limit is not None: count = query.count() -- 2.40.1 From 526433afba948776550cde73ef61aacf366da75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Sat, 13 Nov 2021 15:03:21 +0100 Subject: [PATCH 4/8] [pricelist] serviceside filtering for ingredients --- flaschengeist/plugins/pricelist/__init__.py | 10 +++++++++- .../plugins/pricelist/pricelist_controller.py | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index 3e4c71b..2239727 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -220,15 +220,23 @@ def get_drinks(identifier=None): 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) 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) except ValueError: raise BadRequest drinks, count = pricelist_controller.get_drinks( - public=public, limit=limit, offset=offset, search_name=search_name, search_key=search_key + public=public, + limit=limit, + offset=offset, + search_name=search_name, + search_key=search_key, + ingredient=ingredient, ) logger.debug(f"GET drink {drinks}, {count}") # return jsonify({"drinks": drinks, "count": count}) diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index 5f8154c..b32a26d 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -131,12 +131,14 @@ def _create_public_drink(drink): return None -def get_drinks(name=None, public=False, limit=None, offset=None, search_name=None, search_key=None): +def get_drinks(name=None, public=False, limit=None, offset=None, search_name=None, search_key=None, ingredient=False): count = None if name: query = Drink.query.filter(Drink.name.contains(name)) else: query = Drink.query + if ingredient: + query = query.filter(Drink.cost_per_volume >= 0) if search_name: if search_key == "name": query = query.filter(Drink.name.contains(search_name)) -- 2.40.1 From e4b937991be4b363c9dd0cc34096bc6cc08b2842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Sat, 13 Nov 2021 15:44:06 +0100 Subject: [PATCH 5/8] [pricelist] add serverside pagination and filter for receipts --- flaschengeist/plugins/pricelist/__init__.py | 4 ++++ flaschengeist/plugins/pricelist/pricelist_controller.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index 2239727..5ad57af 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -221,6 +221,7 @@ def get_drinks(identifier=None): 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) @@ -228,6 +229,8 @@ def get_drinks(identifier=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( @@ -237,6 +240,7 @@ def get_drinks(identifier=None): search_name=search_name, search_key=search_key, ingredient=ingredient, + receipt=receipt, ) logger.debug(f"GET drink {drinks}, {count}") # return jsonify({"drinks": drinks, "count": count}) diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index b32a26d..0b786a9 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -131,7 +131,9 @@ def _create_public_drink(drink): return None -def get_drinks(name=None, public=False, limit=None, offset=None, search_name=None, search_key=None, ingredient=False): +def get_drinks( + name=None, public=False, limit=None, offset=None, search_name=None, search_key=None, ingredient=False, receipt=None +): count = None if name: query = Drink.query.filter(Drink.name.contains(name)) @@ -139,6 +141,8 @@ def get_drinks(name=None, public=False, limit=None, offset=None, search_name=Non query = Drink.query if ingredient: query = query.filter(Drink.cost_per_volume >= 0) + if receipt: + query = query.filter(Drink.volumes.any(DrinkPriceVolume.ingredients != None)) if search_name: if search_key == "name": query = query.filter(Drink.name.contains(search_name)) -- 2.40.1 From 1bb7bafa2a69793da05b29f7aa384253e0b5c2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Sat, 13 Nov 2021 15:57:49 +0100 Subject: [PATCH 6/8] [pricelist][fix] better query to send drinks with public prices --- flaschengeist/plugins/pricelist/pricelist_controller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index 0b786a9..3a441f3 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -143,6 +143,8 @@ def get_drinks( query = query.filter(Drink.cost_per_volume >= 0) if receipt: query = query.filter(Drink.volumes.any(DrinkPriceVolume.ingredients != None)) + if public: + query = query.filter(Drink.volumes.any(DrinkPriceVolume.prices.any(DrinkPrice.public))) if search_name: if search_key == "name": query = query.filter(Drink.name.contains(search_name)) @@ -166,8 +168,6 @@ def get_drinks( if offset is not None: query = query.offset(offset) drinks = query.all() - if public: - return [_create_public_drink(drink) for drink in drinks if _create_public_drink(drink)], count return drinks, count -- 2.40.1 From dba60fdab8ce40c6449d50f274d19026a5a2e8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Sun, 14 Nov 2021 19:35:11 +0100 Subject: [PATCH 7/8] [pricelist] serverside pagination and filtering for pricelist --- flaschengeist/plugins/pricelist/__init__.py | 40 ++++++++++ flaschengeist/plugins/pricelist/models.py | 16 +++- .../plugins/pricelist/pricelist_controller.py | 80 +++++++++++++++++-- 3 files changed, 127 insertions(+), 9 deletions(-) diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index 5ad57af..68693e8 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -242,11 +242,51 @@ def get_drinks(identifier=None): 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}) +@PriceListPlugin.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) + 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 + pricelist, count = pricelist_controller.get_pricelist( + public=public, limit=limit, offset=offset, search_name=search_name, search_key=search_key + ) + logger.debug(f"GET pricelist {pricelist}, {count}") + return jsonify({"pricelist": pricelist, "count": count}) + + @PriceListPlugin.blueprint.route("/drinks/search/", methods=["GET"]) def search_drinks(name): """Search Drink diff --git a/flaschengeist/plugins/pricelist/models.py b/flaschengeist/plugins/pricelist/models.py index f6d68f9..43cf792 100644 --- a/flaschengeist/plugins/pricelist/models.py +++ b/flaschengeist/plugins/pricelist/models.py @@ -48,7 +48,8 @@ class DrinkPrice(db.Model, ModelSerializeMixin): id: int = db.Column("id", db.Integer, primary_key=True) price: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False)) volume_id_ = db.Column("volume_id", db.Integer, db.ForeignKey("drink_price_volume.id")) - volume = db.relationship("DrinkPriceVolume", back_populates="prices") + volume: "DrinkPriceVolume" = None + _volume: "DrinkPriceVolume" = db.relationship("DrinkPriceVolume", back_populates="_prices", join_depth=1) public: bool = db.Column(db.Boolean, default=True) description: Optional[str] = db.Column(db.String(30)) @@ -121,11 +122,15 @@ class DrinkPriceVolume(db.Model, ModelSerializeMixin): __tablename__ = "drink_price_volume" id: int = db.Column("id", db.Integer, primary_key=True) drink_id = db.Column(db.Integer, db.ForeignKey("drink.id")) + drink: "Drink" = None + _drink: "Drink" = db.relationship("Drink", back_populates="_volumes") volume: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False)) min_prices: list[MinPrices] = [] # ingredients: list[Ingredient] = [] - - prices: list[DrinkPrice] = db.relationship(DrinkPrice, back_populates="volume", cascade="all,delete,delete-orphan") + prices: list[DrinkPrice] = [] + _prices: list[DrinkPrice] = db.relationship( + DrinkPrice, back_populates="_volume", cascade="all,delete,delete-orphan" + ) ingredients: list[Ingredient] = db.relationship("Ingredient", foreign_keys=Ingredient.volume_id) def __repr__(self): @@ -153,7 +158,10 @@ class Drink(db.Model, ModelSerializeMixin): tags: Optional[list[Tag]] = db.relationship("Tag", secondary=drink_tag_association, cascade="save-update, merge") type: Optional[DrinkType] = db.relationship("DrinkType", foreign_keys=[_type_id]) - volumes: list[DrinkPriceVolume] = db.relationship(DrinkPriceVolume) + volumes: list[DrinkPriceVolume] = [] + _volumes: list[DrinkPriceVolume] = db.relationship( + DrinkPriceVolume, back_populates="_drink", cascade="all,delete,delete-orphan" + ) def __repr__(self): return f"Drink({self.id},{self.name},{self.volumes})" diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index 3a441f3..1c5ac35 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -142,9 +142,9 @@ def get_drinks( if ingredient: query = query.filter(Drink.cost_per_volume >= 0) if receipt: - query = query.filter(Drink.volumes.any(DrinkPriceVolume.ingredients != None)) + query = query.filter(Drink._volumes.any(DrinkPriceVolume.ingredients != None)) if public: - query = query.filter(Drink.volumes.any(DrinkPriceVolume.prices.any(DrinkPrice.public))) + query = query.filter(Drink._volumes.any(DrinkPriceVolume._prices.any(DrinkPrice.public))) if search_name: if search_key == "name": query = query.filter(Drink.name.contains(search_name)) @@ -168,9 +168,72 @@ def get_drinks( if offset is not None: query = query.offset(offset) drinks = query.all() + for drink in drinks: + for volume in drink._volumes: + volume.prices = volume._prices + drink.volumes = drink._volumes + return drinks, count +def get_pricelist(public=False, limit=None, offset=None, search_name=None, search_key=None): + count = None + query = DrinkPrice.query + if public: + query.filter(DrinkPrice.public) + if search_name: + if search_key == "name": + query = query.filter(DrinkPrice._volume.has(DrinkPriceVolume._drink.has(Drink.name.contains(search_name)))) + if search_key == "type": + query = query.filter( + DrinkPrice._volume.has( + DrinkPriceVolume._drink.has(Drink.type.has(DrinkType.name.contains(search_name))) + ) + ) + if search_key == "tags": + query = query.filter( + DrinkPrice._volume.has(DrinkPriceVolume._drink.has(Drink.tags.any(Tag.name.conaitns(search_name)))) + ) + if search_key == "volume": + query = query.filter(DrinkPrice._volume.has(DrinkPriceVolume.volume == float(search_name))) + if search_key == "price": + query = query.filter(DrinkPrice.price == float(search_name)) + if search_key == "description": + query = query.filter(DrinkPrice.description.contains(search_name)) + else: + try: + search_name = float(search_name) + query = query.filter( + (DrinkPrice._volume.has(DrinkPriceVolume.volume == float(search_name))) + | (DrinkPrice.price == float(search_name)) + ) + except: + query = query.filter( + (DrinkPrice._volume.has(DrinkPriceVolume._drink.has(Drink.name.contains(search_name)))) + | ( + DrinkPrice._volume.has( + DrinkPriceVolume._drink.has(Drink.type.has(DrinkType.name.contains(search_name))) + ) + ) + | ( + DrinkPrice._volume.has( + DrinkPriceVolume._drink.has(Drink.tags.any(Tag.name.conaitns(search_name))) + ) + ) + | (DrinkPrice.description.contains(search_name)) + ) + if limit is not None: + count = query.count() + query = query.limit(limit) + if offset is not None: + query = query.offset(offset) + prices = query.all() + for price in prices: + price._volume.drink = price._volume._drink + price.volume = price._volume + return prices, count + + def get_drink(identifier, public=False): drink = None if isinstance(identifier, int): @@ -183,6 +246,9 @@ def get_drink(identifier, public=False): raise NotFound if public: return _create_public_drink(drink) + for volume in drink._volumes: + volume.prices = volume._prices + drink.volumes = drink._volumes return drink @@ -219,11 +285,15 @@ def update_drink(identifier, data): if drink_type: drink.type = drink_type if volumes is not None and session.user_.has_permission(EDIT_VOLUME): - drink.volumes = [] - drink.volumes = set_volumes(volumes) + drink._volumes = [] + drink._volumes = set_volumes(volumes) if len(tags) > 0: drink.tags = tags db.session.commit() + for volume in drink._volumes: + volume.prices = volume._prices + drink.volumes = drink._volumes + return drink except (NotFound, KeyError): raise BadRequest @@ -291,7 +361,7 @@ def set_prices(prices, volume): for _price in prices: price = set_price(_price) _prices.append(price) - volume.prices = _prices + volume._prices = _prices def set_ingredients(ingredients, volume): -- 2.40.1 From 57a03a80cc0e2f2b503840972aac6645c4813fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Mon, 15 Nov 2021 09:19:50 +0100 Subject: [PATCH 8/8] [pricelist] add serverside sorting for pricelist, sorting by name for drinks --- flaschengeist/plugins/pricelist/__init__.py | 12 +++++++- .../plugins/pricelist/pricelist_controller.py | 29 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/flaschengeist/plugins/pricelist/__init__.py b/flaschengeist/plugins/pricelist/__init__.py index 68693e8..afe21e4 100644 --- a/flaschengeist/plugins/pricelist/__init__.py +++ b/flaschengeist/plugins/pricelist/__init__.py @@ -269,6 +269,8 @@ def get_pricelist(): 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) @@ -278,10 +280,18 @@ def get_pricelist(): 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 + 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}) diff --git a/flaschengeist/plugins/pricelist/pricelist_controller.py b/flaschengeist/plugins/pricelist/pricelist_controller.py index 1c5ac35..136711c 100644 --- a/flaschengeist/plugins/pricelist/pricelist_controller.py +++ b/flaschengeist/plugins/pricelist/pricelist_controller.py @@ -161,6 +161,7 @@ def get_drinks( | (Drink.type.has(DrinkType.name.contains(search_name))) | (Drink.tags.any(Tag.name.contains(search_name))) ) + query = query.order_by(Drink.name.asc()) if limit is not None: count = query.count() @@ -176,11 +177,13 @@ def get_drinks( return drinks, count -def get_pricelist(public=False, limit=None, offset=None, search_name=None, search_key=None): +def get_pricelist( + public=False, limit=None, offset=None, search_name=None, search_key=None, sortBy=None, descending=False +): count = None query = DrinkPrice.query if public: - query.filter(DrinkPrice.public) + query = query.filter(DrinkPrice.public) if search_name: if search_key == "name": query = query.filter(DrinkPrice._volume.has(DrinkPriceVolume._drink.has(Drink.name.contains(search_name)))) @@ -217,16 +220,36 @@ def get_pricelist(public=False, limit=None, offset=None, search_name=None, searc ) | ( DrinkPrice._volume.has( - DrinkPriceVolume._drink.has(Drink.tags.any(Tag.name.conaitns(search_name))) + DrinkPriceVolume._drink.has(Drink.tags.any(Tag.name.contains(search_name))) ) ) | (DrinkPrice.description.contains(search_name)) ) + if sortBy == "type": + query = ( + query.join(DrinkPrice._volume) + .join(DrinkPriceVolume._drink) + .join(Drink.type) + .order_by(DrinkType.name.desc() if descending else DrinkType.name.asc()) + ) + elif sortBy == "volume": + query = query.join(DrinkPrice._volume).order_by( + DrinkPriceVolume.volume.desc() if descending else DrinkPriceVolume.volume.asc() + ) + elif sortBy == "price": + query = query.order_by(DrinkPrice.price.desc() if descending else DrinkPrice.price.asc()) + else: + query = ( + query.join(DrinkPrice._volume) + .join(DrinkPriceVolume._drink) + .order_by(Drink.name.desc() if descending else Drink.name.asc()) + ) if limit is not None: count = query.count() query = query.limit(limit) if offset is not None: query = query.offset(offset) + prices = query.all() for price in prices: price._volume.drink = price._volume._drink -- 2.40.1