91 lines
3.5 KiB
Python
91 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
|
|
def _as_dict(value: Any) -> Dict[str, Any]:
|
|
return value if isinstance(value, dict) else {}
|
|
|
|
|
|
def _as_list(value: Any) -> List[Any]:
|
|
return value if isinstance(value, list) else []
|
|
|
|
|
|
def _value(value: Any) -> str:
|
|
return str(value or "").strip()
|
|
|
|
|
|
def _missing_label(field: Any) -> str:
|
|
raw = str(field or "").strip()
|
|
labels = {
|
|
"shipment.recipient_name": "Contacto no local",
|
|
"recipient_name": "Contacto no local",
|
|
"shipment.recipient_phone": "Telefone",
|
|
"recipient_phone": "Telefone",
|
|
"produto/equipamento a recolher": "Equipamento a recolher",
|
|
"equipment": "Equipamento a recolher",
|
|
"motivo/instruções da recolha": "Motivo da recolha",
|
|
"reason": "Motivo da recolha",
|
|
"data preferida para recolha": "Data preferida",
|
|
"preferred_date": "Data preferida",
|
|
"billing.tax_id": "NIF",
|
|
"billing.billing_address": "Morada fiscal",
|
|
"billing.billing_email": "Email faturação",
|
|
"shipment.delivery_address": "Morada de entrega",
|
|
"shipment.pickup_address": "Morada de recolha",
|
|
}
|
|
return labels.get(raw, raw.replace("_", " ").replace(".", " · ").strip().capitalize() or "Dado em falta")
|
|
|
|
|
|
def build_preparation_view_model(task: Dict[str, Any], preparation: Optional[Dict[str, Any]]) -> Dict[str, Any]:
|
|
prep = preparation or {}
|
|
extracted = _as_dict(prep.get("extracted_data"))
|
|
shipment = _as_dict(extracted.get("shipment"))
|
|
customer = _as_dict(extracted.get("customer"))
|
|
billing = _as_dict(extracted.get("billing"))
|
|
sale = _as_dict(extracted.get("sale"))
|
|
|
|
raw_missing = prep.get("missing_fields") or extracted.get("missing_fields") or []
|
|
missing = [{"label": _missing_label(item), "raw": str(item or "")} for item in _as_list(raw_missing)]
|
|
|
|
confirmed: List[Dict[str, str]] = []
|
|
for label, value in [
|
|
("Local de recolha", shipment.get("pickup_address")),
|
|
("Morada de entrega", shipment.get("delivery_address")),
|
|
("Contacto", shipment.get("recipient_name")),
|
|
("Telefone", shipment.get("recipient_phone")),
|
|
("Empresa", customer.get("company") or task.get("customer_name")),
|
|
("Email", customer.get("email") or task.get("customer_email")),
|
|
("NIF", customer.get("tax_id") or billing.get("tax_id")),
|
|
]:
|
|
v = _value(value)
|
|
if v:
|
|
confirmed.append({"label": label, "value": v})
|
|
|
|
products = _as_list(sale.get("products"))
|
|
product_names = [str(p.get("name") or p.get("description") or "").strip() for p in products if isinstance(p, dict)]
|
|
product_names = [x for x in product_names if x]
|
|
if product_names:
|
|
confirmed.append({"label": "Produto", "value": ", ".join(product_names[:3])})
|
|
|
|
suggested = _value(prep.get("suggested_reply") or extracted.get("suggested_reply"))
|
|
|
|
action = _value(task.get("action")) or "Rever tarefa"
|
|
primary_action = "Pedir dados em falta ao cliente" if missing else action
|
|
|
|
return {
|
|
"status": prep.get("status") or ("missing_data" if missing else "ready"),
|
|
"prep_type": prep.get("prep_type") or "generic",
|
|
"primary_action": primary_action,
|
|
"missing_fields": missing,
|
|
"confirmed_fields": confirmed,
|
|
"suggested_reply": suggested,
|
|
"confidence": prep.get("confidence"),
|
|
"technical": {
|
|
"customer": customer,
|
|
"billing": billing,
|
|
"sale": sale,
|
|
"shipment": shipment,
|
|
},
|
|
}
|