Skip to content

Báo cáo (Reports) ​

Nhóm 9 báo cáo cho module Telesales: dashboard tổng quan, disposition breakdown, hiệu suất agent, funnel, sức khoẻ caller-ID, heatmap giờ × thứ, lead-source attribution, chuỗi thời gian và abandon rate. Tất cả đều hỗ trợ export CSV/Excel.

Query params chung ​

Mọi endpoint chia sẻ bộ tham số sau (UTC ISO 8601):

FieldTypeRequiredMô tảGiá trị hợp lệ
campaign_idintegeroptionalLọc theo chiến dịch
date_fromdatetime✅Mốc bắt đầu (ISO 8601 UTC)
date_todatetime✅Mốc kết thúc (ISO 8601 UTC)Khoảng date_from..date_to ≤ 90 ngày
agent_ids[]array<integer>optionalDanh sách nhiều agent cần lọc (?agent_ids[]=25&agent_ids[]=26)
team_idintegeroptionalLọc theo nhóm
timezonestringoptionalNhóm dữ liệu theo ngày/giờ theo múi giờ nàytên timezone TZDB (UTC, Asia/Ho_Chi_Minh, ...) — default UTC
formatstringoptionalĐịnh dạng responsejson (default) / csv / xlsx (xem 9.2)

Lỗi 422 chung — khoảng vượt 90 ngày:

json
{
  "message": "The given data was invalid.",
  "errors": { "date_to": ["The date_from..date_to range may not exceed 90 days."] }
}

Tổng quan 9 endpoint ​

EndpointNội dung
GET /api/telesales/reports/dashboardKPI tổng quan: dials, tỷ lệ bắt máy (Answer Rate), AHT (Average Handle Time - thời gian xử lý trung bình) (Average Handle Time - thời gian xử lý trung bình), chuyển đổi (chuyển đổi (conversion))
GET /api/telesales/reports/disposition-breakdownTỷ lệ phần trăm theo từng disposition code
GET /api/telesales/reports/agent-performanceKPI theo từng agent: calls, conversions, AHT, talk time
GET /api/telesales/reports/funnelFunnel: Lead → Dialled → Connected → Talked > 30 s → Converted
GET /api/telesales/reports/caller-id-healthSức khoẻ caller-ID rotation (ASR, short-call ratio, carrier)
GET /api/telesales/reports/hour-dow-heatmapMatrix 24 giờ × 7 ngày (best calling windows)
GET /api/telesales/reports/lead-source-attributionConversion theo nguồn lead
GET /api/telesales/reports/time-seriesChuỗi thời gian theo ?group_by=day|week|hour
GET /api/telesales/reports/abandon-rateAbandon rate realtime (PDPL/TCPA gate)

9.1 Response mẫu ​

GET /api/telesales/reports/dashboard?campaign_id=43&date_from=2026-06-01&date_to=2026-06-10 ​

Response fields ​

FieldTypeMô tảGiá trị hợp lệ
total_dialsintegerTổng số lần quay số trong khoảng thời gian≥ 0
total_answersintegerTổng số cuộc gọi được khách hàng bắt máy≥ 0
answer_rate_pctstringChuỗi decimal (2 chữ số) — total_answers / total_dials × 100"0.00"-"100.00"
avg_talk_time_secstringThời gian đàm thoại trung bình (giây)
total_talk_time_secstringTổng thời gian đàm thoại (giây)
unique_agentsintegerSố agent khác nhau đã quay số trong khoảng≥ 0
pdpl_blocked_countintegerSố cuộc gọi bị PDPL chặn (ngoài giờ cho phép)≥ 0
json
{
  "data": {
    "total_dials":        487,
    "total_answers":      312,
    "answer_rate_pct":   "64.07",
    "avg_talk_time_sec": "184.5",
    "total_talk_time_sec": "57563",
    "unique_agents":       12,
    "pdpl_blocked_count":   5
  }
}

GET /api/telesales/reports/agent-performance?campaign_id=43&date_from=...&date_to=... ​

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
agent_idintegerID user agent
namestringHọ tên agent
usernamestringTên đăng nhập
dialsintegerSố cuộc đã quay trong khoảng≥ 0
answersintegerSố cuộc khách hàng bắt máy≥ 0
avg_aht_secintegerAHT (Average Handle Time) — thời gian xử lý trung bình mỗi cuộc (giây)≥ 0
conversionsintegerSố cuộc chốt thành công≥ 0
conv_ratenumberconversions / answers × 100 (float, KHÔNG phải string)0-100
json
{
  "data": [
    {
      "agent_id":     3,
      "name":         "Nguyen Van A",
      "username":     "agent01",
      "dials":        152,
      "answers":       98,
      "avg_aht_sec":  191,
      "conversions":   28,
      "conv_rate":   18.42
    },
    {
      "agent_id":     4,
      "name":         "Tran Thi B",
      "username":     "agent02",
      "dials":        140,
      "answers":       86,
      "avg_aht_sec":  176,
      "conversions":   22,
      "conv_rate":   15.71
    }
  ]
}

GET /api/telesales/reports/funnel?campaign_id=43&date_from=...&date_to=... ​

