Connector calls, semantic rules, and DuckDB memory keep long runs stable, and stream retry stops chats from stalling. Co-authored-by: Cursor <cursoragent@cursor.com>
123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
"""Currency-safe amount reporting. Raw cross-currency sums are never produced."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from kamidso.native_connectors.semantic.catalog import load_bundle
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MoneySummary:
|
|
groups: List[Dict[str, Any]] = field(default_factory=list)
|
|
mixed: bool = False
|
|
combined_total: Optional[float] = None
|
|
currency_verified: bool = False
|
|
|
|
|
|
def _amount_fields() -> Dict[str, str]:
|
|
rules = load_bundle()["money"]
|
|
sources = rules.get("source_fields") if isinstance(rules.get("source_fields"), dict) else {}
|
|
policy = rules.get("amount_field_policy") if isinstance(rules.get("amount_field_policy"), dict) else {}
|
|
return {
|
|
"final": str(policy.get("default_record_amount") or "FinalAdjustmentPrice"),
|
|
"fallback": str(policy.get("fallback") or "Price"),
|
|
"currency": str(sources.get("currency_id") or "CurrencyId"),
|
|
}
|
|
|
|
|
|
def _as_amount(value: Any) -> Optional[float]:
|
|
if isinstance(value, bool) or value is None:
|
|
return None
|
|
if isinstance(value, (int, float)):
|
|
return float(value)
|
|
if isinstance(value, str):
|
|
text = value.strip().replace(",", "")
|
|
if not text:
|
|
return None
|
|
try:
|
|
return float(text)
|
|
except ValueError:
|
|
return None
|
|
return None
|
|
|
|
|
|
def _label(currency_id: str, currency_map: Dict[str, Any]) -> tuple:
|
|
mapped = currency_map.get(currency_id)
|
|
if isinstance(mapped, dict):
|
|
name = mapped.get("code") or mapped.get("name")
|
|
if name:
|
|
return str(name), True
|
|
if isinstance(mapped, str) and mapped.strip():
|
|
return mapped.strip(), True
|
|
shown = currency_id or "unknown"
|
|
return f"CurrencyId={shown}", False
|
|
|
|
|
|
def summarize_amounts(
|
|
records: List[Any],
|
|
calibration: Optional[Dict[str, Any]] = None,
|
|
) -> MoneySummary:
|
|
calibration = calibration or {}
|
|
fields = _amount_fields()
|
|
currency_map = calibration.get("currency_map")
|
|
if not isinstance(currency_map, dict):
|
|
currency_map = {}
|
|
buckets: Dict[str, float] = {}
|
|
order: List[str] = []
|
|
for record in records:
|
|
if not isinstance(record, dict):
|
|
continue
|
|
amount = _as_amount(record.get(fields["final"]))
|
|
if amount is None:
|
|
amount = _as_amount(record.get(fields["fallback"]))
|
|
if amount is None:
|
|
continue
|
|
currency = record.get(fields["currency"])
|
|
key = "" if currency is None else str(currency)
|
|
if key not in buckets:
|
|
order.append(key)
|
|
buckets[key] = 0.0
|
|
buckets[key] += amount
|
|
groups: List[Dict[str, Any]] = []
|
|
for key in order:
|
|
label, known = _label(key, currency_map)
|
|
groups.append(
|
|
{
|
|
"currency_id": key,
|
|
"label": label,
|
|
"amount": buckets[key],
|
|
"known": known,
|
|
}
|
|
)
|
|
mixed = len(groups) > 1
|
|
known_single = len(groups) == 1 and bool(groups[0]["known"])
|
|
verified = bool(calibration.get("dashboard_aggregate_currency_semantics_verified")) and known_single
|
|
combined = None if mixed or not groups else groups[0]["amount"]
|
|
return MoneySummary(
|
|
groups=groups,
|
|
mixed=mixed,
|
|
combined_total=combined,
|
|
currency_verified=verified,
|
|
)
|
|
|
|
|
|
def format_amount(value: float) -> str:
|
|
if float(value).is_integer():
|
|
return str(int(value))
|
|
return str(value)
|
|
|
|
|
|
def amount_lines(summary: MoneySummary) -> List[str]:
|
|
if not summary.groups:
|
|
return ["Amounts: none on the verified rows."]
|
|
if summary.mixed:
|
|
lines = ["Amounts by currency (not summed):"]
|
|
for group in summary.groups:
|
|
lines.append(f"- {group['label']}: {format_amount(group['amount'])}")
|
|
lines.append("These currency groups stay separate.")
|
|
return lines
|
|
group = summary.groups[0]
|
|
return [f"Amount: {group['label']} {format_amount(group['amount'])}"]
|