Invoice_Digitization_Agent / backend /ingest /ingest_invoice_sqlite.py
Dipan04's picture
Deploy Invoice Digitization Agent
8a859a8
Raw
History Blame Contribute Delete
5.34 kB
"""
Invoice ingestion helper for SQLite.
Handles insert/update with computed fields.
"""
import sqlite3
from datetime import datetime
from pathlib import Path
from typing import Dict, Optional
from filelock import FileLock
DB_PATH = Path(__file__).parent.parent.parent / "data" / "invoices.db"
LOCK_PATH = Path(__file__).parent.parent.parent / "data" / "invoices.db.lock"
def parse_date(date_input) -> Optional[str]:
"""Convert various date formats to ISO string."""
if not date_input:
return None
if isinstance(date_input, str):
# Try parsing common formats
for fmt in ["%Y-%m-%d %H:%M:%S", "%Y-%m-%d", "%Y%m%d"]:
try:
dt = datetime.strptime(date_input, fmt)
return dt.strftime("%Y-%m-%d %H:%M:%S")
except ValueError:
continue
return date_input # Return as-is if parsing fails
if isinstance(date_input, datetime):
return date_input.strftime("%Y-%m-%d %H:%M:%S")
return str(date_input)
def compute_days_diff(date1_str: Optional[str], date2_str: Optional[str]) -> Optional[int]:
"""Compute day difference between two ISO date strings."""
if not date1_str or not date2_str:
return None
try:
d1 = datetime.strptime(date1_str, "%Y-%m-%d %H:%M:%S")
d2 = datetime.strptime(date2_str, "%Y-%m-%d %H:%M:%S")
return (d1 - d2).days
except:
return None
def ingest_invoice(invoice_data: Dict) -> Dict:
"""
Insert or update invoice in SQLite with computed fields.
Args:
invoice_data: Dict with invoice fields
Returns:
Dict with status and invoice_id
"""
# Parse dates
posting_date = parse_date(invoice_data.get("posting_date"))
clear_date = parse_date(invoice_data.get("clear_date"))
due_in_date = parse_date(invoice_data.get("due_in_date"))
document_create_date = parse_date(invoice_data.get("document_create_date"))
baseline_create_date = parse_date(invoice_data.get("baseline_create_date"))
# Compute derived fields
days_to_clear = compute_days_diff(clear_date, posting_date) if clear_date else None
days_posting_to_due = compute_days_diff(due_in_date, posting_date)
days_create_to_posting = compute_days_diff(posting_date, document_create_date)
days_baseline_to_posting = compute_days_diff(posting_date, baseline_create_date)
is_open = 0 if clear_date else 1
is_overdue = 0
if clear_date and due_in_date:
try:
cd = datetime.strptime(clear_date, "%Y-%m-%d %H:%M:%S")
dd = datetime.strptime(due_in_date, "%Y-%m-%d %H:%M:%S")
is_overdue = 1 if cd > dd else 0
except:
pass
# Prepare data
invoice_id = invoice_data.get("invoice_id")
if not invoice_id:
raise ValueError("invoice_id is required")
# SQLite write with lock
with FileLock(str(LOCK_PATH)):
conn = sqlite3.connect(str(DB_PATH))
cursor = conn.cursor()
cursor.execute("""
INSERT OR REPLACE INTO invoices_history (
invoice_id, business_code, cust_number, name_customer,
posting_date, document_create_date, document_create_date_alt,
due_in_date, baseline_create_date, clear_date,
total_open_amount, invoice_currency, document_type,
cust_payment_terms, posting_id, business_year,
days_to_clear, days_posting_to_due, days_create_to_posting,
days_baseline_to_posting, is_overdue, is_open,
updated_at
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP
)
""", (
invoice_id,
invoice_data.get("business_code"),
invoice_data.get("cust_number"),
invoice_data.get("name_customer"),
posting_date,
document_create_date,
invoice_data.get("document_create_date_alt"),
due_in_date,
baseline_create_date,
clear_date,
invoice_data.get("total_open_amount"),
invoice_data.get("invoice_currency", "USD"),
invoice_data.get("document_type"),
invoice_data.get("cust_payment_terms"),
invoice_data.get("posting_id"),
invoice_data.get("business_year"),
days_to_clear,
days_posting_to_due,
days_create_to_posting,
days_baseline_to_posting,
is_overdue,
is_open
))
conn.commit()
conn.close()
return {
"status": "success",
"invoice_id": invoice_id,
"is_open": bool(is_open),
"days_to_clear": days_to_clear
}
if __name__ == "__main__":
# Test
test_invoice = {
"invoice_id": 12345,
"business_code": "U001",
"cust_number": "0200769623",
"name_customer": "Test Customer",
"posting_date": "2024-01-15",
"clear_date": "2024-02-01",
"due_in_date": "2024-01-30",
"total_open_amount": 50000.0,
"cust_payment_terms": "NAH4"
}
result = ingest_invoice(test_invoice)
print(result)