invoice-system / app /services /invoice_processor.py
Sibi Krishnamoorthy
Add application file
c9ed90a
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import PydanticOutputParser
from app.api.models.invoice import InvoiceAnalysis, ReimbursementStatus
from app.core.config import settings
import uuid
from datetime import datetime
import json
class InvoiceProcessor:
def __init__(self):
self.llm = ChatOpenAI(
model_name=settings.LLM_MODEL_NAME,
temperature=0
)
self.parser = PydanticOutputParser(pydantic_object=InvoiceAnalysis)
self.analysis_prompt = ChatPromptTemplate.from_messages([
("system", """You are an expert at analyzing expense invoices against company reimbursement policies.
Your task is to analyze the given invoice against the provided policy and determine:
1. The reimbursement status (FULLY_REIMBURSED, PARTIALLY_REIMBURSED, or DECLINED)
2. The reimbursable amount
3. Detailed reasons for the decision
4. Any policy violations found
Policy:
{policy_text}
Invoice:
{invoice_text}
{format_instructions}
"""),
])
async def analyze_invoice(self, employee_name: str, policy_text: str, invoice_text: str) -> InvoiceAnalysis:
# Generate a unique invoice ID
invoice_id = str(uuid.uuid4())
# Prepare the prompt
prompt = self.analysis_prompt.format_messages(
policy_text=policy_text,
invoice_text=invoice_text,
format_instructions=self.parser.get_format_instructions()
)
# Get LLM response
response = await self.llm.ainvoke(prompt)
# Parse the response
try:
analysis = self.parser.parse(response.content)
# Ensure the invoice_id is set
analysis.invoice_id = invoice_id
analysis.employee_name = employee_name
return analysis
except Exception as e:
# If parsing fails, create a default analysis
return InvoiceAnalysis(
invoice_id=invoice_id,
employee_name=employee_name,
invoice_date=datetime.utcnow(),
total_amount=0.0,
reimbursable_amount=0.0,
status=ReimbursementStatus.DECLINED,
reason=f"Error analyzing invoice: {str(e)}",
policy_violations=["Failed to parse invoice"]
)