From 8dff80a2685ba7d74aa63eae0e0294657142db99 Mon Sep 17 00:00:00 2001 From: alvaro-domatix Date: Thu, 25 Jun 2026 10:24:31 +0000 Subject: [PATCH] [ADD] spreadsheet_dashboard_subscription_oca: spreadsheet dashboards for subscriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ready-to-use spreadsheet dashboards for subscriptions, built on the community `spreadsheet_dashboard` engine with no Enterprise dependency. Four dashboards are shipped under a dedicated *Subscriptions* group in the Dashboards app (`auto_install` wires them up when both `spreadsheet_dashboard` and `subscription_oca` are present): * **Subscriptions** — monthly/annual recurring revenue, active subscriptions and average MRR, with breakdowns by template, product category, sales team, salesperson, start month and stage. * **Salesperson** — recurring revenue and number of subscriptions by salesperson and sales team. * **MRR Evolution** — net/new/churned MRR and the cumulated MRR over time. MRR change events are derived from the current state (a positive event at start date and a negative one at close); mid-life expansion/contraction is not tracked, which would require a dedicated MRR event log. * **Retention** — cohort sizes and recurring revenue per start month, plus a survival curve built from the start and closing dates. All dashboards expose global filters (salesperson, sales team, customer, template) and refresh from the subscription analysis SQL models defined in this module. Depends on `subscription_oca` (OCA/contract) for the source data. --- .../README.rst | 111 +++ .../__init__.py | 3 + .../__manifest__.py | 19 + .../files/mrr_evolution_dashboard.osheet.json | 707 +++++++++++++++++ .../files/retention_dashboard.osheet.json | 528 +++++++++++++ .../files/salesperson_dashboard.osheet.json | 691 +++++++++++++++++ .../files/subscriptions_dashboard.osheet.json | 718 ++++++++++++++++++ .../data/spreadsheet_dashboards.xml | 114 +++ .../i18n/es.po | 429 +++++++++++ .../models/__init__.py | 4 + .../models/sale_subscription_mrr_report.py | 91 +++ .../sale_subscription_retention_report.py | 96 +++ .../pyproject.toml | 3 + .../readme/DESCRIPTION.md | 22 + .../readme/USAGE.md | 6 + .../report/sql_report_views.xml | 249 ++++++ .../security/ir.model.access.csv | 3 + .../static/description/index.html | 457 +++++++++++ 18 files changed, 4251 insertions(+) create mode 100644 spreadsheet_dashboard_subscription_oca/README.rst create mode 100644 spreadsheet_dashboard_subscription_oca/__init__.py create mode 100644 spreadsheet_dashboard_subscription_oca/__manifest__.py create mode 100644 spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json create mode 100644 spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json create mode 100644 spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json create mode 100644 spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json create mode 100644 spreadsheet_dashboard_subscription_oca/data/spreadsheet_dashboards.xml create mode 100644 spreadsheet_dashboard_subscription_oca/i18n/es.po create mode 100644 spreadsheet_dashboard_subscription_oca/models/__init__.py create mode 100644 spreadsheet_dashboard_subscription_oca/models/sale_subscription_mrr_report.py create mode 100644 spreadsheet_dashboard_subscription_oca/models/sale_subscription_retention_report.py create mode 100644 spreadsheet_dashboard_subscription_oca/pyproject.toml create mode 100644 spreadsheet_dashboard_subscription_oca/readme/DESCRIPTION.md create mode 100644 spreadsheet_dashboard_subscription_oca/readme/USAGE.md create mode 100644 spreadsheet_dashboard_subscription_oca/report/sql_report_views.xml create mode 100644 spreadsheet_dashboard_subscription_oca/security/ir.model.access.csv create mode 100644 spreadsheet_dashboard_subscription_oca/static/description/index.html diff --git a/spreadsheet_dashboard_subscription_oca/README.rst b/spreadsheet_dashboard_subscription_oca/README.rst new file mode 100644 index 00000000..219d847b --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/README.rst @@ -0,0 +1,111 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +======================================= +Subscription OCA Spreadsheet Dashboards +======================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:f1ffb09d1dc8f9a4a2d46af8273e5e4dd79b3e6e6f6fae841fa49a7434cd02c0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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_subscription_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_subscription_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| + +This module adds spreadsheet dashboards for subscriptions, built on top +of the community ``spreadsheet_dashboard`` engine and the analysis +models provided by ``subscription_oca``. No enterprise dependency is +required. + +It ships four ready-to-use dashboards under the **Dashboards** +application, in a dedicated *Subscriptions* group: + +- **Subscriptions**: monthly/annual recurring revenue, active + subscriptions and average MRR, with breakdowns by template, product + category, sales team, salesperson, start month and stage. +- **Salesperson**: recurring revenue and number of subscriptions broken + down by salesperson and sales team. +- **MRR Evolution**: net/new/churned MRR and the cumulated MRR over + time, with a monthly new-vs-churn breakdown. MRR change events are + derived from the current state of the subscriptions (a positive event + at the start date and a negative one at the closing date); mid-life + expansion/contraction is not tracked, which would require a dedicated + MRR event log. +- **Retention**: cohort sizes and recurring revenue per start month, + plus a retention/survival curve built from the start and closing + dates. + +All dashboards expose global filters (salesperson, sales team, customer, +template) and refresh automatically from the subscription analysis +models. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Open the **Dashboards** application. The four dashboards are available +in the *Subscriptions* group. Use the filters at the top (salesperson, +sales team, customer, template) to narrow down the figures. The data is +aggregated from the ``sale.subscription.report``, +``sale.subscription.mrr.report`` and +``sale.subscription.retention.report`` analysis models and refreshes +automatically. + +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 + +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. + +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_subscription_oca/__init__.py b/spreadsheet_dashboard_subscription_oca/__init__.py new file mode 100644 index 00000000..a161af09 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/__init__.py @@ -0,0 +1,3 @@ +# Copyright 2026 Domatix - Alvaro Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import models diff --git a/spreadsheet_dashboard_subscription_oca/__manifest__.py b/spreadsheet_dashboard_subscription_oca/__manifest__.py new file mode 100644 index 00000000..97974a86 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2026 Domatix - Alvaro Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Subscription OCA Spreadsheet Dashboards", + "version": "19.0.1.0.0", + "license": "AGPL-3", + "author": "Domatix, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/spreadsheet", + "category": "Productivity/Dashboard", + "summary": "Spreadsheet dashboards for subscriptions (MRR, salesperson)", + "depends": ["spreadsheet_dashboard", "subscription_oca"], + "data": [ + "security/ir.model.access.csv", + "report/sql_report_views.xml", + "data/spreadsheet_dashboards.xml", + ], + "auto_install": True, + "development_status": "Beta", +} diff --git a/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json b/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json new file mode 100644 index 00000000..ddab7c8f --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json @@ -0,0 +1,707 @@ +{ + "version": "18.5.10", + "sheets": [ + { + "id": "dashboard", + "name": "Dashboard", + "colNumber": 22, + "rowNumber": 80, + "rows": {}, + "cols": { + "0": { + "size": 50 + }, + "1": { + "size": 50 + }, + "2": { + "size": 50 + }, + "3": { + "size": 50 + }, + "4": { + "size": 50 + }, + "5": { + "size": 50 + }, + "6": { + "size": 50 + }, + "7": { + "size": 50 + }, + "8": { + "size": 50 + }, + "9": { + "size": 50 + }, + "10": { + "size": 50 + }, + "11": { + "size": 50 + }, + "12": { + "size": 50 + }, + "13": { + "size": 50 + }, + "14": { + "size": 50 + }, + "15": { + "size": 50 + }, + "16": { + "size": 50 + }, + "17": { + "size": 50 + }, + "18": { + "size": 50 + }, + "19": { + "size": 50 + }, + "20": { + "size": 50 + }, + "21": { + "size": 50 + } + }, + "merges": [], + "cells": {}, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [ + { + "id": "cccccccc-0000-0000-0000-000000000001", + "width": 345, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Net MRR", + "color": "#1f2937", + "bold": true + }, + "background": "#EFF6FF", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C1", + "chartId": "cccccccc-0000-0000-0000-000000000001" + }, + "offset": { + "x": 16, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000002", + "width": 345, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "New MRR (all time)", + "color": "#1f2937", + "bold": true + }, + "background": "#F0FDF4", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C2", + "chartId": "cccccccc-0000-0000-0000-000000000002" + }, + "offset": { + "x": 377, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000003", + "width": 345, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Churned MRR (all time)", + "color": "#1f2937", + "bold": true + }, + "background": "#FEF2F2", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C3", + "chartId": "cccccccc-0000-0000-0000-000000000003" + }, + "offset": { + "x": 738, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000010", + "width": 1068, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Net MRR Over Time" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["event_date:month"], + "measure": "mrr_change", + "order": null, + "resModel": "sale.subscription.mrr.report", + "mode": "line", + "cumulatedStart": true + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [], + "groupBy": ["event_date:month"], + "orderBy": [] + }, + "type": "odoo_line", + "dataSets": [{}], + "chartId": "cccccccc-0000-0000-0000-000000000010", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_mrr_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "cumulative": true, + "cumulatedStart": true + }, + "offset": { + "x": 16, + "y": 172 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000011", + "width": 1068, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR Change by Month & Type" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["event_date:month", "event_type"], + "measure": "mrr_change", + "order": null, + "resModel": "sale.subscription.mrr.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [], + "groupBy": ["event_date:month", "event_type"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "cccccccc-0000-0000-0000-000000000011", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_mrr_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "stacked": true + }, + "offset": { + "x": 16, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000012", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR Change by Type" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["event_type"], + "measure": "mrr_change", + "order": null, + "resModel": "sale.subscription.mrr.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [], + "groupBy": ["event_type"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "cccccccc-0000-0000-0000-000000000012", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_mrr_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 16, + "y": 932 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000013", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "New MRR by Template" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["template_id"], + "measure": "mrr_change", + "order": null, + "resModel": "sale.subscription.mrr.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["event_type", "=", "new"]], + "groupBy": ["template_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "cccccccc-0000-0000-0000-000000000013", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_mrr_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 558, + "y": 932 + }, + "col": 0, + "row": 0 + }, + { + "id": "cccccccc-0000-0000-0000-000000000014", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "New MRR by Salesperson" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["user_id"], + "measure": "mrr_change", + "order": null, + "resModel": "sale.subscription.mrr.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["event_type", "=", "new"]], + "groupBy": ["user_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "cccccccc-0000-0000-0000-000000000014", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_mrr_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 16, + "y": 1312 + }, + "col": 0, + "row": 0 + } + ], + "tables": [], + "areGridLinesVisible": false, + "isVisible": true, + "headerGroups": [], + "comments": {} + }, + { + "id": "data", + "name": "Data", + "colNumber": 8, + "rowNumber": 30, + "rows": {}, + "cols": {}, + "merges": [], + "cells": { + "A1": "=_t(\"MRR KPIs\")", + "B1": "=PIVOT.VALUE(1,\"mrr_change:sum\")", + "B2": "=PIVOT.VALUE(2,\"mrr_change:sum\")", + "B3": "=PIVOT.VALUE(3,\"mrr_change:sum\")", + "C1": "=IFERROR(FORMAT.LARGE.NUMBER(B1))", + "C2": "=IFERROR(FORMAT.LARGE.NUMBER(B2))", + "C3": "=IFERROR(FORMAT.LARGE.NUMBER(B3))" + }, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [], + "tables": [], + "areGridLinesVisible": true, + "isVisible": false, + "headerGroups": [], + "comments": {} + } + ], + "styles": {}, + "formats": {}, + "borders": {}, + "revisionId": "START_REVISION", + "uniqueFigureIds": true, + "settings": { + "locale": { + "name": "English (US)", + "code": "en_US", + "thousandsSeparator": ",", + "decimalSeparator": ".", + "dateFormat": "m/d/yyyy", + "timeFormat": "hh:mm:ss a", + "formulaArgSeparator": ",", + "weekStart": 7 + } + }, + "pivots": { + "1": { + "type": "ODOO", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "context": {}, + "domain": [], + "id": "1", + "measures": [ + { + "id": "mrr_change:sum", + "fieldName": "mrr_change", + "aggregator": "sum" + }, + { + "id": "__count", + "fieldName": "__count" + } + ], + "model": "sale.subscription.mrr.report", + "name": "KPIs 1", + "sortedColumn": null, + "formulaId": "1", + "columns": [], + "rows": [] + }, + "2": { + "type": "ODOO", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "context": {}, + "domain": [["event_type", "=", "new"]], + "id": "2", + "measures": [ + { + "id": "mrr_change:sum", + "fieldName": "mrr_change", + "aggregator": "sum" + } + ], + "model": "sale.subscription.mrr.report", + "name": "KPIs 2", + "sortedColumn": null, + "formulaId": "2", + "columns": [], + "rows": [] + }, + "3": { + "type": "ODOO", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "event_date", + "type": "datetime", + "offset": 0 + } + }, + "context": {}, + "domain": [["event_type", "=", "churn"]], + "id": "3", + "measures": [ + { + "id": "mrr_change:sum", + "fieldName": "mrr_change", + "aggregator": "sum" + } + ], + "model": "sale.subscription.mrr.report", + "name": "KPIs 3", + "sortedColumn": null, + "formulaId": "3", + "columns": [], + "rows": [] + } + }, + "pivotNextId": 4, + "customTableStyles": {}, + "globalFilters": [ + { + "id": "55555555-5555-5555-5555-555555555555", + "type": "date", + "label": "Period", + "defaultValue": "last_90_days" + }, + { + "id": "11111111-1111-1111-1111-111111111111", + "type": "relation", + "label": "Salesperson", + "defaultValueDisplayNames": [], + "modelName": "res.users" + }, + { + "id": "22222222-2222-2222-2222-222222222222", + "type": "relation", + "label": "Sales Team", + "defaultValueDisplayNames": [], + "modelName": "crm.team" + }, + { + "id": "33333333-3333-3333-3333-333333333333", + "type": "relation", + "label": "Customer", + "defaultValueDisplayNames": [], + "modelName": "res.partner" + }, + { + "id": "44444444-4444-4444-4444-444444444444", + "type": "relation", + "label": "Template", + "defaultValueDisplayNames": [], + "modelName": "sale.subscription.template" + } + ], + "lists": {}, + "listNextId": 1, + "chartOdooMenusReferences": { + "cccccccc-0000-0000-0000-000000000001": "subscription_oca.sale_subscription_menu", + "cccccccc-0000-0000-0000-000000000002": "subscription_oca.sale_subscription_menu", + "cccccccc-0000-0000-0000-000000000003": "subscription_oca.sale_subscription_menu" + } +} diff --git a/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json b/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json new file mode 100644 index 00000000..20676439 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json @@ -0,0 +1,528 @@ +{ + "version": "18.5.10", + "sheets": [ + { + "id": "dashboard", + "name": "Dashboard", + "colNumber": 22, + "rowNumber": 80, + "rows": {}, + "cols": { + "0": { + "size": 50 + }, + "1": { + "size": 50 + }, + "2": { + "size": 50 + }, + "3": { + "size": 50 + }, + "4": { + "size": 50 + }, + "5": { + "size": 50 + }, + "6": { + "size": 50 + }, + "7": { + "size": 50 + }, + "8": { + "size": 50 + }, + "9": { + "size": 50 + }, + "10": { + "size": 50 + }, + "11": { + "size": 50 + }, + "12": { + "size": 50 + }, + "13": { + "size": 50 + }, + "14": { + "size": 50 + }, + "15": { + "size": 50 + }, + "16": { + "size": 50 + }, + "17": { + "size": 50 + }, + "18": { + "size": 50 + }, + "19": { + "size": 50 + }, + "20": { + "size": 50 + }, + "21": { + "size": 50 + } + }, + "merges": [], + "cells": {}, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [ + { + "id": "dddddddd-0000-0000-0000-000000000001", + "width": 526, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Subscriptions (cohorts)", + "color": "#1f2937", + "bold": true + }, + "background": "#EFF6FF", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C1", + "chartId": "dddddddd-0000-0000-0000-000000000001" + }, + "offset": { + "x": 16, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "dddddddd-0000-0000-0000-000000000002", + "width": 526, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "MRR at Start", + "color": "#1f2937", + "bold": true + }, + "background": "#FFF7ED", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C2", + "chartId": "dddddddd-0000-0000-0000-000000000002" + }, + "offset": { + "x": 558, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "dddddddd-0000-0000-0000-000000000010", + "width": 1068, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Retention Curve (active subscriptions by month since start)" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["period_index"], + "measure": "__count", + "order": null, + "resModel": "sale.subscription.retention.report", + "mode": "line" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [], + "groupBy": ["period_index"], + "orderBy": [] + }, + "type": "odoo_line", + "dataSets": [{}], + "chartId": "dddddddd-0000-0000-0000-000000000010", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_retention_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "cohort_date", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 16, + "y": 172 + }, + "col": 0, + "row": 0 + }, + { + "id": "dddddddd-0000-0000-0000-000000000011", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Subscriptions by Cohort (start month)" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["cohort_date:month"], + "measure": "__count", + "order": null, + "resModel": "sale.subscription.retention.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["period_index", "=", 0]], + "groupBy": ["cohort_date:month"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "dddddddd-0000-0000-0000-000000000011", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_retention_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "cohort_date", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 16, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "dddddddd-0000-0000-0000-000000000012", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Cohort (start month)" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["cohort_date:month"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.retention.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["period_index", "=", 0]], + "groupBy": ["cohort_date:month"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "dddddddd-0000-0000-0000-000000000012", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_retention_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "cohort_date", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 558, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "dddddddd-0000-0000-0000-000000000013", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Cohort MRR by Template" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["template_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.retention.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["period_index", "=", 0]], + "groupBy": ["template_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "dddddddd-0000-0000-0000-000000000013", + "actionXmlId": "spreadsheet_dashboard_subscription_oca.action_sale_subscription_retention_report", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "cohort_date", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 16, + "y": 932 + }, + "col": 0, + "row": 0 + } + ], + "tables": [], + "areGridLinesVisible": false, + "isVisible": true, + "headerGroups": [], + "comments": {} + }, + { + "id": "data", + "name": "Data", + "colNumber": 8, + "rowNumber": 30, + "rows": {}, + "cols": {}, + "merges": [], + "cells": { + "A1": "=_t(\"Retention KPIs\")", + "B1": "=PIVOT.VALUE(1,\"__count\")", + "B2": "=PIVOT.VALUE(1,\"recurring_monthly:sum\")", + "C1": "=IFERROR(FORMAT.LARGE.NUMBER(B1))", + "C2": "=IFERROR(FORMAT.LARGE.NUMBER(B2))" + }, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [], + "tables": [], + "areGridLinesVisible": true, + "isVisible": false, + "headerGroups": [], + "comments": {} + } + ], + "styles": {}, + "formats": {}, + "borders": {}, + "revisionId": "START_REVISION", + "uniqueFigureIds": true, + "settings": { + "locale": { + "name": "English (US)", + "code": "en_US", + "thousandsSeparator": ",", + "decimalSeparator": ".", + "dateFormat": "m/d/yyyy", + "timeFormat": "hh:mm:ss a", + "formulaArgSeparator": ",", + "weekStart": 7 + } + }, + "pivots": { + "1": { + "type": "ODOO", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "cohort_date", + "type": "datetime", + "offset": 0 + } + }, + "context": {}, + "domain": [["period_index", "=", 0]], + "id": "1", + "measures": [ + { + "id": "recurring_monthly:sum", + "fieldName": "recurring_monthly", + "aggregator": "sum" + }, + { + "id": "__count", + "fieldName": "__count" + } + ], + "model": "sale.subscription.retention.report", + "name": "KPIs 1", + "sortedColumn": null, + "formulaId": "1", + "columns": [], + "rows": [] + } + }, + "pivotNextId": 2, + "customTableStyles": {}, + "globalFilters": [ + { + "id": "55555555-5555-5555-5555-555555555555", + "type": "date", + "label": "Period", + "defaultValue": "last_90_days" + }, + { + "id": "11111111-1111-1111-1111-111111111111", + "type": "relation", + "label": "Salesperson", + "defaultValueDisplayNames": [], + "modelName": "res.users" + }, + { + "id": "22222222-2222-2222-2222-222222222222", + "type": "relation", + "label": "Sales Team", + "defaultValueDisplayNames": [], + "modelName": "crm.team" + }, + { + "id": "33333333-3333-3333-3333-333333333333", + "type": "relation", + "label": "Customer", + "defaultValueDisplayNames": [], + "modelName": "res.partner" + }, + { + "id": "44444444-4444-4444-4444-444444444444", + "type": "relation", + "label": "Template", + "defaultValueDisplayNames": [], + "modelName": "sale.subscription.template" + } + ], + "lists": {}, + "listNextId": 1, + "chartOdooMenusReferences": { + "dddddddd-0000-0000-0000-000000000001": "subscription_oca.sale_subscription_menu", + "dddddddd-0000-0000-0000-000000000002": "subscription_oca.sale_subscription_menu" + } +} diff --git a/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json b/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json new file mode 100644 index 00000000..01670c5a --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json @@ -0,0 +1,691 @@ +{ + "version": "18.5.10", + "sheets": [ + { + "id": "dashboard", + "name": "Dashboard", + "colNumber": 22, + "rowNumber": 80, + "rows": {}, + "cols": { + "0": { + "size": 50 + }, + "1": { + "size": 50 + }, + "2": { + "size": 50 + }, + "3": { + "size": 50 + }, + "4": { + "size": 50 + }, + "5": { + "size": 50 + }, + "6": { + "size": 50 + }, + "7": { + "size": 50 + }, + "8": { + "size": 50 + }, + "9": { + "size": 50 + }, + "10": { + "size": 50 + }, + "11": { + "size": 50 + }, + "12": { + "size": 50 + }, + "13": { + "size": 50 + }, + "14": { + "size": 50 + }, + "15": { + "size": 50 + }, + "16": { + "size": 50 + }, + "17": { + "size": 50 + }, + "18": { + "size": 50 + }, + "19": { + "size": 50 + }, + "20": { + "size": 50 + }, + "21": { + "size": 50 + } + }, + "merges": [], + "cells": {}, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [ + { + "id": "bbbbbbbb-0000-0000-0000-000000000001", + "width": 345, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Monthly Recurring Revenue", + "color": "#1f2937", + "bold": true + }, + "background": "#FFF7ED", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "Data!C2", + "humanize": false, + "keyValue": "Data!C1", + "chartId": "bbbbbbbb-0000-0000-0000-000000000001", + "baselineDescr": { + "text": "ARR" + } + }, + "offset": { + "x": 16, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000002", + "width": 345, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Active Subscriptions", + "color": "#1f2937", + "bold": true + }, + "background": "#F0FDF4", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C3", + "chartId": "bbbbbbbb-0000-0000-0000-000000000002" + }, + "offset": { + "x": 377, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000003", + "width": 345, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Avg MRR / Subscription", + "color": "#1f2937", + "bold": true + }, + "background": "#FAF5FF", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C4", + "chartId": "bbbbbbbb-0000-0000-0000-000000000003" + }, + "offset": { + "x": 738, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000010", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Salesperson" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["user_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["user_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "bbbbbbbb-0000-0000-0000-000000000010", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 16, + "y": 172 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000011", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR share by Salesperson" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["user_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["user_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "bbbbbbbb-0000-0000-0000-000000000011", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 558, + "y": 172 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000012", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Subscriptions by Salesperson" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["user_id"], + "measure": "__count", + "order": null, + "resModel": "sale.subscription.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["user_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "bbbbbbbb-0000-0000-0000-000000000012", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 16, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000013", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Sales Team" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["crm_team_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["crm_team_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "bbbbbbbb-0000-0000-0000-000000000013", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 558, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000014", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Subscriptions by Sales Team" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["crm_team_id"], + "measure": "__count", + "order": null, + "resModel": "sale.subscription.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["crm_team_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "bbbbbbbb-0000-0000-0000-000000000014", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 16, + "y": 932 + }, + "col": 0, + "row": 0 + }, + { + "id": "bbbbbbbb-0000-0000-0000-000000000015", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Salesperson & Template" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["user_id", "template_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["user_id", "template_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "bbbbbbbb-0000-0000-0000-000000000015", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "stacked": true + }, + "offset": { + "x": 558, + "y": 932 + }, + "col": 0, + "row": 0 + } + ], + "tables": [], + "areGridLinesVisible": false, + "isVisible": true, + "headerGroups": [], + "comments": {} + }, + { + "id": "data", + "name": "Data", + "colNumber": 8, + "rowNumber": 30, + "rows": {}, + "cols": {}, + "merges": [], + "cells": { + "A1": "=_t(\"Salesperson KPIs\")", + "B1": "=PIVOT.VALUE(1,\"recurring_monthly:sum\")", + "B2": "=PIVOT.VALUE(1,\"recurring_yearly:sum\")", + "B3": "=PIVOT.VALUE(1,\"__count\")", + "B4": "=IFERROR(B1/B3,0)", + "C1": "=IFERROR(FORMAT.LARGE.NUMBER(B1))", + "C2": "=IFERROR(FORMAT.LARGE.NUMBER(B2))", + "C3": "=IFERROR(FORMAT.LARGE.NUMBER(B3))", + "C4": "=IFERROR(FORMAT.LARGE.NUMBER(B4))" + }, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [], + "tables": [], + "areGridLinesVisible": true, + "isVisible": false, + "headerGroups": [], + "comments": {} + } + ], + "styles": {}, + "formats": {}, + "borders": {}, + "revisionId": "START_REVISION", + "uniqueFigureIds": true, + "settings": { + "locale": { + "name": "English (US)", + "code": "en_US", + "thousandsSeparator": ",", + "decimalSeparator": ".", + "dateFormat": "m/d/yyyy", + "timeFormat": "hh:mm:ss a", + "formulaArgSeparator": ",", + "weekStart": 7 + } + }, + "pivots": { + "1": { + "type": "ODOO", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "context": {}, + "domain": [["in_progress", "=", true]], + "id": "1", + "measures": [ + { + "id": "recurring_monthly:sum", + "fieldName": "recurring_monthly", + "aggregator": "sum" + }, + { + "id": "recurring_yearly:sum", + "fieldName": "recurring_yearly", + "aggregator": "sum" + }, + { + "id": "__count", + "fieldName": "__count" + } + ], + "model": "sale.subscription.report", + "name": "KPIs 1", + "sortedColumn": null, + "formulaId": "1", + "columns": [], + "rows": [] + } + }, + "pivotNextId": 2, + "customTableStyles": {}, + "globalFilters": [ + { + "id": "55555555-5555-5555-5555-555555555555", + "type": "date", + "label": "Period", + "defaultValue": "last_90_days" + }, + { + "id": "11111111-1111-1111-1111-111111111111", + "type": "relation", + "label": "Salesperson", + "defaultValueDisplayNames": [], + "modelName": "res.users" + }, + { + "id": "22222222-2222-2222-2222-222222222222", + "type": "relation", + "label": "Sales Team", + "defaultValueDisplayNames": [], + "modelName": "crm.team" + }, + { + "id": "33333333-3333-3333-3333-333333333333", + "type": "relation", + "label": "Customer", + "defaultValueDisplayNames": [], + "modelName": "res.partner" + }, + { + "id": "44444444-4444-4444-4444-444444444444", + "type": "relation", + "label": "Template", + "defaultValueDisplayNames": [], + "modelName": "sale.subscription.template" + } + ], + "lists": {}, + "listNextId": 1, + "chartOdooMenusReferences": { + "bbbbbbbb-0000-0000-0000-000000000001": "subscription_oca.sale_subscription_menu", + "bbbbbbbb-0000-0000-0000-000000000002": "subscription_oca.sale_subscription_menu", + "bbbbbbbb-0000-0000-0000-000000000003": "subscription_oca.sale_subscription_menu" + } +} diff --git a/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json b/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json new file mode 100644 index 00000000..534b5415 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json @@ -0,0 +1,718 @@ +{ + "version": "18.5.10", + "sheets": [ + { + "id": "dashboard", + "name": "Dashboard", + "colNumber": 22, + "rowNumber": 80, + "rows": {}, + "cols": { + "0": { + "size": 50 + }, + "1": { + "size": 50 + }, + "2": { + "size": 50 + }, + "3": { + "size": 50 + }, + "4": { + "size": 50 + }, + "5": { + "size": 50 + }, + "6": { + "size": 50 + }, + "7": { + "size": 50 + }, + "8": { + "size": 50 + }, + "9": { + "size": 50 + }, + "10": { + "size": 50 + }, + "11": { + "size": 50 + }, + "12": { + "size": 50 + }, + "13": { + "size": 50 + }, + "14": { + "size": 50 + }, + "15": { + "size": 50 + }, + "16": { + "size": 50 + }, + "17": { + "size": 50 + }, + "18": { + "size": 50 + }, + "19": { + "size": 50 + }, + "20": { + "size": 50 + }, + "21": { + "size": 50 + } + }, + "merges": [], + "cells": {}, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [ + { + "id": "aaaaaaaa-0000-0000-0000-000000000001", + "width": 255, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Monthly Recurring Revenue", + "color": "#1f2937", + "bold": true + }, + "background": "#FFF7ED", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "Data!C2", + "humanize": false, + "keyValue": "Data!C1", + "chartId": "aaaaaaaa-0000-0000-0000-000000000001", + "baselineDescr": { + "text": "ARR" + } + }, + "offset": { + "x": 16, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000002", + "width": 255, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Annual Recurring Revenue", + "color": "#1f2937", + "bold": true + }, + "background": "#EFF6FF", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C2", + "chartId": "aaaaaaaa-0000-0000-0000-000000000002" + }, + "offset": { + "x": 287, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000003", + "width": 255, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Active Subscriptions", + "color": "#1f2937", + "bold": true + }, + "background": "#F0FDF4", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C3", + "chartId": "aaaaaaaa-0000-0000-0000-000000000003" + }, + "offset": { + "x": 558, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000004", + "width": 255, + "height": 132, + "tag": "chart", + "data": { + "type": "scorecard", + "title": { + "text": "Avg MRR / Subscription", + "color": "#1f2937", + "bold": true + }, + "background": "#FAF5FF", + "baselineColorUp": "#00A04A", + "baselineColorDown": "#DC6965", + "baselineMode": "text", + "baseline": "", + "humanize": false, + "keyValue": "Data!C4", + "chartId": "aaaaaaaa-0000-0000-0000-000000000004" + }, + "offset": { + "x": 829, + "y": 16 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000010", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Template" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["template_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["template_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "aaaaaaaa-0000-0000-0000-000000000010", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 16, + "y": 172 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000011", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Start Month" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["date_start:month"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "line" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["date_start:month"], + "orderBy": [] + }, + "type": "odoo_line", + "dataSets": [{}], + "chartId": "aaaaaaaa-0000-0000-0000-000000000011", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 558, + "y": 172 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000012", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Product Category" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["categ_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["categ_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "aaaaaaaa-0000-0000-0000-000000000012", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 16, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000013", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Sales Team" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["crm_team_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["crm_team_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "aaaaaaaa-0000-0000-0000-000000000013", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 558, + "y": 552 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000014", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "MRR by Salesperson" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["user_id"], + "measure": "recurring_monthly", + "order": null, + "resModel": "sale.subscription.report", + "mode": "pie" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["user_id"], + "orderBy": [] + }, + "type": "odoo_pie", + "dataSets": [{}], + "chartId": "aaaaaaaa-0000-0000-0000-000000000014", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + } + }, + "offset": { + "x": 16, + "y": 932 + }, + "col": 0, + "row": 0 + }, + { + "id": "aaaaaaaa-0000-0000-0000-000000000015", + "width": 526, + "height": 360, + "tag": "chart", + "data": { + "title": { + "text": "Subscriptions by Stage" + }, + "background": "#FFFFFF", + "legendPosition": "top", + "metaData": { + "groupBy": ["stage_id"], + "measure": "__count", + "order": null, + "resModel": "sale.subscription.report", + "mode": "bar" + }, + "searchParams": { + "comparison": null, + "context": {}, + "domain": [["in_progress", "=", true]], + "groupBy": ["stage_id"], + "orderBy": [] + }, + "type": "odoo_bar", + "dataSets": [{}], + "chartId": "aaaaaaaa-0000-0000-0000-000000000015", + "actionXmlId": "subscription_oca.sale_subscription_report_action", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "stacked": false + }, + "offset": { + "x": 558, + "y": 932 + }, + "col": 0, + "row": 0 + } + ], + "tables": [], + "areGridLinesVisible": false, + "isVisible": true, + "headerGroups": [], + "comments": {} + }, + { + "id": "data", + "name": "Data", + "colNumber": 8, + "rowNumber": 30, + "rows": {}, + "cols": {}, + "merges": [], + "cells": { + "A1": "=_t(\"Subscription KPIs\")", + "B1": "=PIVOT.VALUE(1,\"recurring_monthly:sum\")", + "B2": "=PIVOT.VALUE(1,\"recurring_yearly:sum\")", + "B3": "=PIVOT.VALUE(1,\"__count\")", + "B4": "=IFERROR(B1/B3,0)", + "C1": "=IFERROR(FORMAT.LARGE.NUMBER(B1))", + "C2": "=IFERROR(FORMAT.LARGE.NUMBER(B2))", + "C3": "=IFERROR(FORMAT.LARGE.NUMBER(B3))", + "C4": "=IFERROR(FORMAT.LARGE.NUMBER(B4))" + }, + "styles": {}, + "formats": {}, + "borders": {}, + "conditionalFormats": [], + "dataValidationRules": [], + "figures": [], + "tables": [], + "areGridLinesVisible": true, + "isVisible": false, + "headerGroups": [], + "comments": {} + } + ], + "styles": {}, + "formats": {}, + "borders": {}, + "revisionId": "START_REVISION", + "uniqueFigureIds": true, + "settings": { + "locale": { + "name": "English (US)", + "code": "en_US", + "thousandsSeparator": ",", + "decimalSeparator": ".", + "dateFormat": "m/d/yyyy", + "timeFormat": "hh:mm:ss a", + "formulaArgSeparator": ",", + "weekStart": 7 + } + }, + "pivots": { + "1": { + "type": "ODOO", + "fieldMatching": { + "11111111-1111-1111-1111-111111111111": { + "chain": "user_id", + "type": "many2one" + }, + "22222222-2222-2222-2222-222222222222": { + "chain": "crm_team_id", + "type": "many2one" + }, + "33333333-3333-3333-3333-333333333333": { + "chain": "partner_id", + "type": "many2one" + }, + "44444444-4444-4444-4444-444444444444": { + "chain": "template_id", + "type": "many2one" + }, + "55555555-5555-5555-5555-555555555555": { + "chain": "date_start", + "type": "datetime", + "offset": 0 + } + }, + "context": {}, + "domain": [["in_progress", "=", true]], + "id": "1", + "measures": [ + { + "id": "recurring_monthly:sum", + "fieldName": "recurring_monthly", + "aggregator": "sum" + }, + { + "id": "recurring_yearly:sum", + "fieldName": "recurring_yearly", + "aggregator": "sum" + }, + { + "id": "__count", + "fieldName": "__count" + } + ], + "model": "sale.subscription.report", + "name": "KPIs 1", + "sortedColumn": null, + "formulaId": "1", + "columns": [], + "rows": [] + } + }, + "pivotNextId": 2, + "customTableStyles": {}, + "globalFilters": [ + { + "id": "55555555-5555-5555-5555-555555555555", + "type": "date", + "label": "Period", + "defaultValue": "last_90_days" + }, + { + "id": "11111111-1111-1111-1111-111111111111", + "type": "relation", + "label": "Salesperson", + "defaultValueDisplayNames": [], + "modelName": "res.users" + }, + { + "id": "22222222-2222-2222-2222-222222222222", + "type": "relation", + "label": "Sales Team", + "defaultValueDisplayNames": [], + "modelName": "crm.team" + }, + { + "id": "33333333-3333-3333-3333-333333333333", + "type": "relation", + "label": "Customer", + "defaultValueDisplayNames": [], + "modelName": "res.partner" + }, + { + "id": "44444444-4444-4444-4444-444444444444", + "type": "relation", + "label": "Template", + "defaultValueDisplayNames": [], + "modelName": "sale.subscription.template" + } + ], + "lists": {}, + "listNextId": 1, + "chartOdooMenusReferences": { + "aaaaaaaa-0000-0000-0000-000000000001": "subscription_oca.sale_subscription_menu", + "aaaaaaaa-0000-0000-0000-000000000002": "subscription_oca.sale_subscription_menu", + "aaaaaaaa-0000-0000-0000-000000000003": "subscription_oca.sale_subscription_menu", + "aaaaaaaa-0000-0000-0000-000000000004": "subscription_oca.sale_subscription_menu" + } +} diff --git a/spreadsheet_dashboard_subscription_oca/data/spreadsheet_dashboards.xml b/spreadsheet_dashboard_subscription_oca/data/spreadsheet_dashboards.xml new file mode 100644 index 00000000..4bad0df6 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/data/spreadsheet_dashboards.xml @@ -0,0 +1,114 @@ + + + + Subscriptions + 150 + + + + Subscriptions + + + + + 10 + True + + + + Salesperson + + + + + 20 + True + + + + MRR Evolution + + + + + 30 + True + + + + Retention + + + + + 40 + True + + diff --git a/spreadsheet_dashboard_subscription_oca/i18n/es.po b/spreadsheet_dashboard_subscription_oca/i18n/es.po new file mode 100644 index 00000000..7fc246f4 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/i18n/es.po @@ -0,0 +1,429 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * spreadsheet_dashboard_subscription_oca +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 19.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-06-22 17:34+0000\n" +"PO-Revision-Date: 2026-06-22 17:34+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "ARR" +msgstr "ARR" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Active Subscriptions" +msgstr "Suscripciones activas" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Annual Recurring Revenue" +msgstr "Ingresos recurrentes anuales" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Avg MRR / Subscription" +msgstr "MRR medio / suscripción" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields.selection,name:spreadsheet_dashboard_subscription_oca.selection__sale_subscription_mrr_report__event_type__churn +msgid "Churn" +msgstr "Baja" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "Churned MRR (all time)" +msgstr "MRR perdido (histórico)" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__cohort_date +msgid "Cohort (start month)" +msgstr "Cohorte (mes de inicio)" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "Cohort MRR by Template" +msgstr "MRR de cohorte por plantilla" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__user_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__user_id +msgid "Commercial agent" +msgstr "Comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__company_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__company_id +msgid "Company" +msgstr "Compañía" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__company_currency_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__company_currency_id +msgid "Company Currency" +msgstr "Divisa de la compañía" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__partner_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__partner_id +msgid "Customer" +msgstr "Cliente" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__display_name +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__event_date +msgid "Event date" +msgstr "Fecha del evento" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__event_type +msgid "Event type" +msgstr "Tipo de evento" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__id +msgid "ID" +msgstr "ID" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "MRR Change by Month & Type" +msgstr "Variación de MRR por mes y tipo" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "MRR Change by Type" +msgstr "Variación de MRR por tipo" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:spreadsheet.dashboard,name:spreadsheet_dashboard_subscription_oca.spreadsheet_dashboard_subscription_oca_mrr_evolution +msgid "MRR Evolution" +msgstr "Evolución del MRR" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "MRR KPIs" +msgstr "KPIs de MRR" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "MRR at Start" +msgstr "MRR inicial" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "MRR by Cohort (start month)" +msgstr "MRR por cohorte (mes de inicio)" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "MRR by Product Category" +msgstr "MRR por categoría de producto" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "MRR by Sales Team" +msgstr "MRR por equipo de ventas" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "MRR by Salesperson" +msgstr "MRR por comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +msgid "MRR by Salesperson & Template" +msgstr "MRR por comercial y plantilla" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "MRR by Start Month" +msgstr "MRR por mes de inicio" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "MRR by Template" +msgstr "MRR por plantilla" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__mrr_change +msgid "MRR change" +msgstr "Variación de MRR" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +msgid "MRR share by Salesperson" +msgstr "Reparto de MRR por comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Monthly Recurring Revenue" +msgstr "Ingresos recurrentes mensuales" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__recurring_monthly +msgid "Monthly recurring revenue" +msgstr "Ingresos recurrentes mensuales" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__period_index +msgid "Months since start" +msgstr "Meses desde el inicio" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "Net MRR" +msgstr "MRR neto" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "Net MRR Over Time" +msgstr "MRR neto a lo largo del tiempo" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields.selection,name:spreadsheet_dashboard_subscription_oca.selection__sale_subscription_mrr_report__event_type__new +msgid "New" +msgstr "Alta" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "New MRR (all time)" +msgstr "MRR nuevo (histórico)" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "New MRR by Salesperson" +msgstr "MRR nuevo por comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +msgid "New MRR by Template" +msgstr "MRR nuevo por plantilla" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:spreadsheet.dashboard,name:spreadsheet_dashboard_subscription_oca.spreadsheet_dashboard_subscription_oca_retention +msgid "Retention" +msgstr "Retención" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "Retention Curve (active subscriptions by month since start)" +msgstr "Curva de retención (suscripciones activas por mes desde el inicio)" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "Retention KPIs" +msgstr "KPIs de retención" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__crm_team_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__crm_team_id +msgid "Sale team" +msgstr "Equipo de ventas" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Sales Team" +msgstr "Equipo de ventas" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: model:spreadsheet.dashboard,name:spreadsheet_dashboard_subscription_oca.spreadsheet_dashboard_subscription_oca_salesperson +msgid "Salesperson" +msgstr "Comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +msgid "Salesperson KPIs" +msgstr "KPIs de comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__subscription_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__subscription_id +msgid "Subscription" +msgstr "Suscripción" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Subscription KPIs" +msgstr "KPIs de suscripciones" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model,name:spreadsheet_dashboard_subscription_oca.model_sale_subscription_mrr_report +msgid "Subscription MRR Evolution" +msgstr "Evolución del MRR de suscripciones" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model,name:spreadsheet_dashboard_subscription_oca.model_sale_subscription_retention_report +msgid "Subscription Retention" +msgstr "Retención de suscripciones" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_mrr_report__template_id +#: model:ir.model.fields,field_description:spreadsheet_dashboard_subscription_oca.field_sale_subscription_retention_report__template_id +msgid "Subscription template" +msgstr "Plantilla de suscripción" + +#. module: spreadsheet_dashboard_subscription_oca +#: model:spreadsheet.dashboard,name:spreadsheet_dashboard_subscription_oca.spreadsheet_dashboard_subscription_oca_subscriptions +#: model:spreadsheet.dashboard.group,name:spreadsheet_dashboard_subscription_oca.spreadsheet_dashboard_group_subscription_oca +msgid "Subscriptions" +msgstr "Suscripciones" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "Subscriptions (cohorts)" +msgstr "Suscripciones (cohortes)" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +msgid "Subscriptions by Cohort (start month)" +msgstr "Suscripciones por cohorte (mes de inicio)" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +msgid "Subscriptions by Sales Team" +msgstr "Suscripciones por equipo de ventas" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +msgid "Subscriptions by Salesperson" +msgstr "Suscripciones por comercial" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Subscriptions by Stage" +msgstr "Suscripciones por etapa" + +#. module: spreadsheet_dashboard_subscription_oca +#. odoo-javascript +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/Domatix/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/mrr_evolution_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/retention_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/salesperson_dashboard.osheet.json:0 +#: code:addons/spreadsheet_dashboard_subscription_oca/data/files/subscriptions_dashboard.osheet.json:0 +msgid "Template" +msgstr "Plantilla" diff --git a/spreadsheet_dashboard_subscription_oca/models/__init__.py b/spreadsheet_dashboard_subscription_oca/models/__init__.py new file mode 100644 index 00000000..115ccbd7 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/models/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2026 Domatix - Alvaro Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import sale_subscription_mrr_report +from . import sale_subscription_retention_report diff --git a/spreadsheet_dashboard_subscription_oca/models/sale_subscription_mrr_report.py b/spreadsheet_dashboard_subscription_oca/models/sale_subscription_mrr_report.py new file mode 100644 index 00000000..39103a2e --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/models/sale_subscription_mrr_report.py @@ -0,0 +1,91 @@ +# Copyright 2026 Domatix - Alvaro Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models, tools + + +class SaleSubscriptionMrrReport(models.Model): + """MRR change events derived from the current state of the subscriptions. + + There is no stored MRR event log in ``subscription_oca``. This SQL view + reconstructs an approximate one from what we do have: a positive ``new`` + event at the start date of every subscription and a negative ``churn`` + event at the closing date of the closed ones (the end date when set, + otherwise the last write date as a fallback). Cumulating ``mrr_change`` + over time therefore yields the net active MRR. Mid-life expansion and + contraction are not tracked (that would require a real event log). + """ + + _name = "sale.subscription.mrr.report" + _description = "Subscription MRR Evolution" + _auto = False + _rec_name = "subscription_id" + _order = "event_date desc" + + subscription_id = fields.Many2one( + comodel_name="sale.subscription", string="Subscription", readonly=True + ) + partner_id = fields.Many2one( + comodel_name="res.partner", string="Customer", readonly=True + ) + template_id = fields.Many2one( + comodel_name="sale.subscription.template", + string="Subscription template", + readonly=True, + ) + user_id = fields.Many2one( + comodel_name="res.users", string="Commercial agent", readonly=True + ) + crm_team_id = fields.Many2one( + comodel_name="crm.team", string="Sale team", readonly=True + ) + company_id = fields.Many2one( + comodel_name="res.company", string="Company", readonly=True + ) + company_currency_id = fields.Many2one( + comodel_name="res.currency", string="Company Currency", readonly=True + ) + event_date = fields.Date(string="Event date", readonly=True) + event_type = fields.Selection( + [("new", "New"), ("churn", "Churn")], + string="Event type", + readonly=True, + ) + mrr_change = fields.Monetary( + string="MRR change", + currency_field="company_currency_id", + readonly=True, + ) + + def _query(self): + return """ + SELECT + (sub.id * 2 + ev.n) AS id, + sub.id AS subscription_id, + sub.partner_id AS partner_id, + sub.template_id AS template_id, + sub.user_id AS user_id, + sub.crm_team_id AS crm_team_id, + sub.company_id AS company_id, + sub.company_currency_id AS company_currency_id, + ev.event_date AS event_date, + ev.event_type AS event_type, + ev.mrr_change AS mrr_change + FROM sale_subscription sub + LEFT JOIN sale_subscription_stage stage + ON stage.id = sub.stage_id + CROSS JOIN LATERAL ( + VALUES + (0, sub.date_start, 'new', sub.recurring_monthly), + (1, COALESCE(sub.date, sub.write_date::date), 'churn', + -sub.recurring_monthly) + ) AS ev(n, event_date, event_type, mrr_change) + WHERE sub.active = TRUE + AND ev.event_date IS NOT NULL + AND (ev.event_type = 'new' OR stage.type = 'post') + """ + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute( + f"CREATE OR REPLACE VIEW {self._table} AS ({self._query()})" + ) diff --git a/spreadsheet_dashboard_subscription_oca/models/sale_subscription_retention_report.py b/spreadsheet_dashboard_subscription_oca/models/sale_subscription_retention_report.py new file mode 100644 index 00000000..90d19341 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/models/sale_subscription_retention_report.py @@ -0,0 +1,96 @@ +# Copyright 2026 Domatix - Alvaro Domatix +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models, tools + + +class SaleSubscriptionRetentionReport(models.Model): + """Retention cohorts derived from the current state of the subscriptions. + + Each subscription is expanded into one row per elapsed month between its + start date and either its closing date (for churned ones) or today (for + the ones still running). Grouping by ``cohort_date`` (the start month) and + ``period_index`` (months since the start) gives a retention/survival matrix + without needing a stored event log. + """ + + _name = "sale.subscription.retention.report" + _description = "Subscription Retention" + _auto = False + _rec_name = "subscription_id" + _order = "cohort_date desc, period_index" + + subscription_id = fields.Many2one( + comodel_name="sale.subscription", string="Subscription", readonly=True + ) + partner_id = fields.Many2one( + comodel_name="res.partner", string="Customer", readonly=True + ) + template_id = fields.Many2one( + comodel_name="sale.subscription.template", + string="Subscription template", + readonly=True, + ) + user_id = fields.Many2one( + comodel_name="res.users", string="Commercial agent", readonly=True + ) + crm_team_id = fields.Many2one( + comodel_name="crm.team", string="Sale team", readonly=True + ) + company_id = fields.Many2one( + comodel_name="res.company", string="Company", readonly=True + ) + company_currency_id = fields.Many2one( + comodel_name="res.currency", string="Company Currency", readonly=True + ) + cohort_date = fields.Date(string="Cohort (start month)", readonly=True) + period_index = fields.Integer(string="Months since start", readonly=True) + recurring_monthly = fields.Monetary( + string="Monthly recurring revenue", + currency_field="company_currency_id", + readonly=True, + ) + + def _query(self): + return """ + SELECT + (sub.id * 1000 + gs.idx) AS id, + sub.id AS subscription_id, + sub.partner_id AS partner_id, + sub.template_id AS template_id, + sub.user_id AS user_id, + sub.crm_team_id AS crm_team_id, + sub.company_id AS company_id, + sub.company_currency_id AS company_currency_id, + date_trunc('month', sub.date_start)::date AS cohort_date, + gs.idx AS period_index, + sub.recurring_monthly AS recurring_monthly + FROM sale_subscription sub + LEFT JOIN sale_subscription_stage stage + ON stage.id = sub.stage_id + CROSS JOIN LATERAL ( + SELECT CASE + WHEN stage.type = 'post' + THEN COALESCE(sub.date, sub.write_date::date) + ELSE CURRENT_DATE + END AS d + ) AS ref + CROSS JOIN LATERAL generate_series( + 0, + LEAST( + GREATEST(0, ( + EXTRACT(YEAR FROM age(ref.d, sub.date_start)) * 12 + + EXTRACT(MONTH FROM age(ref.d, sub.date_start)) + )::int), + 60 + ) + ) AS gs(idx) + WHERE sub.active = TRUE + AND sub.date_start IS NOT NULL + AND sub.date_start <= CURRENT_DATE + """ + + def init(self): + tools.drop_view_if_exists(self.env.cr, self._table) + self.env.cr.execute( + f"CREATE OR REPLACE VIEW {self._table} AS ({self._query()})" + ) diff --git a/spreadsheet_dashboard_subscription_oca/pyproject.toml b/spreadsheet_dashboard_subscription_oca/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/spreadsheet_dashboard_subscription_oca/readme/DESCRIPTION.md b/spreadsheet_dashboard_subscription_oca/readme/DESCRIPTION.md new file mode 100644 index 00000000..3dd1d979 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/readme/DESCRIPTION.md @@ -0,0 +1,22 @@ +This module adds spreadsheet dashboards for subscriptions, built on top of the +community ``spreadsheet_dashboard`` engine and the analysis models provided by +``subscription_oca``. No enterprise dependency is required. + +It ships four ready-to-use dashboards under the **Dashboards** application, in a +dedicated *Subscriptions* group: + +* **Subscriptions**: monthly/annual recurring revenue, active subscriptions and + average MRR, with breakdowns by template, product category, sales team, + salesperson, start month and stage. +* **Salesperson**: recurring revenue and number of subscriptions broken down by + salesperson and sales team. +* **MRR Evolution**: net/new/churned MRR and the cumulated MRR over time, with a + monthly new-vs-churn breakdown. MRR change events are derived from the current + state of the subscriptions (a positive event at the start date and a negative + one at the closing date); mid-life expansion/contraction is not tracked, which + would require a dedicated MRR event log. +* **Retention**: cohort sizes and recurring revenue per start month, plus a + retention/survival curve built from the start and closing dates. + +All dashboards expose global filters (salesperson, sales team, customer, +template) and refresh automatically from the subscription analysis models. diff --git a/spreadsheet_dashboard_subscription_oca/readme/USAGE.md b/spreadsheet_dashboard_subscription_oca/readme/USAGE.md new file mode 100644 index 00000000..b8746d15 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/readme/USAGE.md @@ -0,0 +1,6 @@ +Open the **Dashboards** application. The four dashboards are available in the +*Subscriptions* group. Use the filters at the top (salesperson, sales team, +customer, template) to narrow down the figures. The data is aggregated from the +``sale.subscription.report``, ``sale.subscription.mrr.report`` and +``sale.subscription.retention.report`` analysis models and refreshes +automatically. diff --git a/spreadsheet_dashboard_subscription_oca/report/sql_report_views.xml b/spreadsheet_dashboard_subscription_oca/report/sql_report_views.xml new file mode 100644 index 00000000..5be5f5b1 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/report/sql_report_views.xml @@ -0,0 +1,249 @@ + + + + + sale.subscription.mrr.report.search + sale.subscription.mrr.report + + + + + + + + + + + + + + + + + + + + + + + sale.subscription.mrr.report.graph + sale.subscription.mrr.report + + + + + + + + + + sale.subscription.mrr.report.pivot + sale.subscription.mrr.report + + + + + + + + + + + sale.subscription.mrr.report.list + sale.subscription.mrr.report + + + + + + + + + + + + + + + + + + MRR Evolution + sale.subscription.mrr.report + graph,pivot,list + + {"search_default_groupby_event_date": 1} + +

