From 823c05f78dbbbb63b5cb2dcc148e6cf952497f64 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 5 Oct 2025 23:38:03 +0000 Subject: [PATCH] Implement code changes to enhance functionality and improve performance --- app/services/llm_tax_analyzer.py | 81 ++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/app/services/llm_tax_analyzer.py b/app/services/llm_tax_analyzer.py index 996fe9b..0bfa56f 100644 --- a/app/services/llm_tax_analyzer.py +++ b/app/services/llm_tax_analyzer.py @@ -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", {})