Add /match-specific endpoint to match specific receipts by file IDs
This commit is contained in:
@@ -513,6 +513,90 @@ async def match_auto():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.post("/match-specific", response_model=MatchingResponse)
|
||||||
|
async def match_specific_receipts(file_ids: List[str]):
|
||||||
|
"""
|
||||||
|
Match specific receipts by their file IDs against all imported transactions.
|
||||||
|
|
||||||
|
This endpoint allows you to match one or more specific receipts instead of all processed receipts.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_ids: List of file IDs to match (e.g., ["file1", "file2"])
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if not stored_transactions:
|
||||||
|
raise HTTPException(status_code=400, detail="No transactions imported. Please upload CSV first.")
|
||||||
|
|
||||||
|
if not file_ids:
|
||||||
|
raise HTTPException(status_code=400, detail="No file IDs provided.")
|
||||||
|
|
||||||
|
# Convert stored transactions to Receipt/Transaction models
|
||||||
|
transactions = [
|
||||||
|
Transaction(
|
||||||
|
id=t["id"],
|
||||||
|
transaction_date=datetime.strptime(t["txn_date"], "%Y-%m-%d"),
|
||||||
|
amount=abs(t["amount"]),
|
||||||
|
vendor=t["payee_name"],
|
||||||
|
notes=t.get("memo", "")
|
||||||
|
) for t in stored_transactions
|
||||||
|
]
|
||||||
|
|
||||||
|
receipts = []
|
||||||
|
missing_files = []
|
||||||
|
|
||||||
|
for file_id in file_ids:
|
||||||
|
if file_id in processed_receipts:
|
||||||
|
receipt_data = processed_receipts[file_id]
|
||||||
|
if receipt_data.get("extraction_success"):
|
||||||
|
receipts.append(Receipt(
|
||||||
|
id=file_id,
|
||||||
|
file_name=receipt_data.get("filename", ""),
|
||||||
|
upload_date=receipt_data.get("upload_date", datetime.now()),
|
||||||
|
receipt_date=datetime.strptime(receipt_data.get("date", "2024-01-01"), "%Y-%m-%d"),
|
||||||
|
amount=receipt_data.get("total_amount", 0.0),
|
||||||
|
tax=receipt_data.get("tax_amount", 0.0),
|
||||||
|
vendor=receipt_data.get("vendor", ""),
|
||||||
|
category=receipt_data.get("category", "")
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
missing_files.append(f"{file_id} (not successfully processed)")
|
||||||
|
else:
|
||||||
|
missing_files.append(f"{file_id} (not found)")
|
||||||
|
|
||||||
|
if missing_files:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail=f"Some files not found or not processed: {', '.join(missing_files)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not receipts:
|
||||||
|
raise HTTPException(status_code=400, detail="No successfully processed receipts found for the provided file IDs.")
|
||||||
|
|
||||||
|
# Process matching using AI engine
|
||||||
|
matches = matching_engine.process_matching(receipts, transactions)
|
||||||
|
|
||||||
|
# Convert to response format
|
||||||
|
match_responses = [
|
||||||
|
MatchResponse(
|
||||||
|
receipt_id=match.receipt.id,
|
||||||
|
transaction_id=match.transaction.id,
|
||||||
|
confidence_score=match.confidence_score,
|
||||||
|
match_reason=match.match_reason,
|
||||||
|
receipt_vendor=match.receipt.vendor,
|
||||||
|
receipt_amount=match.receipt.amount,
|
||||||
|
transaction_vendor=match.transaction.vendor,
|
||||||
|
transaction_amount=match.transaction.amount
|
||||||
|
) for match in matches
|
||||||
|
]
|
||||||
|
|
||||||
|
# Get statistics
|
||||||
|
stats = matching_engine.get_matching_stats(matches)
|
||||||
|
|
||||||
|
return MatchingResponse(matches=match_responses, stats=stats)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
@app.post("/approve")
|
@app.post("/approve")
|
||||||
async def approve_match(request: ApprovalRequest):
|
async def approve_match(request: ApprovalRequest):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user