Phản hồi trả về là một mảng phẳng (không phải object lồng {stages, conversion_overall_pct}).

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
stagestringTên bước trong funnelTotal leads / Dialed / Connected / Talked > 30s / Disposed / Converted
countintegerSố lead/cuộc gọi ở bước này≥ 0
json
{
  "data": [
    { "stage": "Total leads",  "count":  487 },
    { "stage": "Dialed",       "count":  312 },
    { "stage": "Connected",    "count":  248 },
    { "stage": "Talked > 30s", "count":  198 },
    { "stage": "Disposed",     "count":  290 },
    { "stage": "Converted",    "count":   78 }
  ]
}

Có 6 stage — gồm cả Disposed. Client tự tính conversion_overall_pct = Converted / Total_leads × 100 từ stage đầu và cuối.

GET /api/telesales/reports/disposition-breakdown?campaign_id=43&date_from=...&date_to=... ​

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
codestringMã disposition
labelstringNhãn hiển thị
categorystringNhóm kết quảcontact / no_contact / callback / remove
colorstringMã màu UI badge#RRGGBB
countintegerSố cuộc gọi có disposition này≥ 0
pctstringChuỗi decimal 2 chữ số — phần trăm trên tổng cuộc gọi"0.00"-"100.00"
json
{
  "data": [
    {
      "code":     "no_answer",
      "label":    "No Answer",
      "category": "no_contact",
      "color":    "#6B7280",
      "count":     95,
      "pct":      "30.45"
    },
    {
      "code":     "sale",
      "label":    "Sale Success",
      "category": "contact",
      "color":    "#10B981",
      "count":     78,
      "pct":      "25.00"
    }
  ]
}

Mỗi item kèm category + color (Giao diện có thể dùng để hiển thị badge). pct là chuỗi decimal. Không có wrapper meta: {total_calls} — client tự tính total = sum(count).

GET /api/telesales/reports/caller-id-health?date_from=...&date_to=... ​

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
cidstringSố caller-ID
display_namestring|nullTên nội bộ
carrierstringNhà mạngviettel / mobifone / vinaphone / vietnamobile / landline / other
cli_typestringLoại sốmobile / fixed_02x / hotline_1900 / hotline_1800 / brandname
Trạng thái trong nhóm xoay vòngstringTrạng thái trong rotation poolactive / cooldown / paused / disabled
cooldown_untildatetime|nullLúc hết cooldownISO 8601 UTC
daily_capintegerGiới hạn cuộc/ngày≥ 1
total_callsintegerTổng số cuộc đã gọi trong khoảng≥ 0
answered_callsintegerSố cuộc khách hàng bắt máy≥ 0
asr_pctnumberAnswer-Seizure Ratio (%) — answered/total × 1000-100
acd_secintegerAverage Call Duration — thời lượng đàm thoại trung bình (giây)≥ 0
short_callsintegerSố cuộc dưới ngưỡng "đàm thoại có ý nghĩa"≥ 0
short_call_ratio_pctnumberTỷ lệ cuộc ngắn / tổng0-100
rejected_callsintegerSố cuộc bị từ chối≥ 0
health_statusstringPhân loại sức khoẻhealthy / warning / suspected_block / no_data
health_calls_todayintegerSố cuộc gọi hôm nay (dùng đánh giá cooldown)≥ 0
json
{
  "data": [
    {
      "cid":                  "0900000012",
      "display_name":         "Sales Line 1",
      "carrier":              "viettel",
      "cli_type":             "fixed_02x",
      "Trạng thái trong nhóm xoay vòng":          "active",
      "cooldown_until":        null,
      "daily_cap":             200,
      "total_calls":           152,
      "answered_calls":         98,
      "asr_pct":                64.5,
      "acd_sec":                121,
      "short_calls":             28,
      "short_call_ratio_pct":   18.4,
      "rejected_calls":           2,
      "health_status":         "healthy",
      "health_calls_today":      87
    }
  ]
}

GET /api/telesales/reports/hour-dow-heatmap?campaign_id=43&date_from=...&date_to=... ​

Trả về mảng phẳng 168 phần tử (7 ngày × 24 giờ), không lồng theo day-of-week.

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
day_of_weekintegerThứ trong tuần0 = CN, 1 = T2, ..., 6 = T7
hourintegerGiờ trong ngày (theo timezone query param)0-23
dialsintegerSố cuộc đã quay trong slot≥ 0
answeredintegerSố cuộc khách bắt máy≥ 0
answer_rate_pctnumberTỷ lệ bắt máy answered/dials × 1000-100
json
{
  "data": [
    { "day_of_week": 1, "hour": 0, "dials": 0,  "answered": 0,  "answer_rate_pct":  0 },
    { "day_of_week": 1, "hour": 1, "dials": 0,  "answered": 0,  "answer_rate_pct":  0 },
    { "day_of_week": 1, "hour": 9, "dials": 87, "answered": 56, "answer_rate_pct": 64.4 }
  ]
}

Ứng dụng tích hợp có thể chuyển dữ liệu thành ma trận 7 × 24 để hiển thị heatmap để render heatmap.

