Compare commits
	
		
			12 Commits
		
	
	
		
			1b371763ee
			...
			42e304cf5f
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 42e304cf5f | |
|  | 55278c8413 | |
|  | 57a03a80cc | |
|  | dba60fdab8 | |
|  | 1bb7bafa2a | |
|  | e4b937991b | |
|  | 526433afba | |
|  | 8fb74358e7 | |
|  | 26a00ed6a6 | |
|  | ff13eefb45 | |
|  | e7b978ae3c | |
|  | ff1a0544f8 | 
|  | @ -214,10 +214,87 @@ def get_drinks(identifier=None): | ||||||
| 
 | 
 | ||||||
|     if identifier: |     if identifier: | ||||||
|         result = pricelist_controller.get_drink(identifier, public=public) |         result = pricelist_controller.get_drink(identifier, public=public) | ||||||
|  |         return jsonify(result) | ||||||
|     else: |     else: | ||||||
|         result = pricelist_controller.get_drinks(public=public) |         limit = request.args.get("limit") | ||||||
|     logger.debug(f"GET drink {result}") |         offset = request.args.get("offset") | ||||||
|     return jsonify(result) |         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}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @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) | ||||||
|  |     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}) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @PriceListPlugin.blueprint.route("/drinks/search/<string:name>", methods=["GET"]) | @PriceListPlugin.blueprint.route("/drinks/search/<string:name>", methods=["GET"]) | ||||||
|  |  | ||||||
|  | @ -48,7 +48,8 @@ class DrinkPrice(db.Model, ModelSerializeMixin): | ||||||
|     id: int = db.Column("id", db.Integer, primary_key=True) |     id: int = db.Column("id", db.Integer, primary_key=True) | ||||||
|     price: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False)) |     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_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) |     public: bool = db.Column(db.Boolean, default=True) | ||||||
|     description: Optional[str] = db.Column(db.String(30)) |     description: Optional[str] = db.Column(db.String(30)) | ||||||
| 
 | 
 | ||||||
|  | @ -76,16 +77,17 @@ class DrinkIngredient(db.Model, ModelSerializeMixin): | ||||||
|     id: int = db.Column("id", db.Integer, primary_key=True) |     id: int = db.Column("id", db.Integer, primary_key=True) | ||||||
|     volume: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False), nullable=False) |     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")) |     ingredient_id: int = db.Column(db.Integer, db.ForeignKey("drink.id")) | ||||||
|     #    drink_ingredient: Drink = db.relationship("Drink") |     cost_per_volume: float | ||||||
|     # price: float = 0 |     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 |     @property | ||||||
| #    def price(self): |     def name(self): | ||||||
| #        try: |         return self._drink_ingredient.name if self._drink_ingredient else None | ||||||
| #            return self.drink_ingredient.cost_price_pro_volume * self.volume |  | ||||||
| #        except AttributeError: |  | ||||||
| #            pass |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Ingredient(db.Model, ModelSerializeMixin): | class Ingredient(db.Model, ModelSerializeMixin): | ||||||
|  | @ -120,11 +122,15 @@ class DrinkPriceVolume(db.Model, ModelSerializeMixin): | ||||||
|     __tablename__ = "drink_price_volume" |     __tablename__ = "drink_price_volume" | ||||||
|     id: int = db.Column("id", db.Integer, primary_key=True) |     id: int = db.Column("id", db.Integer, primary_key=True) | ||||||
|     drink_id = db.Column(db.Integer, db.ForeignKey("drink.id")) |     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)) |     volume: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False)) | ||||||
|     min_prices: list[MinPrices] = [] |     min_prices: list[MinPrices] = [] | ||||||
|     # ingredients: list[Ingredient] = [] |     # ingredients: list[Ingredient] = [] | ||||||
| 
 |     prices: list[DrinkPrice] = [] | ||||||
|     prices: list[DrinkPrice] = db.relationship(DrinkPrice, back_populates="volume", cascade="all,delete,delete-orphan") |     _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) |     ingredients: list[Ingredient] = db.relationship("Ingredient", foreign_keys=Ingredient.volume_id) | ||||||
| 
 | 
 | ||||||
|     def __repr__(self): |     def __repr__(self): | ||||||
|  | @ -152,7 +158,10 @@ class Drink(db.Model, ModelSerializeMixin): | ||||||
| 
 | 
 | ||||||
