from abc import ABC, abstractmethod from loguru import logger class ImageProcessingInterface(ABC): @abstractmethod def process_image(self, image_base64: str, model_name: str, prompt: str, system: str, temperature: float): pass def _validate_receipt_data(self, json_content): """ Validates the receipt data to ensure required fields are correctly populated. :param json_content: The JSON content to validate :return: True if the required fields are valid, False otherwise """ if "total_price" not in json_content or json_content.get("total_price") == "unknown": return False if "items" not in json_content or not json_content.get("items"): return False return True def _add_total_price(self, json_content): """ Duplicates the value of 'total_price_without_discount' into 'total_price' for each item in the 'items' array. If 'total_price_without_discount' is missing or equals 'unknown', 'total_price' is set to "0.00". :param json_content: Dictionary containing the JSON data :return: Modified JSON content """ if "items" in json_content: for item in json_content["items"]: total_price_without_discount = item.get("total_price_without_discount") if total_price_without_discount and total_price_without_discount != "unknown": item["total_price"] = total_price_without_discount else: logger.warning( f"Item {item.get('name', 'unknown')} has missing or 'unknown' 'total_price_without_discount'. Setting 'total_price' to '0.00'.") item["total_price"] = "0.00" return json_content def _extract_float_value(self, json_content, key, default=0.0): try: return float(json_content.get(key, default)) except (ValueError, TypeError): logger.error(f"Invalid {key} value: {json_content.get(key)}") return default def _add_discount_item(self, json_content): """ Adds a new "Discount" item to the 'items' array if 'total_discount' is greater than 0. :param json_content: Dictionary containing the JSON data :return: Modified JSON content """ total_discount = self._extract_float_value(json_content, "total_discount", 0.0) all_items_price_with_tax = json_content.get("all_items_price_with_tax", "unknown") if total_discount > 0: discount_item = { "name": "Discount", "quantity": 1.0, "measurement_unit": "ks", "total_price_without_discount": -total_discount, "unit_price": -total_discount, "total_price_with_discount": -total_discount, "discount": 0.0, "category": "Discount", "item_price_with_tax": all_items_price_with_tax, "total_price": -total_discount } if "items" not in json_content: json_content["items"] = [] json_content["items"].append(discount_item) logger.info("Added 'Discount' item to the receipt.") return json_content def _add_rounding_item(self, json_content): """ Adds a new "Rounding" item to the 'items' array if 'rounding' is not zero. :param json_content: Dictionary containing the JSON data :return: Modified JSON content """ rounding = self._extract_float_value(json_content, "rounding", 0.0) if rounding != 0: all_items_price_with_tax = json_content.get("all_items_price_with_tax", "unknown") rounding_item = { "name": "Rounding", "quantity": 1.0, "measurement_unit": "ks", "total_price_without_discount": rounding, "unit_price": rounding, "total_price_with_discount": rounding, "discount": 0.0, "category": "Rounding", "item_price_with_tax": all_items_price_with_tax, "total_price": rounding } if "items" not in json_content: json_content["items"] = [] json_content["items"].append(rounding_item) logger.info("Added 'Rounding' item to the receipt.") return json_content