GET /api/telesales/reports/lead-source-attribution?date_from=...&date_to=... ​

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
sourcestringNguồn lead — lead không có nguồn gom dưới "(unknown)"
total_leadsintegerTổng số lead từ nguồn này trong khoảng≥ 0
dialed_countintegerSố lead đã được quay số≥ 0
contacted_countintegerSố lead khách hàng bắt máy≥ 0
conv_countintegerSố lead chốt thành công≥ 0
conv_rate_pctstringTỷ lệ chuyển đổi conv_count/total_leads × 100 (decimal 2 chữ số)"0.00"-"100.00"
json
{
  "data": [
    {
      "source":           "facebook_lead_ads",
      "total_leads":       240,
      "dialed_count":      230,
      "contacted_count":   152,
      "conv_count":         62,
      "conv_rate_pct":    "25.83"
    },
    {
      "source":           "(unknown)",
      "total_leads":         5,
      "dialed_count":        3,
      "contacted_count":     2,
      "conv_count":          0,
      "conv_rate_pct":     "0.00"
    }
  ]
}

GET /api/telesales/reports/time-series?campaign_id=43&group_by=day&date_from=...&date_to=... ​

Trả về mảng phẳng — không có wrapper {group_by, metrics, series}.

Query parameter bổ sung ​

FieldTypeRequiredMô tảGiá trị hợp lệ
group_bystringoptionalBước nhóm thời gianday (default) / week / hour

Response fields (mỗi item trong data[]) ​

FieldTypeMô tảGiá trị hợp lệ
Mốc thời gian (Mốc thời gian (bucket))stringMốc thời gian — format theo group_byday → YYYY-MM-DD; week → YYYY-Www (ISO 8601); hour → YYYY-MM-DD HH:00:00
dialsintegerSố cuộc đã quay trong bucket≥ 0
answersintegerSố cuộc khách bắt máy≥ 0
talk_secintegerTổng thời gian đàm thoại (giây)≥ 0
conversionsintegerSố cuộc chốt thành công≥ 0
json
{
  "data": [
    { "bucket": "2026-06-01", "dials": 110, "answers": 68, "talk_sec":  9180, "conversions": 18 },
    { "bucket": "2026-06-02", "dials": 105, "answers": 71, "talk_sec": 10260, "conversions": 16 },
    { "bucket": "2026-06-05", "dials":  82, "answers": 55, "talk_sec":  6720, "conversions": 15 }
  ]
}

GET /api/telesales/reports/abandon-rate?campaign_id=43 (realtime) ​

Response của endpoint này phong phú hơn các báo cáo khác — chứa current (ảnh chụp trạng thái thời gian thực) + breaches (lịch sử lần vượt ngưỡng gần đây).

Response fields ​

FieldTypeMô tảGiá trị hợp lệ
current.campaign_idintegerID chiến dịch
current.attempts_totalintegerTổng số attempt trong cửa sổ đo≥ 0
current.attempts_abandonedintegerSố attempt bị abandon trước khi agent kịp nói≥ 0
current.abandon_rate_pctnumberTỷ lệ abandon (%)0-100
current.window_minutesintegerĐộ dài cửa sổ đo (phút, default 30 ngày = 43.200)≥ 1
current.window_fromdatetimeMốc bắt đầu cửa sổISO 8601
current.window_todatetimeMốc kết thúc cửa sổISO 8601
current.campaign_namestringTên chiến dịch
current.campaign_statusstringTrạng thái chiến dịchdraft / active / paused / completed
current.limit_pctnumberNgưỡng PDPL/TCPA cho phépdefault 3
current.breachedboolĐang vượt ngưỡng hay không
breaches[]arrayLịch sử các snapshot đã vượt ngưỡng (rỗng nếu chưa từng vượt)
json
{
  "data": {
    "current": {
      "campaign_id":           43,
      "attempts_total":         1,
      "attempts_abandoned":     0,
      "abandon_rate_pct":       0,
      "window_minutes":     43200,
      "window_from":      "2026-05-10 02:31:14",
      "window_to":        "2026-06-09 02:31:14",
      "tenant_id":              1,
      "campaign_name":     "Outbound Sales Q3-2026 03",
      "campaign_status":   "active",
      "limit_pct":              3,
      "breached":           false
    },
    "breaches": []
  }
}

Khi breached=true, mảng breaches chứa lịch sử snapshot (các cửa sổ thời gian đã vượt giới hạn). Client dùng để render banner cảnh báo và vẽ xu hướng.

9.2 Export CSV / Excel ​

http
GET /api/telesales/reports/{report}/export?format=csv|xlsx

{report} ∈ {dashboard, disposition-breakdown, agent-performance, funnel, caller-id-health, hour-dow-heatmap, lead-source-attribution, time-series}.

Response: file stream (Content-Type: text/csv hoặc application/vnd.openxmlformats-officedocument.spreadsheetml.sheet).

Định dạng xuất mặc định là chuẩn chung. Mẫu Excel theo từng khách hàng (thứ tự cột, label header, conditional formatting riêng) được cấu hình trong gói cấu hình riêng.

Cấp phép theo điều khoản sử dụng của Zorio.