Merge branch 'v20260203-10-autotask-resolution-field-aliases' into main
This commit is contained in:
commit
753c14bb4e
@ -1 +1 @@
|
||||
v20260203-09-autotask-resolution-from-note
|
||||
v20260203-10-autotask-resolution-field-aliases
|
||||
|
||||
@ -584,22 +584,43 @@ class AutotaskClient:
|
||||
if not isinstance(t, dict):
|
||||
raise AutotaskError("Autotask did not return a ticket object.")
|
||||
|
||||
stabilising_fields = [
|
||||
"id",
|
||||
"companyID",
|
||||
"queueID",
|
||||
"title",
|
||||
"priority",
|
||||
"status",
|
||||
"dueDateTime",
|
||||
"ticketCategory",
|
||||
"issueType",
|
||||
"subIssueType",
|
||||
"source",
|
||||
"organizationalLevelAssociationID",
|
||||
]
|
||||
# Some Autotask environments return slightly different field names (e.g. *ID vs *Id).
|
||||
# We always source values from the fresh GET and send the canonical field names in the PUT payload.
|
||||
field_sources: Dict[str, list[str]] = {
|
||||
"id": ["id"],
|
||||
"companyID": ["companyID", "companyId"],
|
||||
"queueID": ["queueID", "queueId"],
|
||||
"title": ["title"],
|
||||
"priority": ["priority"],
|
||||
"status": ["status"],
|
||||
"dueDateTime": ["dueDateTime", "dueDate", "dueDateUtc"],
|
||||
"ticketCategory": ["ticketCategory", "ticketCategoryID", "ticketCategoryId"],
|
||||
"issueType": ["issueType", "issueTypeID", "issueTypeId"],
|
||||
"subIssueType": ["subIssueType", "subIssueTypeID", "subIssueTypeId"],
|
||||
"source": ["source", "sourceID", "sourceId"],
|
||||
"organizationalLevelAssociationID": [
|
||||
"organizationalLevelAssociationID",
|
||||
"organizationalLevelAssociationId",
|
||||
],
|
||||
}
|
||||
|
||||
def _get_first(ticket_obj: Dict[str, Any], keys: list[str]) -> Any:
|
||||
for k in keys:
|
||||
if k in ticket_obj:
|
||||
return ticket_obj.get(k)
|
||||
return None
|
||||
|
||||
stabilising_fields = list(field_sources.keys())
|
||||
|
||||
resolved_values: Dict[str, Any] = {}
|
||||
missing: list[str] = []
|
||||
for f in stabilising_fields:
|
||||
v = _get_first(t, field_sources[f])
|
||||
# Treat None/"" as missing, but allow 0 for picklists.
|
||||
if v in (None, ""):
|
||||
missing.append(f)
|
||||
resolved_values[f] = v
|
||||
|
||||
missing = [f for f in stabilising_fields if t.get(f) in (None, "")]
|
||||
if missing:
|
||||
raise AutotaskError(
|
||||
"Cannot safely update ticket resolution because required fields are missing: " + ", ".join(missing)
|
||||
@ -614,11 +635,10 @@ class AutotaskClient:
|
||||
else:
|
||||
new_res = res_txt
|
||||
|
||||
payload: Dict[str, Any] = {k: t.get(k) for k in stabilising_fields}
|
||||
# Ensure numeric ID is an int for PUT.
|
||||
payload["id"] = int(t.get("id"))
|
||||
payload: Dict[str, Any] = dict(resolved_values)
|
||||
payload["id"] = int(resolved_values.get("id"))
|
||||
# Explicitly keep status unchanged.
|
||||
payload["status"] = t.get("status")
|
||||
payload["status"] = resolved_values.get("status")
|
||||
payload["resolution"] = new_res
|
||||
|
||||
self.update_ticket(payload)
|
||||
|
||||
@ -512,6 +512,12 @@ Changes:
|
||||
- Resolution updates follow the validated safe pattern: GET the current Ticket first, then PUT with stabilising fields while keeping the status unchanged.
|
||||
- Added verification to ensure the resolution text is persisted after the update.
|
||||
|
||||
## v20260203-10-autotask-resolution-field-aliases
|
||||
|
||||
- Fix: Resolution PUT now always reuses the latest classification/routing fields from GET /Tickets/{id}, including support for common field-name variants (*ID/*Id).
|
||||
- Prevents failure when issueType/subIssueType/source are not present under the expected keys after ticket creation or later changes.
|
||||
- Keeps ticket status unchanged while updating resolution, per validated Postman contract.
|
||||
|
||||
***
|
||||
|
||||
## v0.1.21
|
||||
|
||||
Loading…
Reference in New Issue
Block a user