feat(psa): implement post_note and update_ticket_status in CW provider
Replaces NotImplementedError stubs with working implementations: - post_note maps note_type to CW flag fields (internalAnalysisFlag, resolutionFlag, detailDescriptionFlag) with appropriate visibility and notification settings - update_ticket_status uses CW JSON Patch format to update status Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -155,7 +155,7 @@ class ConnectWiseProvider(PSAProvider):
|
||||
status=data.get("status", {}).get("name") if data.get("status") else None,
|
||||
)
|
||||
|
||||
# ── Stubs for later slices ────────────────────────────────────────
|
||||
# ── Notes & status updates ───────────────────────────────────────
|
||||
|
||||
async def post_note(
|
||||
self,
|
||||
@@ -164,12 +164,71 @@ class ConnectWiseProvider(PSAProvider):
|
||||
note_type: str,
|
||||
member_id: str | None = None,
|
||||
) -> PSANote:
|
||||
raise NotImplementedError("Implemented in Slice 4")
|
||||
"""Post a note to a CW ticket.
|
||||
|
||||
Maps ResolutionFlow note types to CW flag fields:
|
||||
- internal_analysis → internalAnalysisFlag (internal only)
|
||||
- resolution → resolutionFlag (internal, triggers notifications)
|
||||
- description → detailDescriptionFlag (external, triggers notifications)
|
||||
"""
|
||||
from app.services.psa.types import NoteType
|
||||
|
||||
flags = {
|
||||
NoteType.INTERNAL_ANALYSIS: {
|
||||
"internalAnalysisFlag": True,
|
||||
"resolutionFlag": False,
|
||||
"detailDescriptionFlag": False,
|
||||
"internalFlag": True,
|
||||
"processNotifications": False,
|
||||
},
|
||||
NoteType.RESOLUTION: {
|
||||
"internalAnalysisFlag": False,
|
||||
"resolutionFlag": True,
|
||||
"detailDescriptionFlag": False,
|
||||
"internalFlag": True,
|
||||
"processNotifications": True,
|
||||
},
|
||||
NoteType.DESCRIPTION: {
|
||||
"internalAnalysisFlag": False,
|
||||
"resolutionFlag": False,
|
||||
"detailDescriptionFlag": True,
|
||||
"internalFlag": False,
|
||||
"processNotifications": True,
|
||||
},
|
||||
}
|
||||
|
||||
note_flags = flags.get(note_type, flags[NoteType.INTERNAL_ANALYSIS])
|
||||
|
||||
body: dict = {
|
||||
"text": text,
|
||||
**note_flags,
|
||||
}
|
||||
|
||||
if member_id:
|
||||
body["member"] = {"id": int(member_id)}
|
||||
|
||||
data = await self.client.post(
|
||||
f"/service/tickets/{ticket_id}/notes", json_body=body
|
||||
)
|
||||
|
||||
return PSANote(
|
||||
id=str(data.get("id", "")),
|
||||
text=data.get("text", ""),
|
||||
note_type=note_type,
|
||||
created_at=data.get("dateCreated"),
|
||||
)
|
||||
|
||||
async def update_ticket_status(
|
||||
self, ticket_id: str, status_id: int
|
||||
) -> PSATicket:
|
||||
raise NotImplementedError("Implemented in Slice 4")
|
||||
"""Update a CW ticket's status using JSON Patch format."""
|
||||
patch_body = [
|
||||
{"op": "replace", "path": "status", "value": {"id": status_id}}
|
||||
]
|
||||
data = await self.client.patch(
|
||||
f"/service/tickets/{ticket_id}", json_body=patch_body
|
||||
)
|
||||
return self._map_ticket(data)
|
||||
|
||||
async def list_members(self) -> list[PSAMember]:
|
||||
raise NotImplementedError("Implemented in Slice 5")
|
||||
|
||||
Reference in New Issue
Block a user