Add AI rules support for document processing and matching; enhance tax analysis with flag_for_review and auto_approve fields

This commit is contained in:
bolade
2025-10-08 00:12:09 +01:00
parent f582110674
commit 2e020437a8
5 changed files with 394 additions and 49 deletions
+36 -3
View File
@@ -378,8 +378,11 @@ async def process_document(
This endpoint uses AI to extract structured data from receipt images,
including vendor, amount, date, and category information.
Optionally accepts user_location to guide tax calculations and depreciation
based on the user's location (format: "State/Province, Country" e.g., "Ontario, Canada").
Optionally accepts:
- user_location: Guide tax calculations and depreciation based on location
(format: "State/Province, Country" e.g., "Ontario, Canada")
- ai_rules: Custom categorization rules to override default logic
(e.g., [{"condition": "vendor is Starbucks", "action": "Food"}])
"""
try:
# Get file info from database
@@ -387,11 +390,20 @@ async def process_document(
if not db_uploaded_file:
raise HTTPException(status_code=404, detail=f"File {file_id} not found")
# Convert ai_rules from Pydantic models to dictionaries if provided
ai_rules_list = None
if request.ai_rules:
ai_rules_list = [
{"condition": rule.condition, "action": rule.action}
for rule in request.ai_rules
]
# Process the file using the stored file path
receipt_data = await document_processor.process_file(
db_uploaded_file.file_path,
db_uploaded_file.file_type,
user_location=request.user_location,
ai_rules=ai_rules_list,
)
# Parse date for database storage
@@ -570,9 +582,21 @@ async def match_specific_receipts(request: MatchSpecificRequest, db: db_dependen
else:
logger.info(f"Using default/provided user_location: {user_location}")
# Convert ai_rules from Pydantic models to dictionaries if provided
ai_rules_list = None
if request.ai_rules:
ai_rules_list = [
{"condition": rule.condition, "action": rule.action}
for rule in request.ai_rules
]
logger.info(f"Applying {len(ai_rules_list)} custom AI rules to matching")
try:
matching_results = matching_engine.process_matching(
receipts, transactions, user_location=user_location
receipts,
transactions,
user_location=user_location,
ai_rules=ai_rules_list,
)
logger.info(f"Matching completed, got {len(matching_results)} results")
@@ -584,6 +608,13 @@ async def match_specific_receipts(request: MatchSpecificRequest, db: db_dependen
# if result.tax_analysis and "final_tax_amount" in result.tax_analysis:
# final_tax = result.tax_analysis["final_tax_amount"]
# Extract flag_for_review and auto_approve from tax_analysis if available
flag_for_review = None
auto_approve = None
if result.tax_analysis:
flag_for_review = result.tax_analysis.get("flag_for_review")
auto_approve = result.tax_analysis.get("auto_approve")
match_response = MatchResponse(
receipt_id=result.receipt.id,
transaction_id=result.transaction.id
@@ -603,6 +634,8 @@ async def match_specific_receipts(request: MatchSpecificRequest, db: db_dependen
if result.transaction
else 0.0,
tax_analysis=result.tax_analysis,
flag_for_review=flag_for_review,
auto_approve=auto_approve,
)
match_responses.append(match_response)