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, }, }