Spaces:
Sleeping
Sleeping
File size: 2,355 Bytes
c1b1f3a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | from typing import Dict, Any, Tuple, List
import re
from datetime import datetime
from pydantic import BaseModel, Field
class ValidationResult(BaseModel):
is_valid: bool
errors: List[str] = Field(default_factory=list)
confidence_penalty: float = 0.0
def validate_extracted_fields(doc_class: str, fields: Dict[str, Any]) -> ValidationResult:
"""
Validates extracted field values based on business rules:
- total_amount: numeric, > 0
- date / invoice_date: valid date pattern
- invoice_number: non-empty string
Returns ValidationResult with pass/fail and penalty.
"""
errors = []
penalty = 0.0
if doc_class in ["invoice", "receipt"]:
amount_val = fields.get("total_amount")
if amount_val is not None:
# Clean currency symbols and commas
cleaned_str = re.sub(r'[^\d.-]', '', str(amount_val).replace(',', ''))
try:
amt = float(cleaned_str)
if amt <= 0:
errors.append(f"total_amount must be positive: got {amt}")
penalty += 0.25
except ValueError:
errors.append(f"total_amount cannot be parsed as float: {amount_val}")
penalty += 0.35
date_val = fields.get("date") or fields.get("invoice_date")
if date_val is not None:
# Check standard date formats
valid_date = False
date_str = str(date_val).strip()
date_formats = ["%Y-%m-%d", "%d/%m/%Y", "%m/%d/%Y", "%d-%m-%Y", "%Y/%m/%d", "%b %d, %Y", "%d %b %Y"]
for fmt in date_formats:
try:
datetime.strptime(date_str, fmt)
valid_date = True
break
except ValueError:
pass
# Also check with date regex
if not valid_date and not re.search(r'\d{1,4}[/\-.]\d{1,2}[/\-.]\d{1,4}', date_str):
errors.append(f"date format unrecognized: {date_val}")
penalty += 0.2
if doc_class == "invoice":
inv_num = fields.get("invoice_number")
if inv_num is not None and not str(inv_num).strip():
errors.append("invoice_number is empty")
penalty += 0.3
is_valid = len(errors) == 0
return ValidationResult(is_valid=is_valid, errors=errors, confidence_penalty=min(penalty, 0.5))
|