+ No MRR events yet +

+

+ Reconstruction of the monthly recurring revenue changes over + time: a "new" event when a subscription starts and a "churn" + event when one is closed. Cumulate it to see the net active MRR. +

+
+
+ + + + sale.subscription.retention.report.search + sale.subscription.retention.report + + + + + + + + + + + + + + + + + + + sale.subscription.retention.report.graph + sale.subscription.retention.report + + + + + + + + + + sale.subscription.retention.report.pivot + sale.subscription.retention.report + + + + + + + + + + + sale.subscription.retention.report.list + sale.subscription.retention.report + + + + + + + + + + + + + + + + + + Retention Analysis + sale.subscription.retention.report + pivot,graph,list + + {"search_default_groupby_cohort_date": 1} + +

+ No cohorts yet +

+

+ Retention cohorts built from the current subscriptions. Each + cohort groups the subscriptions that started the same month and + tracks the still-active recurring revenue over the following + months. +

+
+
+ + + + + +
diff --git a/spreadsheet_dashboard_subscription_oca/security/ir.model.access.csv b/spreadsheet_dashboard_subscription_oca/security/ir.model.access.csv new file mode 100644 index 00000000..1c9192e8 --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sale_subscription_mrr_report,sale.subscription.mrr.report,model_sale_subscription_mrr_report,sales_team.group_sale_salesman,1,0,0,0 +access_sale_subscription_retention_report,sale.subscription.retention.report,model_sale_subscription_retention_report,sales_team.group_sale_salesman,1,0,0,0 diff --git a/spreadsheet_dashboard_subscription_oca/static/description/index.html b/spreadsheet_dashboard_subscription_oca/static/description/index.html new file mode 100644 index 00000000..57e5f94c --- /dev/null +++ b/spreadsheet_dashboard_subscription_oca/static/description/index.html @@ -0,0 +1,457 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Subscription OCA Spreadsheet Dashboards

+ +

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

+

This module adds spreadsheet dashboards for subscriptions, built on top +of the community spreadsheet_dashboard engine and the analysis +models provided by subscription_oca. No enterprise dependency is +required.

+

It ships four ready-to-use dashboards under the Dashboards +application, in a dedicated Subscriptions group:

+
    +
  • Subscriptions: monthly/annual recurring revenue, active +subscriptions and average MRR, with breakdowns by template, product +category, sales team, salesperson, start month and stage.
  • +
  • Salesperson: recurring revenue and number of subscriptions broken +down by salesperson and sales team.
  • +
  • MRR Evolution: net/new/churned MRR and the cumulated MRR over +time, with a monthly new-vs-churn breakdown. MRR change events are +derived from the current state of the subscriptions (a positive event +at the start date and a negative one at the closing date); mid-life +expansion/contraction is not tracked, which would require a dedicated +MRR event log.
  • +
  • Retention: cohort sizes and recurring revenue per start month, +plus a retention/survival curve built from the start and closing +dates.
  • +
+

All dashboards expose global filters (salesperson, sales team, customer, +template) and refresh automatically from the subscription analysis +models.

+

Table of contents

+ +
+

Usage

+

Open the Dashboards application. The four dashboards are available +in the Subscriptions group. Use the filters at the top (salesperson, +sales team, customer, template) to narrow down the figures. The data is +aggregated from the sale.subscription.report, +sale.subscription.mrr.report and +sale.subscription.retention.report analysis models and refreshes +automatically.

+
+
+

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
  • +
+
+
+

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.

+

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.

+
+
+
+
+ +