Add conditional ticket status update based on time entries
Implements API contract section 9: ticket resolution workflow with conditional status updates based on time entry existence. - Added query_time_entries_by_ticket_id() for POST /TimeEntries/query - update_ticket_resolution_safe() now checks time entries: * No time entries: sets status to 5 (Complete) * Has time entries: keeps current status (ticket remains open) This ensures tickets are only auto-closed when appropriate per the validated Autotask API workflow. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
88421badbd
commit
9b905fa24f
@ -559,11 +559,16 @@ class AutotaskClient:
|
||||
|
||||
|
||||
def update_ticket_resolution_safe(self, ticket_id: int, resolution_text: str) -> Dict[str, Any]:
|
||||
"""Safely update the Ticket 'resolution' field without changing status.
|
||||
"""Safely update the Ticket 'resolution' field with conditional status update.
|
||||
|
||||
Autotask Tickets require a full PUT update; therefore we must:
|
||||
- GET /Tickets/{id} to retrieve current stabilising fields (including classification/routing)
|
||||
- PUT /Tickets with those stabilising fields unchanged, and only update 'resolution'
|
||||
- Query time entries for the ticket
|
||||
- PUT /Tickets with stabilising fields and conditional status
|
||||
|
||||
Status logic (per API contract section 9):
|
||||
- If NO time entries exist: set status to 5 (Complete)
|
||||
- If time entries exist: keep current status unchanged
|
||||
|
||||
IMPORTANT:
|
||||
- GET /Tickets/{id} returns the ticket object under the 'item' envelope in most tenants.
|
||||
@ -639,14 +644,23 @@ class AutotaskClient:
|
||||
"Cannot safely update ticket resolution because required fields are missing: " + ", ".join(missing)
|
||||
)
|
||||
|
||||
# Check for time entries as per API contract section 9
|
||||
# If no time entries exist, we can set status to 5 (Complete)
|
||||
# If time entries exist, status remains unchanged
|
||||
time_entries = self.query_time_entries_by_ticket_id(int(ticket_id))
|
||||
has_time_entries = len(time_entries) > 0
|
||||
|
||||
# Determine final status based on time entry check
|
||||
# Status 5 = Complete (sets completedDate and resolvedDateTime)
|
||||
final_status = resolved_status if has_time_entries else 5
|
||||
|
||||
# Build payload with exact values from GET response (including null if that's what we got)
|
||||
payload: Dict[str, Any] = {
|
||||
"id": int(ticket_id),
|
||||
"issueType": resolved_issue_type,
|
||||
"subIssueType": resolved_sub_issue_type,
|
||||
"source": resolved_source,
|
||||
# Keep status unchanged
|
||||
"status": resolved_status,
|
||||
"status": final_status,
|
||||
"resolution": str(resolution_text or ""),
|
||||
}
|
||||
|
||||
@ -955,3 +969,22 @@ class AutotaskClient:
|
||||
if limit and isinstance(limit, int) and limit > 0:
|
||||
return items[: int(limit)]
|
||||
return items
|
||||
|
||||
def query_time_entries_by_ticket_id(self, ticket_id: int) -> List[Dict[str, Any]]:
|
||||
"""Query TimeEntries for a specific ticket.
|
||||
|
||||
Uses POST /TimeEntries/query as per API contract section 6.
|
||||
|
||||
Returns list of time entry items. Empty list if no time entries exist.
|
||||
"""
|
||||
|
||||
try:
|
||||
tid = int(ticket_id)
|
||||
except Exception:
|
||||
tid = 0
|
||||
if tid <= 0:
|
||||
return []
|
||||
|
||||
payload = {"filter": [{"op": "eq", "field": "ticketID", "value": tid}]}
|
||||
data = self._request("POST", "TimeEntries/query", json_body=payload)
|
||||
return self._as_items_list(data)
|
||||
|
||||
@ -4,6 +4,13 @@ This file documents all changes made to this project via Claude Code.
|
||||
|
||||
## [2026-02-05]
|
||||
|
||||
### Added
|
||||
- Autotask conditional ticket status update based on time entries (API contract section 9):
|
||||
- `query_time_entries_by_ticket_id()` - Query time entries for a ticket via POST /TimeEntries/query
|
||||
- `update_ticket_resolution_safe()` now checks for time entries and conditionally sets status:
|
||||
- If NO time entries exist: sets status to 5 (Complete) with completedDate and resolvedDateTime
|
||||
- If time entries exist: keeps current status unchanged (ticket remains open)
|
||||
|
||||
### Fixed
|
||||
- Autotask ticket resolution update now correctly preserves exact field values from GET response in PUT payload.
|
||||
The `issueType`, `subIssueType`, and `source` fields are copied with their exact values (including null)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user