diff --git a/oca_dependencies.txt b/oca_dependencies.txt new file mode 100644 index 00000000..941c76e0 --- /dev/null +++ b/oca_dependencies.txt @@ -0,0 +1 @@ +helpdesk diff --git a/spreadsheet_dashboard_helpdesk_oca/README.rst b/spreadsheet_dashboard_helpdesk_oca/README.rst new file mode 100644 index 00000000..39ce056e --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/README.rst @@ -0,0 +1,88 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================================== +Spreadsheet dashboard for helpdesk +================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:ae03011402cac074f10571f3194b90d3a005fda27d1ce6dda6c057380e5f7583 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fspreadsheet-lightgray.png?logo=github + :target: https://github.com/OCA/spreadsheet/tree/19.0/spreadsheet_dashboard_helpdesk_oca + :alt: OCA/spreadsheet +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/spreadsheet-19-0/spreadsheet-19-0-spreadsheet_dashboard_helpdesk_oca + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/spreadsheet&target_branch=19.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Spreadsheet dashboard for helpdesk tickets. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Domatix + +Contributors +------------ + +- Domatix + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-domatix| image:: https://github.com/domatix.png?size=40px + :target: https://github.com/domatix + :alt: domatix + +Current `maintainer `__: + +|maintainer-domatix| + +This module is part of the `OCA/spreadsheet `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/spreadsheet_dashboard_helpdesk_oca/__init__.py b/spreadsheet_dashboard_helpdesk_oca/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/spreadsheet_dashboard_helpdesk_oca/__manifest__.py b/spreadsheet_dashboard_helpdesk_oca/__manifest__.py new file mode 100644 index 00000000..7dcc70ca --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/__manifest__.py @@ -0,0 +1,13 @@ +{ + "name": "Spreadsheet dashboard for helpdesk", + "category": "Hidden", + "depends": ["spreadsheet_dashboard", "helpdesk_mgmt"], + "version": "19.0.1.0.0", + "website": "https://github.com/OCA/spreadsheet", + "author": "Domatix, Odoo Community Association (OCA)", + "maintainers": ["domatix"], + "data": ["data/dashboards.xml"], + "installable": True, + "auto_install": ["helpdesk_mgmt"], + "license": "AGPL-3", +} diff --git a/spreadsheet_dashboard_helpdesk_oca/data/dashboards.xml b/spreadsheet_dashboard_helpdesk_oca/data/dashboards.xml new file mode 100644 index 00000000..80d64957 --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/data/dashboards.xml @@ -0,0 +1,27 @@ + + + + + Helpdesk + + + + + 100 + True + + diff --git a/spreadsheet_dashboard_helpdesk_oca/data/files/helpdesk_dashboard.json b/spreadsheet_dashboard_helpdesk_oca/data/files/helpdesk_dashboard.json new file mode 100644 index 00000000..1ba68e10 --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/data/files/helpdesk_dashboard.json @@ -0,0 +1,894 @@ +{ + "version": "18.4.14", + "sheets": [ + { + "id": "sheet1", + "name": "Dashboard", + "colNumber": 7, + "rowNumber": 55, + "rows": { + "6": {"size": 40}, + "22": {"size": 40}, + "23": {"size": 40}, + "24": {"size": 30}, + "25": {"size": 30}, + "26": {"size": 30}, + "27": {"size": 30}, + "28": {"size": 30}, + "29": {"size": 30}, + "30": {"size": 30}, + "31": {"size": 30}, + "32": {"size": 30}, + "33": {"size": 30}, + "34": {"size": 30}, + "35": {"size": 40}, + "36": {"size": 40}, + "37": {"size": 30}, + "38": {"size": 30}, + "39": {"size": 30}, + "40": {"size": 30}, + "41": {"size": 30}, + "42": {"size": 30}, + "43": {"size": 30}, + "44": {"size": 30}, + "45": {"size": 30}, + "46": {"size": 30}, + "47": {"size": 30} + }, + "cols": { + "0": {"size": 275}, + "1": {"size": 103}, + "2": {"size": 100}, + "3": {"size": 50}, + "4": {"size": 275}, + "5": {"size": 103}, + "6": {"size": 100} + }, + "merges": [], + "cells": { + "A7": "[Tickets by Stage](odoo://view/{\"viewType\":\"graph\",\"action\":{\"domain\":[],\"context\":{\"group_by\":[\"stage_id\"],\"graph_measure\":\"__count\",\"graph_mode\":\"pie\",\"graph_groupbys\":[\"stage_id\"]},\"modelName\":\"helpdesk.ticket\",\"views\":[[false,\"graph\"],[false,\"pivot\"],[false,\"list\"],[false,\"search\"]]},\"threshold\":0,\"name\":\"Tickets Analysis\"})", + "E7": "[Tickets by Team](odoo://view/{\"viewType\":\"graph\",\"action\":{\"domain\":[],\"context\":{\"group_by\":[\"stage_id\",\"team_id\"],\"graph_measure\":\"__count\",\"graph_mode\":\"bar\",\"graph_groupbys\":[\"stage_id\",\"team_id\"]},\"modelName\":\"helpdesk.ticket\",\"views\":[[false,\"graph\"],[false,\"pivot\"],[false,\"list\"],[false,\"search\"]]},\"threshold\":0,\"name\":\"Tickets Analysis\"})", + "A23": "[Top Customers](odoo://view/{\"viewType\":\"pivot\",\"action\":{\"domain\":[[\"partner_id\",\"!=\",false]],\"context\":{\"group_by\":[],\"pivot_measures\":[\"__count\"],\"pivot_column_groupby\":[],\"pivot_row_groupby\":[\"partner_id\"]},\"modelName\":\"helpdesk.ticket\",\"views\":[[false,\"graph\"],[false,\"pivot\"],[false,\"list\"],[false,\"search\"]]},\"threshold\":0,\"name\":\"Tickets Analysis\"})", + "A24": "=_t(\"Customer\")", + "A25": "=PIVOT.HEADER(4,\"#partner_id\",1)", + "A26": "=PIVOT.HEADER(4,\"#partner_id\",2)", + "A27": "=PIVOT.HEADER(4,\"#partner_id\",3)", + "A28": "=PIVOT.HEADER(4,\"#partner_id\",4)", + "A29": "=PIVOT.HEADER(4,\"#partner_id\",5)", + "A30": "=PIVOT.HEADER(4,\"#partner_id\",6)", + "A31": "=PIVOT.HEADER(4,\"#partner_id\",7)", + "A32": "=PIVOT.HEADER(4,\"#partner_id\",8)", + "A33": "=PIVOT.HEADER(4,\"#partner_id\",9)", + "A34": "=PIVOT.HEADER(4,\"#partner_id\",10)", + "B24": "=_t(\"Tickets\")", + "B25": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",1)", + "B26": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",2)", + "B27": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",3)", + "B28": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",4)", + "B29": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",5)", + "B30": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",6)", + "B31": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",7)", + "B32": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",8)", + "B33": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",9)", + "B34": "=PIVOT.VALUE(4,\"__count\",\"#partner_id\",10)", + "E23": "[Top Assignees](odoo://view/{\"viewType\":\"pivot\",\"action\":{\"domain\":[[\"user_id\",\"!=\",false]],\"context\":{\"group_by\":[],\"pivot_measures\":[\"__count\"],\"pivot_column_groupby\":[],\"pivot_row_groupby\":[\"user_id\"]},\"modelName\":\"helpdesk.ticket\",\"views\":[[false,\"graph\"],[false,\"pivot\"],[false,\"list\"],[false,\"search\"]]},\"threshold\":0,\"name\":\"Tickets Analysis\"})", + "E24": "=_t(\"Assignee\")", + "E25": "=PIVOT.HEADER(1,\"#user_id\",1)", + "E26": "=PIVOT.HEADER(1,\"#user_id\",2)", + "E27": "=PIVOT.HEADER(1,\"#user_id\",3)", + "E28": "=PIVOT.HEADER(1,\"#user_id\",4)", + "E29": "=PIVOT.HEADER(1,\"#user_id\",5)", + "E30": "=PIVOT.HEADER(1,\"#user_id\",6)", + "E31": "=PIVOT.HEADER(1,\"#user_id\",7)", + "E32": "=PIVOT.HEADER(1,\"#user_id\",8)", + "E33": "=PIVOT.HEADER(1,\"#user_id\",9)", + "E34": "=PIVOT.HEADER(1,\"#user_id\",10)", + "F24": "=_t(\"Tickets\")", + "F25": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",1)", + "F26": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",2)", + "F27": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",3)", + "F28": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",4)", + "F29": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",5)", + "F30": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",6)", + "F31": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",7)", + "F32": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",8)", + "F33": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",9)", + "F34": "=PIVOT.VALUE(1,\"__count\",\"#user_id\",10)", + "A36": "[Tickets by Tags](odoo://view/{\"viewType\":\"pivot\",\"action\":{\"domain\":[[\"tag_ids\",\"!=\",false]],\"context\":{\"group_by\":[\"tag_ids\"],\"pivot_measures\":[\"__count\"],\"pivot_column_groupby\":[],\"pivot_row_groupby\":[\"tag_ids\"]},\"modelName\":\"helpdesk.ticket\",\"views\":[[false,\"graph\"],[false,\"pivot\"],[false,\"list\"],[false,\"search\"]]},\"threshold\":0,\"name\":\"Tickets Analysis\"})", + "A37": "=_t(\"Tag\")", + "A38": "=PIVOT.HEADER(3,\"#tag_ids\",1)", + "A39": "=PIVOT.HEADER(3,\"#tag_ids\",2)", + "A40": "=PIVOT.HEADER(3,\"#tag_ids\",3)", + "A41": "=PIVOT.HEADER(3,\"#tag_ids\",4)", + "A42": "=PIVOT.HEADER(3,\"#tag_ids\",5)", + "A43": "=PIVOT.HEADER(3,\"#tag_ids\",6)", + "A44": "=PIVOT.HEADER(3,\"#tag_ids\",7)", + "A45": "=PIVOT.HEADER(3,\"#tag_ids\",8)", + "A46": "=PIVOT.HEADER(3,\"#tag_ids\",9)", + "A47": "=PIVOT.HEADER(3,\"#tag_ids\",10)", + "B37": "=_t(\"Tickets\")", + "B38": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",1)", + "B39": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",2)", + "B40": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",3)", + "B41": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",4)", + "B42": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",5)", + "B43": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",6)", + "B44": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",7)", + "B45": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",8)", + "B46": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",9)", + "B47": "=PIVOT.VALUE(3,\"__count\",\"#tag_ids\",10)" + }, + "styles": { + "A7": 1, + "A23": 1, + "A36": 1, + "E7": 1, + "E23": 1, + "A24": 2, + "A37": 2, + "E24": 2, + "E37": 2, + "A25:C34": 3, + "A38:C47": 3, + "E25:G34": 3, + "E38:G47": 3, + "B24:C24": 4, + "B37:C37": 4, + "F24:G24": 4, + "F37:G37": 4 + }, + "formats": {}, + "borders": { + "A7:C7": 1, + "A23:C23": 1, + "A36:C36": 1, + "E7:G7": 1, + "E23:G23": 1, + "E36:G36": 1, + "A8:C8": 2, + "A24:C24": 2, + "A37:C37": 2, + "E8:G8": 2, + "E24:G24": 2, + "E37:G37": 2, + "A25:C25": 3, + "A38:C38": 3, + "E25:G25": 3, + "E38:G38": 3, + "A26:C33": 4, + "A39:C46": 4, + "E26:G33": 4, + "E39:G46": 4, + "A34:C34": 5, + "A47:C47": 5, + "E34:G34": 5, + "E47:G47": 5, + "A35:C35": 6, + "A48:C48": 6, + "E35:G35": 6, + "E48:G48": 6 + }, + "conditionalFormats": [ + { + "rule": {"type": "DataBarRule", "color": 15531509, "rangeValues": "B25:B34"}, + "id": "62781980-687b-452e-bf4b-1d95aa74b206", + "ranges": ["A25:A34"] + }, + { + "rule": {"type": "DataBarRule", "color": 15726335, "rangeValues": "F25:F34"}, + "id": "fa3cf786-7e59-4040-b972-a8ea6adfa84a", + "ranges": ["E25:E34"] + }, + { + "rule": {"type": "DataBarRule", "color": 16775149, "rangeValues": "B38:B47"}, + "id": "4da45c58-2120-47f1-9c38-efc72705ce1e", + "ranges": ["A38:A47"] + } + ], + "dataValidationRules": [], + "figures": [ + { + "id": "26f09a19-26d7-4d7d-b8d9-9eda7661ef5a", + "width": 475, + "height": 344, + "tag": "chart", + "data": { + "title": {"text": ""}, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["stage_id", "team_id"], + "measure": "__count", + "order": null, + "resModel": "helpdesk.ticket", + "mode": "bar", + "cumulatedStart": false + }, + "searchParams": { + "comparison": null, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [], + "groupBy": ["stage_id", "team_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [], + "verticalAxisPosition": "left", + "stacked": true, + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + } + }, + "offset": {"x": 525, "y": 178}, + "col": 0, + "row": 0 + }, + { + "id": "70a88eff-8ce0-4392-8905-156ef2771086", + "width": 480, + "height": 344, + "tag": "chart", + "data": { + "title": {"text": ""}, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["stage_id"], + "measure": "__count", + "order": null, + "resModel": "helpdesk.ticket", + "mode": "pie", + "cumulatedStart": false + }, + "searchParams": { + "comparison": null, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [], + "groupBy": ["stage_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [], + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + } + }, + "offset": {"x": 0, "y": 178}, + "col": 0, + "row": 0 + }, + { + "id": "8eae55ae-5435-49ee-ad58-dae822bbd9dd", + "width": 200, + "height": 108, + "tag": "chart", + "data": { + "baselineColorDown": "#DC6965", + "baselineColorUp": "#00A04A", + "baselineMode": "difference", + "title": {"text": "Tickets", "bold": true, "color": "#434343"}, + "type": "scorecard", + "background": "#EFF6FF", + "keyValue": "Data!D2", + "humanize": false, + "fieldMatching": {}, + "baseline": "Data!E2" + }, + "offset": {"x": 0, "y": 10}, + "col": 0, + "row": 0 + }, + { + "id": "746a2799-0dc9-4bce-b309-4cedffa67a3a", + "width": 200, + "height": 108, + "tag": "chart", + "data": { + "baselineColorDown": "#DC6965", + "baselineColorUp": "#00A04A", + "baselineMode": "percentage", + "title": {"text": "Open Tickets", "bold": true, "color": "#434343"}, + "type": "scorecard", + "background": "#FEF2F2", + "baseline": "Data!E3", + "baselineDescr": {"text": "since last period"}, + "keyValue": "Data!D3", + "humanize": false, + "fieldMatching": {} + }, + "offset": {"x": 210, "y": 10}, + "col": 0, + "row": 0 + }, + { + "id": "488da38e-01db-46a0-b4b0-e2fafc4ad390", + "width": 200, + "height": 108, + "tag": "chart", + "data": { + "baselineColorDown": "#DC6965", + "baselineColorUp": "#00A04A", + "baselineMode": "difference", + "title": {"text": "Time to Assign", "bold": true, "color": "#434343"}, + "type": "scorecard", + "background": "#FEF2F2", + "baseline": "Data!E4", + "baselineDescr": {"text": "last period"}, + "keyValue": "Data!D4", + "humanize": false, + "fieldMatching": {} + }, + "offset": {"x": 420, "y": 10}, + "col": 0, + "row": 0 + }, + { + "id": "ce7e17ea-eed0-493e-9968-5905c0969ca9", + "width": 200, + "height": 108, + "tag": "chart", + "data": { + "baselineColorDown": "#DC6965", + "baselineColorUp": "#00A04A", + "baselineMode": "difference", + "title": {"text": "Time to Close", "color": "#434343", "bold": true}, + "type": "scorecard", + "background": "#FEF2F2", + "baseline": "Data!E5", + "baselineDescr": {"text": "last period"}, + "keyValue": "Data!D5", + "humanize": false, + "fieldMatching": {} + }, + "offset": {"x": 629, "y": 10}, + "col": 0, + "row": 0 + } + ], + "tables": [ + { + "range": "A24:C34", + "type": "static", + "config": { + "hasFilters": false, + "totalRow": false, + "firstColumn": false, + "lastColumn": false, + "numberOfHeaders": 1, + "bandedRows": true, + "bandedColumns": false, + "automaticAutofill": true, + "styleId": "None" + } + }, + { + "range": "A37:C47", + "type": "static", + "config": { + "hasFilters": false, + "totalRow": false, + "firstColumn": false, + "lastColumn": false, + "numberOfHeaders": 1, + "bandedRows": true, + "bandedColumns": false, + "automaticAutofill": true, + "styleId": "None" + } + }, + { + "range": "E24:G34", + "type": "static", + "config": { + "hasFilters": false, + "totalRow": false, + "firstColumn": false, + "lastColumn": false, + "numberOfHeaders": 1, + "bandedRows": true, + "bandedColumns": false, + "automaticAutofill": true, + "styleId": "None" + } + }, + { + "range": "E37:G47", + "type": "static", + "config": { + "hasFilters": false, + "totalRow": false, + "firstColumn": false, + "lastColumn": false, + "numberOfHeaders": 1, + "bandedRows": true, + "bandedColumns": false, + "automaticAutofill": true, + "styleId": "None" + } + } + ], + "areGridLinesVisible": true, + "isVisible": true, + "headerGroups": {"ROW": [], "COL": []}, + "comments": {} + }, + { + "id": "add7aca3-0196-4975-a083-1a0ad034c57d", + "name": "Data", + "colNumber": 26, + "rowNumber": 90, + "rows": {}, + "cols": { + "0": {"size": 119}, + "1": {"size": 119}, + "2": {"size": 97}, + "3": {"size": 144}, + "4": {"size": 138} + }, + "merges": [], + "cells": { + "A1": "=_t(\"KPI\")", + "A2": "=_t(\"Tickets\")", + "A3": "=_t(\"Open tickets\")", + "A4": "=_t(\"Time to Assign\")", + "A5": "=_t(\"Time to Close\")", + "B1": "=_t(\"Current\")", + "B2": "=PIVOT.VALUE(5,\"__count\")", + "B3": "=PIVOT.VALUE(7,\"__count\")", + "B4": "=PIVOT.VALUE(5,\"hours_to_assign\")", + "B5": "=PIVOT.VALUE(5,\"hours_to_close\")", + "C1": "=_t(\"Previous\")", + "C2": "=PIVOT.VALUE(6,\"__count\")", + "C3": "=PIVOT.VALUE(8,\"__count\")", + "C4": "=PIVOT.VALUE(6,\"hours_to_assign\")", + "C5": "=PIVOT.VALUE(6,\"hours_to_close\")", + "D1": "=_t(\"Current\")", + "D2": "=FORMAT.LARGE.NUMBER(B2)", + "D3": "=FORMAT.LARGE.NUMBER(B3)", + "D4": "=CONCATENATE(ROUND(B4),_t(\" hours\"))", + "D5": "=CONCATENATE(ROUND(B5),_t(\" hours\"))", + "E1": "=_t(\"Previous\")", + "E2": "=FORMAT.LARGE.NUMBER(C2)", + "E3": "=FORMAT.LARGE.NUMBER(C3)", + "E4": "=ROUND(C4)", + "E5": "=ROUND(C5)" + }, + "styles": {"A1:C1": 5, "D1:E1": 6, "D2:E3": 7, "D4:E5": 8}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [], + "tables": [], + "areGridLinesVisible": true, + "isVisible": true, + "headerGroups": {"ROW": [], "COL": []}, + "comments": {} + } + ], + "styles": { + "1": {"textColor": "#01666b", "fontSize": 16, "bold": true}, + "2": {"textColor": "#434343", "bold": true, "fontSize": 11}, + "3": {"textColor": "#434343", "verticalAlign": "middle"}, + "4": {"textColor": "#434343", "bold": true, "fontSize": 11, "align": "center"}, + "5": {"bold": true}, + "6": {"bold": true, "fillColor": "#f2f2f2"}, + "7": {"fillColor": "#f2f2f2"}, + "8": {"align": "right", "fillColor": "#f2f2f2"} + }, + "formats": {}, + "borders": { + "1": {"bottom": {"style": "thin", "color": "#CCCCCC"}}, + "2": {"top": {"style": "thin", "color": "#CCCCCC"}}, + "3": {"bottom": {"style": "thick", "color": "#FFFFFF"}}, + "4": { + "top": {"style": "thick", "color": "#FFFFFF"}, + "bottom": {"style": "thick", "color": "#FFFFFF"} + }, + "5": { + "top": {"style": "thick", "color": "#FFFFFF"}, + "bottom": {"style": "thin", "color": "#FFFFFF"} + }, + "6": {"top": {"style": "thin", "color": "#FFFFFF"}} + }, + "revisionId": "START_REVISION", + "uniqueFigureIds": true, + "settings": { + "locale": { + "name": "English (US)", + "code": "en_US", + "thousandsSeparator": ",", + "decimalSeparator": ".", + "dateFormat": "mm/dd/yyyy", + "timeFormat": "hh:mm:ss", + "formulaArgSeparator": ",", + "weekStart": 7 + } + }, + "pivots": { + "1": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [["user_id", "!=", false]], + "id": "1", + "measures": [{"id": "__count", "fieldName": "__count"}], + "model": "helpdesk.ticket", + "name": "Tickets by Assignee", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "1", + "columns": [], + "rows": [{"fieldName": "user_id"}] + }, + "2": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [["team_id", "!=", false]], + "id": "2", + "measures": [{"id": "__count", "fieldName": "__count"}], + "model": "helpdesk.ticket", + "name": "Tickets by Team", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "2", + "columns": [], + "rows": [{"fieldName": "team_id"}] + }, + "3": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [["tag_ids", "!=", false]], + "id": "3", + "measures": [{"id": "__count", "fieldName": "__count"}], + "model": "helpdesk.ticket", + "name": "Tickets by Tags", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "3", + "columns": [], + "rows": [{"fieldName": "tag_ids"}] + }, + "4": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [["partner_id", "!=", false]], + "id": "4", + "measures": [{"id": "__count", "fieldName": "__count"}], + "model": "helpdesk.ticket", + "name": "Tickets by Customer", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "4", + "columns": [], + "rows": [{"fieldName": "partner_id"}] + }, + "5": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [], + "id": "5", + "measures": [ + {"id": "__count", "fieldName": "__count"}, + {"id": "hours_to_assign", "fieldName": "hours_to_assign"}, + {"id": "hours_to_close", "fieldName": "hours_to_close"} + ], + "model": "helpdesk.ticket", + "name": "stats - current", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "5", + "columns": [], + "rows": [] + }, + "6": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": -1 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [], + "id": "6", + "measures": [ + {"id": "__count", "fieldName": "__count"}, + {"id": "hours_to_assign", "fieldName": "hours_to_assign"}, + {"id": "hours_to_close", "fieldName": "hours_to_close"} + ], + "model": "helpdesk.ticket", + "name": "stats - previous", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "6", + "columns": [], + "rows": [] + }, + "7": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": 0 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [["closed", "=", false]], + "id": "7", + "measures": [{"id": "__count", "fieldName": "__count"}], + "model": "helpdesk.ticket", + "name": "open tickets - current", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "7", + "columns": [], + "rows": [] + }, + "8": { + "type": "ODOO", + "fieldMatching": { + "83b5c62c-1c67-4477-a057-c0ec29edd595": { + "chain": "create_date", + "type": "datetime", + "offset": -1 + }, + "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d": { + "chain": "user_id", + "type": "many2one" + }, + "3fc9b370-1aae-436e-b77e-6bbc5f10f56c": { + "chain": "team_id", + "type": "many2one" + }, + "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9": { + "chain": "tag_ids", + "type": "many2many" + }, + "9c9461c3-974d-41c1-8cbd-2fa8e89de148": { + "chain": "partner_id", + "type": "many2one" + } + }, + "context": {"group_by": [], "graph_measure": "__count__"}, + "domain": [["closed", "=", false]], + "id": "8", + "measures": [{"id": "__count", "fieldName": "__count"}], + "model": "helpdesk.ticket", + "name": "open tickets - previous", + "sortedColumn": {"measure": "__count", "order": "desc", "domain": []}, + "formulaId": "8", + "columns": [], + "rows": [] + } + }, + "pivotNextId": 9, + "customTableStyles": {}, + "globalFilters": [ + { + "id": "83b5c62c-1c67-4477-a057-c0ec29edd595", + "type": "date", + "label": "Period", + "defaultValue": "last_30_days" + }, + { + "id": "fb7f6ae2-e19c-40d5-9976-7a05b1f18c2d", + "type": "relation", + "label": "Agent", + "modelName": "res.users", + "defaultValueDisplayNames": [] + }, + { + "id": "3fc9b370-1aae-436e-b77e-6bbc5f10f56c", + "type": "relation", + "label": "Team", + "modelName": "helpdesk.ticket.team", + "defaultValueDisplayNames": [] + }, + { + "id": "cfccbf2c-c86e-4915-a73d-c1e8ae69abe9", + "type": "relation", + "label": "Tags", + "modelName": "helpdesk.ticket.tag", + "defaultValueDisplayNames": [] + }, + { + "id": "9c9461c3-974d-41c1-8cbd-2fa8e89de148", + "type": "relation", + "label": "Customer", + "modelName": "res.partner", + "defaultValueDisplayNames": [] + } + ], + "lists": {}, + "listNextId": 1, + "chartOdooMenusReferences": { + "26f09a19-26d7-4d7d-b8d9-9eda7661ef5a": "helpdesk_mgmt.helpdesk_ticket_main_menu", + "70a88eff-8ce0-4392-8905-156ef2771086": "helpdesk_mgmt.helpdesk_ticket_main_menu", + "8eae55ae-5435-49ee-ad58-dae822bbd9dd": "helpdesk_mgmt.helpdesk_ticket_main_menu", + "746a2799-0dc9-4bce-b309-4cedffa67a3a": "helpdesk_mgmt.helpdesk_ticket_main_menu", + "488da38e-01db-46a0-b4b0-e2fafc4ad390": "helpdesk_mgmt.helpdesk_ticket_main_menu", + "ce7e17ea-eed0-493e-9968-5905c0969ca9": "helpdesk_mgmt.helpdesk_ticket_main_menu" + } +} diff --git a/spreadsheet_dashboard_helpdesk_oca/models/__init__.py b/spreadsheet_dashboard_helpdesk_oca/models/__init__.py new file mode 100644 index 00000000..8e082e7c --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/models/__init__.py @@ -0,0 +1 @@ +from . import helpdesk_ticket diff --git a/spreadsheet_dashboard_helpdesk_oca/models/helpdesk_ticket.py b/spreadsheet_dashboard_helpdesk_oca/models/helpdesk_ticket.py new file mode 100644 index 00000000..65ff64bc --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/models/helpdesk_ticket.py @@ -0,0 +1,33 @@ +# Copyright 2026 Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class HelpdeskTicket(models.Model): + _inherit = "helpdesk.ticket" + + hours_to_assign = fields.Float( + compute="_compute_hours_metrics", + store=True, + aggregator="avg", + ) + hours_to_close = fields.Float( + compute="_compute_hours_metrics", + store=True, + aggregator="avg", + ) + + @api.depends("create_date", "assigned_date", "closed_date") + def _compute_hours_metrics(self): + for ticket in self: + hours_to_assign = 0.0 + hours_to_close = 0.0 + if ticket.create_date and ticket.assigned_date: + delta = ticket.assigned_date - ticket.create_date + hours_to_assign = delta.total_seconds() / 3600 + if ticket.create_date and ticket.closed_date: + delta = ticket.closed_date - ticket.create_date + hours_to_close = delta.total_seconds() / 3600 + ticket.hours_to_assign = hours_to_assign + ticket.hours_to_close = hours_to_close diff --git a/spreadsheet_dashboard_helpdesk_oca/pyproject.toml b/spreadsheet_dashboard_helpdesk_oca/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/spreadsheet_dashboard_helpdesk_oca/readme/CONTRIBUTORS.md b/spreadsheet_dashboard_helpdesk_oca/readme/CONTRIBUTORS.md new file mode 100644 index 00000000..6ab0fbbc --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Domatix diff --git a/spreadsheet_dashboard_helpdesk_oca/readme/DESCRIPTION.md b/spreadsheet_dashboard_helpdesk_oca/readme/DESCRIPTION.md new file mode 100644 index 00000000..5d743a0c --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/readme/DESCRIPTION.md @@ -0,0 +1 @@ +Spreadsheet dashboard for helpdesk tickets. diff --git a/spreadsheet_dashboard_helpdesk_oca/static/description/icon.png b/spreadsheet_dashboard_helpdesk_oca/static/description/icon.png new file mode 100644 index 00000000..b3ad914a Binary files /dev/null and b/spreadsheet_dashboard_helpdesk_oca/static/description/icon.png differ diff --git a/spreadsheet_dashboard_helpdesk_oca/static/description/index.html b/spreadsheet_dashboard_helpdesk_oca/static/description/index.html new file mode 100644 index 00000000..67577c87 --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/static/description/index.html @@ -0,0 +1,431 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Spreadsheet dashboard for helpdesk