|     tags: Optional[list[Tag]] = db.relationship("Tag", secondary=drink_tag_association, cascade="save-update, merge") |     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]) |     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): |     def __repr__(self): | ||||||
|         return f"Drink({self.id},{self.name},{self.volumes})" |         return f"Drink({self.id},{self.name},{self.volumes})" | ||||||
|  |  | ||||||
|  | @ -131,13 +131,130 @@ def _create_public_drink(drink): | ||||||
|     return None |     return None | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_drinks(name=None, public=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: |     if name: | ||||||
|         drinks = Drink.query.filter(Drink.name.contains(name)).all() |         query = Drink.query.filter(Drink.name.contains(name)) | ||||||
|     drinks = Drink.query.all() |     else: | ||||||
|  |         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 public: |     if public: | ||||||
|         return [_create_public_drink(drink) for drink in drinks if _create_public_drink(drink)] |         query = query.filter(Drink._volumes.any(DrinkPriceVolume._prices.any(DrinkPrice.public))) | ||||||
|     return drinks |     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))) | ||||||
|  |             ) | ||||||
|  |     query = query.order_by(Drink.name.asc()) | ||||||
|  | 
 | ||||||
|  |     if limit is not None: | ||||||
|  |         count = query.count() | ||||||
|  |         query = query.limit(limit) | ||||||
|  |     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, sortBy=None, descending=False | ||||||
|  | ): | ||||||
|  |     count = None | ||||||
|  |     query = DrinkPrice.query | ||||||
|  |     if 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)))) | ||||||
|  |         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.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 | ||||||
|  |         price.volume = price._volume | ||||||
|  |     return prices, count | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_drink(identifier, public=False): | def get_drink(identifier, public=False): | ||||||
|  | @ -152,6 +269,9 @@ def get_drink(identifier, public=False): | ||||||
|         raise NotFound |         raise NotFound | ||||||
|     if public: |     if public: | ||||||
|         return _create_public_drink(drink) |         return _create_public_drink(drink) | ||||||
|  |     for volume in drink._volumes: | ||||||
|  |         volume.prices = volume._prices | ||||||
|  |     drink.volumes = drink._volumes | ||||||
|     return drink |     return drink | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -188,11 +308,15 @@ def update_drink(identifier, data): | ||||||
|         if drink_type: |         if drink_type: | ||||||
|             drink.type = drink_type |             drink.type = drink_type | ||||||
|         if volumes is not None and session.user_.has_permission(EDIT_VOLUME): |         if volumes is not None and session.user_.has_permission(EDIT_VOLUME): | ||||||
|             drink.volumes = [] |             drink._volumes = [] | ||||||
|             drink.volumes = set_volumes(volumes) |             drink._volumes = set_volumes(volumes) | ||||||
|         if len(tags) > 0: |         if len(tags) > 0: | ||||||
|             drink.tags = tags |             drink.tags = tags | ||||||
|         db.session.commit() |         db.session.commit() | ||||||
|  |         for volume in drink._volumes: | ||||||
|  |             volume.prices = volume._prices | ||||||
|  |         drink.volumes = drink._volumes | ||||||
|  | 
 | ||||||
|         return drink |         return drink | ||||||
|     except (NotFound, KeyError): |     except (NotFound, KeyError): | ||||||
|         raise BadRequest |         raise BadRequest | ||||||
|  | @ -209,6 +333,9 @@ def set_volumes(volumes): | ||||||
| 
 | 
 | ||||||
| def delete_drink(identifier): | def delete_drink(identifier): | ||||||
|     drink = get_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.delete(drink) | ||||||
|     db.session.commit() |     db.session.commit() | ||||||
| 
 | 
 | ||||||
|  | @ -257,7 +384,7 @@ def set_prices(prices, volume): | ||||||
|         for _price in prices: |         for _price in prices: | ||||||
|             price = set_price(_price) |             price = set_price(_price) | ||||||
|             _prices.append(price) |             _prices.append(price) | ||||||
|         volume.prices = _prices |         volume._prices = _prices | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def set_ingredients(ingredients, volume): | def set_ingredients(ingredients, volume): | ||||||
|  | @ -315,6 +442,10 @@ def delete_price(identifier): | ||||||
| def set_drink_ingredient(data): | def set_drink_ingredient(data): | ||||||
|     allowed_keys = DrinkIngredient().serialize().keys() |     allowed_keys = DrinkIngredient().serialize().keys() | ||||||
|     values = {key: value for key, value in data.items() if key in allowed_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) |     ingredient_id = values.pop("id", -1) | ||||||
|     if ingredient_id < 0: |     if ingredient_id < 0: | ||||||
|         drink_ingredient = DrinkIngredient(**values) |         drink_ingredient = DrinkIngredient(**values) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue