From 981d65c27450881bcb09cc910b52d6113cbb95bf Mon Sep 17 00:00:00 2001 From: Ivo Oskamp Date: Thu, 15 Jan 2026 12:44:01 +0100 Subject: [PATCH] Auto-commit local changes before build (2026-01-15 12:44:01) --- .last-branch | 2 +- .../app/integrations/autotask/client.py | 55 ++++++++++++++++++- docs/changelog.md | 9 +++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/.last-branch b/.last-branch index 83d7747..36c68d6 100644 --- a/.last-branch +++ b/.last-branch @@ -1 +1 @@ -v20260115-06-autotask-auth-fallback +v20260115-07-autotask-picklist-field-detect diff --git a/containers/backupchecks/src/backend/app/integrations/autotask/client.py b/containers/backupchecks/src/backend/app/integrations/autotask/client.py index e45f4f5..0f39cfd 100644 --- a/containers/backupchecks/src/backend/app/integrations/autotask/client.py +++ b/containers/backupchecks/src/backend/app/integrations/autotask/client.py @@ -222,18 +222,50 @@ class AutotaskClient: return self._get_ticket_picklist_values(field_names=["source", "sourceid"]) def _get_ticket_picklist_values(self, field_names: List[str]) -> List[Dict[str, Any]]: + """Retrieve picklist values for a Tickets field. + + Autotask field metadata can vary between tenants/environments. + We first try exact name matches, then fall back to a contains-match + on the metadata field name/label for picklist fields. + """ + fields = self._get_entity_fields("Tickets") wanted = {n.strip().lower() for n in (field_names or []) if str(n).strip()} + def _field_label(f: Dict[str, Any]) -> str: + # Autotask metadata commonly provides either "label" or "displayName". + return str(f.get("label") or f.get("displayName") or "").strip().lower() + field: Optional[Dict[str, Any]] = None + + # 1) Exact name match for f in fields: name = str(f.get("name") or "").strip().lower() if name in wanted: field = f break + # 2) Fallback: contains match for picklists (handles QueueID vs TicketQueueID etc.) + if field is None and wanted: + candidates: List[Dict[str, Any]] = [] + for f in fields: + if not bool(f.get("isPickList")): + continue + name = str(f.get("name") or "").strip().lower() + label = _field_label(f) + if any(w in name for w in wanted) or any(w in label for w in wanted): + candidates.append(f) + + if candidates: + # Prefer the most specific/shortest name match to avoid overly broad matches. + candidates.sort(key=lambda x: len(str(x.get("name") or ""))) + field = candidates[0] + if not field: - raise AutotaskError(f"Unable to locate Tickets field metadata for picklist retrieval: {sorted(wanted)}") + raise AutotaskError( + "Unable to locate Tickets field metadata for picklist retrieval: " + f"{sorted(wanted)}" + ) if not bool(field.get("isPickList")): raise AutotaskError(f"Tickets.{field.get('name')} is not marked as a picklist in Autotask metadata.") @@ -251,14 +283,33 @@ class AutotaskClient: """ fields = self._get_entity_fields("Tickets") priority_field: Optional[Dict[str, Any]] = None + + def _field_label(f: Dict[str, Any]) -> str: + return str(f.get("label") or f.get("displayName") or "").strip().lower() + + # Exact match first for f in fields: name = str(f.get("name") or "").strip().lower() if name == "priority": priority_field = f break + # Fallback: contains match (handles variations like TicketPriority) + if priority_field is None: + candidates: List[Dict[str, Any]] = [] + for f in fields: + if not bool(f.get("isPickList")): + continue + name = str(f.get("name") or "").strip().lower() + label = _field_label(f) + if "priority" in name or "priority" in label: + candidates.append(f) + if candidates: + candidates.sort(key=lambda x: len(str(x.get("name") or ""))) + priority_field = candidates[0] + if not priority_field: - raise AutotaskError("Unable to locate Tickets.priority field metadata for picklist retrieval.") + raise AutotaskError("Unable to locate a Tickets priority picklist field in Autotask metadata.") if not bool(priority_field.get("isPickList")): raise AutotaskError("Tickets.priority is not marked as a picklist in Autotask metadata.") diff --git a/docs/changelog.md b/docs/changelog.md index cd4b606..e8a1911 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -55,6 +55,15 @@ Changes: - Extended authentication error diagnostics to include selected environment and resolved Autotask zone information. - Increased reliability of Autotask connection testing across different tenants and sandbox configurations. +## v20260115-07-autotask-picklist-field-detect + +### Changes: +- Improved detection of Autotask Ticket entity picklist fields to handle tenant-specific field naming. +- Added fallback matching logic based on field name and display label for picklist fields. +- Fixed queue picklist resolution when fields are not named exactly `queue` or `queueid`. +- Applied the same robust detection logic to ticket priority picklist retrieval. +- Prevented connection test failures caused by missing or differently named metadata fields. + *** ## v0.1.21