+ +

Beta License: AGPL-3 OCA/spreadsheet Translate me on Weblate Try me on Runboat

+

Spreadsheet dashboard for helpdesk tickets.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Domatix
  • +
+
+
+

Contributors

+
    +
  • Domatix
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

domatix

+

This module is part of the OCA/spreadsheet project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+
+ + diff --git a/spreadsheet_dashboard_helpdesk_oca/tests/__init__.py b/spreadsheet_dashboard_helpdesk_oca/tests/__init__.py new file mode 100644 index 00000000..89f9d092 --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/tests/__init__.py @@ -0,0 +1 @@ +from . import test_helpdesk_ticket_metrics diff --git a/spreadsheet_dashboard_helpdesk_oca/tests/test_helpdesk_ticket_metrics.py b/spreadsheet_dashboard_helpdesk_oca/tests/test_helpdesk_ticket_metrics.py new file mode 100644 index 00000000..1cc5cedc --- /dev/null +++ b/spreadsheet_dashboard_helpdesk_oca/tests/test_helpdesk_ticket_metrics.py @@ -0,0 +1,30 @@ +# Copyright 2026 Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import timedelta + +from odoo import fields +from odoo.tests import tagged + +from odoo.addons.helpdesk_mgmt.tests.common import TestHelpdeskTicketBase + + +@tagged("post_install", "-at_install") +class TestHelpdeskTicketMetrics(TestHelpdeskTicketBase): + def test_hours_metrics(self): + now = fields.Datetime.now() + ticket = self.env["helpdesk.ticket"].create( + { + "name": "Broken printer", + "description": "

Test

", + "team_id": self.team_a.id, + } + ) + ticket.write( + { + "assigned_date": now + timedelta(hours=2), + "closed_date": now + timedelta(hours=5), + } + ) + self.assertAlmostEqual(ticket.hours_to_assign, 2.0, places=2) + self.assertAlmostEqual(ticket.hours_to_close, 5.0, places=2)