bugfix: Invoice details
This commit is contained in:
@@ -19,6 +19,10 @@ class InvoiceContext:
|
||||
complete_invoices: dict[str, Any] | None = None
|
||||
billing_analysis: dict[str, Any] | None = None
|
||||
invoice_detail: Any = None
|
||||
invoice_amount: str = ""
|
||||
invoice_amount_open: str = ""
|
||||
invoice_period: str = ""
|
||||
invoice_emissao: str = ""
|
||||
customer_id: str = ""
|
||||
error: str | None = None
|
||||
cache_hit: bool = False
|
||||
@@ -33,6 +37,10 @@ class InvoiceContext:
|
||||
"complete_invoices_payload": self.complete_invoices,
|
||||
"billing_analysis": self.billing_analysis,
|
||||
"invoice_detail": self.invoice_detail,
|
||||
"invoice_amount": self.invoice_amount,
|
||||
"invoice_amount_open": self.invoice_amount_open,
|
||||
"invoice_period": self.invoice_period,
|
||||
"invoice_emissao": self.invoice_emissao,
|
||||
"customer_id": self.customer_id,
|
||||
"invoice_context_error": self.error,
|
||||
"invoice_context_cache_hit": self.cache_hit,
|
||||
@@ -42,6 +50,55 @@ class InvoiceContext:
|
||||
}
|
||||
|
||||
|
||||
def extract_invoice_summary_context(detail: Any) -> dict[str, str]:
|
||||
"""Extrai o resumo semântico da fatura detalhada.
|
||||
|
||||
Mantém a paridade com o prefetch do Contas original: ``bill_pdf`` devolve
|
||||
um envelope com ``parsed_content`` e o parser coloca o total em
|
||||
``total_geral``. Workflows e agentes não precisam conhecer a estrutura do
|
||||
PDF para consumir ``invoice_amount``/``invoice_amount_open``.
|
||||
"""
|
||||
parsed = detail
|
||||
if isinstance(detail, dict) and isinstance(detail.get("parsed_content"), dict):
|
||||
parsed = detail["parsed_content"]
|
||||
if not isinstance(parsed, dict):
|
||||
return {}
|
||||
|
||||
resumo = parsed.get("Fatura Resumo")
|
||||
if not isinstance(resumo, list):
|
||||
resumo = []
|
||||
|
||||
invoice_period = ""
|
||||
invoice_emissao = ""
|
||||
invoice_amount = ""
|
||||
parsed_total = parsed.get("total_geral")
|
||||
if parsed_total is not None and str(parsed_total).strip():
|
||||
invoice_amount = str(parsed_total).strip()
|
||||
|
||||
for item in resumo:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
desc = str(item.get("desc", "") or "").strip().casefold()
|
||||
if desc in {"período", "periodo"}:
|
||||
invoice_period = str(item.get("period", "") or "").strip()
|
||||
elif desc in {"emissão", "emissao"}:
|
||||
invoice_emissao = str(item.get("emissao", "") or "").strip()
|
||||
if not invoice_amount and bool(item.get("is_total")) and str(item.get("value", "")).strip():
|
||||
invoice_amount = str(item.get("value", "")).strip()
|
||||
if not invoice_amount and "total" in desc and str(item.get("value", "")).strip():
|
||||
invoice_amount = str(item.get("value", "")).strip()
|
||||
|
||||
context: dict[str, str] = {}
|
||||
if invoice_period:
|
||||
context["invoice_period"] = invoice_period
|
||||
if invoice_emissao:
|
||||
context["invoice_emissao"] = invoice_emissao
|
||||
if invoice_amount:
|
||||
context["invoice_amount"] = invoice_amount
|
||||
context["invoice_amount_open"] = invoice_amount
|
||||
return context
|
||||
|
||||
|
||||
class InvoiceContextService:
|
||||
"""Session-scoped invoice prefetch backed by the framework cache.
|
||||
|
||||
@@ -155,6 +212,7 @@ class InvoiceContextService:
|
||||
|
||||
detail = None
|
||||
detail_ms = 0.0
|
||||
summary: dict[str, str] = {}
|
||||
if include_detail and resolved_invoice_id:
|
||||
detail, detail_error, detail_ms = await self._timed_to_thread(
|
||||
"invoice_detail", self.client.bill_pdf, msisdn, resolved_invoice_id, customer_id,
|
||||
@@ -163,6 +221,8 @@ class InvoiceContextService:
|
||||
if detail_error:
|
||||
errors["invoice_detail"] = detail_error
|
||||
error_parts.append(f"invoice_detail: {detail_error}")
|
||||
else:
|
||||
summary = extract_invoice_summary_context(detail)
|
||||
|
||||
metadata = {
|
||||
"cache_hit": False,
|
||||
@@ -177,7 +237,12 @@ class InvoiceContextService:
|
||||
msisdn=msisdn, invoice_id=resolved_invoice_id,
|
||||
complete_invoices=complete if isinstance(complete, dict) else None,
|
||||
billing_analysis=billing if isinstance(billing, dict) else None,
|
||||
invoice_detail=detail, customer_id=customer_id,
|
||||
invoice_detail=detail,
|
||||
invoice_amount=summary.get("invoice_amount", ""),
|
||||
invoice_amount_open=summary.get("invoice_amount_open", ""),
|
||||
invoice_period=summary.get("invoice_period", ""),
|
||||
invoice_emissao=summary.get("invoice_emissao", ""),
|
||||
customer_id=customer_id,
|
||||
error="; ".join(error_parts) or None, cache_hit=False, business_events=events, errors=errors, metadata=metadata,
|
||||
)
|
||||
|
||||
@@ -219,7 +284,10 @@ class InvoiceContextService:
|
||||
await self.cache.set(key, {
|
||||
"msisdn": ctx.msisdn, "invoice_id": ctx.invoice_id,
|
||||
"complete_invoices": ctx.complete_invoices, "billing_analysis": ctx.billing_analysis,
|
||||
"invoice_detail": ctx.invoice_detail, "customer_id": ctx.customer_id,
|
||||
"invoice_detail": ctx.invoice_detail,
|
||||
"invoice_amount": ctx.invoice_amount, "invoice_amount_open": ctx.invoice_amount_open,
|
||||
"invoice_period": ctx.invoice_period, "invoice_emissao": ctx.invoice_emissao,
|
||||
"customer_id": ctx.customer_id,
|
||||
"error": ctx.error, "cache_hit": False,
|
||||
"errors": dict(ctx.errors or {}), "metadata": dict(ctx.metadata or {}),
|
||||
"_fetched_at": time.time(),
|
||||
|
||||
Reference in New Issue
Block a user