Implement code changes to enhance functionality and improve performance
This commit is contained in:
@@ -132,6 +132,9 @@ class LLMTaxAnalyzer:
|
||||
logger.info(
|
||||
f"Completed batch tax analysis, enhanced {len(enhanced_matches)} matches"
|
||||
)
|
||||
# logger.info(
|
||||
# f"\n\n\nFinal batch enhanced matches: {enhanced_matches}"
|
||||
# )
|
||||
return enhanced_matches
|
||||
|
||||
def _process_matches_individually(self, matches: list, user_location: str) -> list:
|
||||
@@ -218,7 +221,6 @@ class LLMTaxAnalyzer:
|
||||
RECEIPT DETAILS:
|
||||
- Vendor: {receipt.vendor}
|
||||
- Amount: ${receipt.amount:.2f}
|
||||
- Tax: ${receipt.tax:.2f}
|
||||
- Currency: {receipt.currency}
|
||||
- Date: {receipt.receipt_date.strftime("%Y-%m-%d")}
|
||||
- Category: {receipt.category}
|
||||
@@ -322,7 +324,8 @@ CCA DEPRECIATION RATES BY ASSET CLASS:
|
||||
"""Get tax rule analysis from LLM"""
|
||||
|
||||
prompt = f"""
|
||||
You are a Canadian tax expert analyzing a receipt-transaction match. Apply the following tax rules intelligently:
|
||||
You are a tax expert analyzing a receipt-transaction match. Apply the following tax rules intelligently:
|
||||
And you are to calculate the tax for the receipt based on the context provided.
|
||||
|
||||
{context}
|
||||
|
||||
@@ -437,16 +440,23 @@ b) **CCA Depreciation** (for tax purposes - Canada):
|
||||
|
||||
Provide a structured JSON response with the following format:
|
||||
|
||||
**CRITICAL INSTRUCTION FOR final_tax_amount:**
|
||||
- This field MUST contain ONLY the calculated sales tax amount in dollars
|
||||
- This is NOT the total amount including tax
|
||||
- This is ONLY the tax portion (HST/GST/PST/QST)
|
||||
- Example: If receipt total is $100 and calculated tax is $13, return 13.00 (not 113.00)
|
||||
- For meals & entertainment: Return the FULL calculated tax amount (not the 50% adjusted amount)
|
||||
|
||||
{{
|
||||
"final_tax_amount": XX.XX,
|
||||
"final_tax_amount": XX.XX, // ONLY the calculated tax amount (e.g., 13.00 for $100 + $13 HST)
|
||||
"sales_tax": {{
|
||||
"applicable_province": "XX",
|
||||
"applicable_rate": 0.XX,
|
||||
"tax_name": "HST/GST/PST/QST",
|
||||
"calculated_tax": XX.XX,
|
||||
"calculated_tax": XX.XX, // This should match final_tax_amount above
|
||||
"stated_tax": XX.XX,
|
||||
"discrepancy": XX.XX,
|
||||
"reason": "Detailed explanation: which address used (billing/shipping), why this location, which scenario applies",
|
||||
"reason": "Detailed explanation",
|
||||
"requires_review": true/false
|
||||
}},
|
||||
"foreign_exchange": {{
|
||||
@@ -638,7 +648,6 @@ MATCH {i} (ID: match_{i}):
|
||||
Receipt Details:
|
||||
- Vendor: {receipt.vendor}
|
||||
- Amount: ${receipt.amount:.2f}
|
||||
- Tax: ${receipt.tax:.2f}
|
||||
- Currency: {receipt.currency}
|
||||
- Date: {receipt.receipt_date.strftime("%Y-%m-%d")}
|
||||
- Category: {receipt.category}
|
||||
@@ -679,13 +688,11 @@ CCA DEPRECIATION RATES BY ASSET CLASS:
|
||||
"""
|
||||
return context
|
||||
|
||||
def _get_llm_tax_analysis_batch(
|
||||
self, context: str, num_matches: int
|
||||
) -> Dict[str, Any]:
|
||||
def _get_llm_tax_analysis_batch(self, context: str, num_matches: int) -> Dict[str, Any]:
|
||||
"""Get tax rule analysis from LLM for ALL matches in a single call"""
|
||||
|
||||
prompt = f"""
|
||||
You are a Canadian tax expert analyzing MULTIPLE receipt-transaction matches. Apply the following tax rules intelligently to EACH match.
|
||||
You are a Canadian tax expert analyzing MULTIPLE receipt-transaction matches.
|
||||
|
||||
{context}
|
||||
|
||||
@@ -747,13 +754,22 @@ c) User in Ontario, Receipt has NO address information:
|
||||
|
||||
=== YOUR TASK ===
|
||||
|
||||
Analyze EACH match (match_0, match_1, match_2, etc.) and return a JSON object where each key is the match ID (e.g., "match_0") and the value is the complete tax analysis for that match.
|
||||
Analyze EACH match and return a JSON object where each key is the match ID and the value is the complete tax analysis.
|
||||
|
||||
**CRITICAL INSTRUCTION FOR final_tax_amount:**
|
||||
- This field MUST contain ONLY the calculated sales tax amount in dollars
|
||||
- This is NOT the total amount including tax
|
||||
- This is ONLY the tax portion (HST/GST/PST/QST)
|
||||
- Example: If receipt total is $100 and calculated tax is $13, return 13.00 (not 113.00)
|
||||
- For meals & entertainment: Return the FULL calculated tax amount (not the 50% adjusted amount)
|
||||
- VERIFY: final_tax_amount should equal sales_tax.calculated_tax
|
||||
-
|
||||
|
||||
Return your response as a SINGLE JSON object in this format:
|
||||
|
||||
{{
|
||||
"match_0": {{
|
||||
"final_tax_amount": XX.XX,
|
||||
"final_tax_amount": XX.XX, // ONLY the calculated tax amount
|
||||
"sales_tax": {{
|
||||
"applicable_province": "XX",
|
||||
"applicable_rate": 0.XX,
|
||||
@@ -800,17 +816,7 @@ Return your response as a SINGLE JSON object in this format:
|
||||
}},
|
||||
... for all {num_matches} matches ...
|
||||
}}
|
||||
|
||||
**Critical Reminders**:
|
||||
- Sales tax uses RECEIPT location (or user location if receipt has none)
|
||||
- Depreciation ALWAYS uses USER location
|
||||
- For different addresses, use SHIPPING address for sales tax
|
||||
- International transactions: no Canadian tax + FX flag
|
||||
- Be precise with all calculations
|
||||
- Always explain your reasoning clearly
|
||||
- Return analysis for ALL {num_matches} matches
|
||||
"""
|
||||
|
||||
try:
|
||||
response = self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
@@ -902,9 +908,36 @@ Return your response as a SINGLE JSON object in this format:
|
||||
|
||||
def _apply_tax_analysis_to_match(self, match, tax_analysis: Dict[str, Any]):
|
||||
"""Apply tax analysis results to a match object"""
|
||||
|
||||
# Store the complete tax analysis
|
||||
|
||||
# **CRITICAL FIX: Ensure final_tax_amount matches calculated_tax**
|
||||
final_tax = tax_analysis.get("final_tax_amount", 0.0)
|
||||
calculated_tax = tax_analysis.get("sales_tax", {}).get("calculated_tax", 0.0)
|
||||
|
||||
# If there's a mismatch, use calculated_tax as the source of truth
|
||||
if abs(final_tax - calculated_tax) > 0.01:
|
||||
logger.warning(
|
||||
f"Correcting final_tax_amount mismatch for {match.receipt.vendor}: "
|
||||
f"LLM returned final_tax_amount={final_tax}, but calculated_tax={calculated_tax}. "
|
||||
f"Using calculated_tax as final value."
|
||||
)
|
||||
tax_analysis["final_tax_amount"] = calculated_tax
|
||||
|
||||
# Special case: If final_tax is 0 but calculated_tax > 0, always use calculated_tax
|
||||
if final_tax == 0.0 and calculated_tax > 0.0:
|
||||
logger.warning(
|
||||
f"Correcting zero final_tax_amount for {match.receipt.vendor}: "
|
||||
f"LLM returned 0 but calculated {calculated_tax} HST. Setting final_tax_amount={calculated_tax}"
|
||||
)
|
||||
tax_analysis["final_tax_amount"] = calculated_tax
|
||||
tax_analysis["sales_tax"]["requires_review"] = True
|
||||
|
||||
# Apply the corrected tax analysis
|
||||
match.tax_analysis = tax_analysis
|
||||
|
||||
logger.debug(
|
||||
f"Applied tax analysis to match: {match.receipt.vendor} -> "
|
||||
f"final_tax_amount={tax_analysis['final_tax_amount']}"
|
||||
)
|
||||
|
||||
# Apply confidence adjustments based on tax analysis
|
||||
confidence_adj = tax_analysis.get("confidence_adjustment", {})
|
||||
|
||||
Reference in New Issue
Block a user