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: | ||||
|         result = pricelist_controller.get_drink(identifier, public=public) | ||||
|     else: | ||||
|         result = pricelist_controller.get_drinks(public=public) | ||||
|     logger.debug(f"GET drink {result}") | ||||
|         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}) | ||||
| 
 | ||||
| 
 | ||||
| @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"]) | ||||
|  |  | |||
|  | @ -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)) | ||||
| 
 | ||||
|  | @ -76,16 +77,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): | ||||
|  | @ -120,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): | ||||
|  | @ -152,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})" | ||||
|  |  | |||
|  | @ -131,13 +131,130 @@ 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, search_name=None, search_key=None, ingredient=False, receipt=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 ingredient: | ||||
|         query = query.filter(Drink.cost_per_volume >= 0) | ||||
|     if receipt: | ||||
|         query = query.filter(Drink._volumes.any(DrinkPriceVolume.ingredients != None)) | ||||
|     if public: | ||||
|         return [_create_public_drink(drink) for drink in drinks if _create_public_drink(drink)] | ||||
|     return drinks | ||||
|         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)) | ||||
|         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): | ||||
|  | @ -152,6 +269,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 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -188,11 +308,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 | ||||
|  | @ -209,6 +333,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() | ||||
| 
 | ||||
|  | @ -257,7 +384,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): | ||||
|  | @ -315,6 +442,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) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue