Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions healthcheck/am_healthcheck/vendor-rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@
"created_at",
"created",
"created at",
"conversation created at"
"conversation created at",
"created time"
],
"closed_at": [
"closed_at",
"closed_date",
"solved_at",
"resolved_at",
"solved at",
"closed at"
"closed at",
"closed time",
"resolved time"
],
"human_agent_participated": [
"human_agent_participated",
Expand Down
30 changes: 30 additions & 0 deletions healthcheck/tests/test_vendors.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,33 @@ def test_intercom_label_headers_map(self):
export = load_export(path)
self.assertIn("conversation_id", export["columns_found"])
self.assertIn("opened_at", export["columns_found"])

def test_freshdesk_style_headers_map(self):
"""Freshdesk's standard ticket export labels its timestamps
"Created time" / "Closed time" / "Resolved time" (Freshworks support:
"How do I export my tickets from Freshdesk?"). None of those space
forms were in the alias table, so a native export silently lost both
timestamps and the recount could not place a single line in time."""
from am_healthcheck.vendors import load_export
path = self._export([
"Ticket ID", "Created time", "Closed time",
"human_agent_participated", "issue_addressed",
"customer_recontacted_within_window", "vendor_billed"])
export = load_export(path)
self.assertIn("conversation_id", export["columns_found"])
self.assertIn("opened_at", export["columns_found"])
self.assertIn("closed_at", export["columns_found"])
self.assertEqual(export["columns_missing"], [])

def test_freshdesk_resolved_time_maps_to_closed_at(self):
"""Freshdesk splits "Resolved time" (status 4) from "Closed time"
(status 5); either one ends the conversation, so both map to
closed_at, matching the existing Zendesk "Solved at" alias."""
from am_healthcheck.vendors import load_export
path = self._export([
"Ticket ID", "Created time", "Resolved time",
"human_agent_participated", "issue_addressed",
"customer_recontacted_within_window", "vendor_billed"])
export = load_export(path)
self.assertIn("closed_at", export["columns_found"])
self.assertEqual(export["columns_missing"], [])
7 changes: 5 additions & 2 deletions registry/vendor-rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@
"created_at",
"created",
"created at",
"conversation created at"
"conversation created at",
"created time"
],
"closed_at": [
"closed_at",
"closed_date",
"solved_at",
"resolved_at",
"solved at",
"closed at"
"closed at",
"closed time",
"resolved time"
],
"human_agent_participated": [
"human_agent_participated",
Expand Down
7 changes: 5 additions & 2 deletions website/vendor-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"solved_at",
"resolved_at",
"solved at",
"closed at"
"closed at",
"closed time",
"resolved time"
],
"conversation_id": [
"conversation_id",
Expand Down Expand Up @@ -71,7 +73,8 @@
"created_at",
"created",
"created at",
"conversation created at"
"conversation created at",
"created time"
],
"vendor_billed": [
"vendor_billed",
Expand Down