Merged PR 4443: First version of the aggregated model for YTD/MTD Overview

# Description

First version of the model int_ytd_mtd_aggregated_main_metrics_overview

It aggregates data at the level of:
* Date
* Dimension
* Dimension Value
* Metric Name (or Id Metric)

This computes differences and relative differences in:
* current MTD vs previous month EOM
* current MTD vs previous year MTD
* current year YTD vs previous year YTD

This is applied to 13 metrics, namely:
* Total Revenue
* Revenue Retained Post-Resolutions
* Guest Revenue
* Invoiced Operator Revenue
* Invoiced APIs Revenue
* Billable Bookings
* Live Deals
* New Deals
* Churning Deals
* Damage Waiver Payout Rate
* Host Resolutions Payout Rate
* Invoiced Operator Revenue per Billable Booking
* Waiver Revenue per Billable Booking

This still does not handle:
* Comparison vs. targets (to be done later, need input)
* Missing metrics on Onboarding MRR / Revenue Churn (to be done later)
* Invoicing dependant data exclusion (to be done in reporting)

# Checklist

- [X] The edited models and dependants run properly with production data.
- [X] The edited models are sufficiently documented.
- [X] The edited models contain PK tests, and I've ran and passed them.
- [X] I have checked for DRY opportunities with other models and docs.
- [X] I've picked the right materialization for the affected models. **At the moment I keep everything as views and seems ok. We'll see if this needs to be materialised as tables later on**

# Other

- [ ] Check if a full-refresh is required after this PR is merged.

Related work items: #27609
This commit is contained in:
Oriol Roqué Paniagua 2025-02-18 15:45:24 +00:00
parent 073620bd3d
commit 7260368bad
2 changed files with 312 additions and 0 deletions

View file

@ -0,0 +1,171 @@
{% set metrics = [
{
"id_metric": 1,
"name": "Total Revenue",
"current_month_MTD": "current_month_mtd_total_revenue_in_gbp",
"previous_month_EOM": "previous_month_eom_total_revenue_in_gbp",
"previous_year_MTD": "previous_year_mtd_total_revenue_in_gbp",
"current_YTD": "current_ytd_total_revenue_in_gbp",
"previous_YTD": "previous_ytd_total_revenue_in_gbp",
"requires_invoicing_data": true,
},
{
"id_metric": 2,
"name": "Revenue Retained Post-Resolutions",
"current_month_MTD": "current_month_mtd_revenue_retained_post_resolutions_in_gbp",
"previous_month_EOM": "previous_month_eom_revenue_retained_post_resolutions_in_gbp",
"previous_year_MTD": "previous_year_mtd_revenue_retained_post_resolutions_in_gbp",
"current_YTD": "current_ytd_revenue_retained_post_resolutions_in_gbp",
"previous_YTD": "previous_ytd_revenue_retained_post_resolutions_in_gbp",
"requires_invoicing_data": true,
},
{
"id_metric": 3,
"name": "Guest Revenue",
"current_month_MTD": "current_month_mtd_total_guest_payments_in_gbp",
"previous_month_EOM": "previous_month_eom_total_guest_payments_in_gbp",
"previous_year_MTD": "previous_year_mtd_total_guest_payments_in_gbp",
"current_YTD": "current_ytd_total_guest_payments_in_gbp",
"previous_YTD": "previous_ytd_total_guest_payments_in_gbp",
"requires_invoicing_data": false,
},
{
"id_metric": 4,
"name": "Invoiced Operator Revenue",
"current_month_MTD": "current_month_mtd_xero_operator_net_fees_in_gbp",
"previous_month_EOM": "previous_month_eom_xero_operator_net_fees_in_gbp",
"previous_year_MTD": "previous_year_mtd_xero_operator_net_fees_in_gbp",
"current_YTD": "current_ytd_xero_operator_net_fees_in_gbp",
"previous_YTD": "previous_ytd_xero_operator_net_fees_in_gbp",
"requires_invoicing_data": true,
},
{
"id_metric": 5,
"name": "Invoiced APIs Revenue",
"current_month_MTD": "current_month_mtd_xero_apis_net_fees_in_gbp",
"previous_month_EOM": "previous_month_eom_xero_apis_net_fees_in_gbp",
"previous_year_MTD": "previous_year_mtd_xero_apis_net_fees_in_gbp",
"current_YTD": "current_ytd_xero_apis_net_fees_in_gbp",
"previous_YTD": "previous_ytd_xero_apis_net_fees_in_gbp",
"requires_invoicing_data": true,
},
{
"id_metric": 6,
"name": "Billable Bookings",
"current_month_MTD": "current_month_mtd_billable_bookings",
"previous_month_EOM": "previous_month_eom_billable_bookings",
"previous_year_MTD": "previous_year_mtd_billable_bookings",
"current_YTD": "current_ytd_billable_bookings",
"previous_YTD": "previous_ytd_billable_bookings",
"requires_invoicing_data": false,
},
{
"id_metric": 7,
"name": "Live Deals",
"current_month_MTD": "current_month_mtd_live_deals",
"previous_month_EOM": "previous_month_eom_live_deals",
"previous_year_MTD": "previous_year_mtd_live_deals",
"current_YTD": "current_ytd_live_deals",
"previous_YTD": "previous_ytd_live_deals",
"requires_invoicing_data": false,
},
{
"id_metric": 8,
"name": "New Deals",
"current_month_MTD": "current_month_mtd_new_deals",
"previous_month_EOM": "previous_month_eom_new_deals",
"previous_year_MTD": "previous_year_mtd_new_deals",
"current_YTD": "current_ytd_new_deals",
"previous_YTD": "previous_ytd_new_deals",
"requires_invoicing_data": false,
},
{
"id_metric": 9,
"name": "Churning Deals",
"current_month_MTD": "current_month_mtd_churning_deals",
"previous_month_EOM": "previous_month_eom_churning_deals",
"previous_year_MTD": "previous_year_mtd_churning_deals",
"current_YTD": "current_ytd_churning_deals",
"previous_YTD": "previous_ytd_churning_deals",
"requires_invoicing_data": false,
},
{
"id_metric": 10,
"name": "Damage Waiver Payout Rate",
"current_month_MTD": "current_month_mtd_waiver_payout_rate",
"previous_month_EOM": "previous_month_eom_waiver_payout_rate",
"previous_year_MTD": "previous_year_mtd_waiver_payout_rate",
"current_YTD": "current_ytd_waiver_payout_rate",
"previous_YTD": "previous_ytd_waiver_payout_rate",
"requires_invoicing_data": true,
},
{
"id_metric": 11,
"name": "Host Resolutions Payout Rate",
"current_month_MTD": "current_month_mtd_resolutions_payout_rate",
"previous_month_EOM": "previous_month_eom_resolutions_payout_rate",
"previous_year_MTD": "previous_year_mtd_resolutions_payout_rate",
"current_YTD": "current_ytd_resolutions_payout_rate",
"previous_YTD": "previous_ytd_resolutions_payout_rate",
"requires_invoicing_data": true,
},
{
"id_metric": 12,
"name": "Invoiced Operator Revenue per Billable Booking",
"current_month_MTD": "current_month_mtd_operator_revenue_per_billable_booking",
"previous_month_EOM": "previous_month_eom_operator_revenue_per_billable_booking",
"previous_year_MTD": "previous_year_mtd_operator_revenue_per_billable_booking",
"current_YTD": "current_ytd_operator_revenue_per_billable_booking",
"previous_YTD": "previous_ytd_operator_revenue_per_billable_booking",
"requires_invoicing_data": true,
},
{
"id_metric": 13,
"name": "Waiver Revenue per Billable Booking",
"current_month_MTD": "current_month_mtd_waiver_revenue_per_billable_booking",
"previous_month_EOM": "previous_month_eom_waiver_revenue_per_billable_booking",
"previous_year_MTD": "previous_year_mtd_waiver_revenue_per_billable_booking",
"current_YTD": "current_ytd_waiver_revenue_per_billable_booking",
"previous_YTD": "previous_ytd_waiver_revenue_per_billable_booking",
"requires_invoicing_data": false,
},
] %}
with
int_ytd_mtd_main_metrics_overview as (
select * from {{ ref("int_ytd_mtd_main_metrics_overview") }}
)
{% for metric in metrics %}
select
calendar_year,
financial_year,
date,
previous_year_date,
dimension,
dimension_value,
{{ metric.id_metric }} as id_metric,
-- quotation marks added because text format
'{{ metric.name }}' as metric_name,
{{ metric.requires_invoicing_data }} as requires_invoicing_data,
{{ metric.current_month_MTD }} as current_month_mtd,
{{ metric.previous_month_EOM }} as previous_month_eom,
{{ metric.previous_year_MTD }} as previous_year_mtd,
{{ metric.current_YTD }} as current_year_ytd,
{{ metric.previous_YTD }} as previous_year_ytd,
{{ metric.current_month_MTD }}
- {{ metric.previous_month_EOM }}
as diff_current_month_mtd_vs_previous_month_eom,
{{ metric.current_month_MTD }}
- {{ metric.previous_year_MTD }} as diff_current_month_mtd_vs_previous_year_mtd,
{{ metric.current_YTD }}
- {{ metric.previous_YTD }} as diff_current_ytd_vs_previous_ytd,
{{ metric.current_month_MTD }} / nullif({{ metric.previous_month_EOM }}, 0)
- 1 as rel_diff_current_month_mtd_vs_previous_month_eom,
{{ metric.current_month_MTD }} / nullif({{ metric.previous_year_MTD }}, 0)
- 1 as rel_diff_current_month_mtd_vs_previous_year_mtd,
{{ metric.current_YTD }} / nullif({{ metric.previous_YTD }}, 0)
- 1 as rel_diff_current_ytd_vs_previous_ytd
from int_ytd_mtd_main_metrics_overview
{% if not loop.last %}
union all
{% endif %}
{% endfor %}

View file

@ -2171,3 +2171,144 @@ models:
- name: previous_month_eom_xero_waiver_paid_back_to_host_in_gbp
data_type: numeric
description: Waiver amounts paid back to hosts via Xero for the previous month, at the end of the month in GBP.
- name: int_ytd_mtd_aggregated_main_metrics_overview
description: |
This model provides a high-level overview of the main metrics for the month-to-date
and financial year-to-date periods. Data is aggregated at metric level, and provides
evolutions current month MTD vs. previous month EOM, current month MTD vs. previous
year MTD and current YTD vs. previous YTD.
data_tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- date
- dimension
- dimension_value
- metric_name
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- date
- dimension
- dimension_value
- id_metric
columns:
- name: date
data_type: date
description: The date for the month-to-date and year-to-date metrics.
data_tests:
- not_null
- name: dimension
data_type: string
description: The dimension or granularity of the metrics.
data_tests:
- accepted_values:
values:
- global
- name: dimension_value
data_type: string
description: The value or segment available for the selected dimension.
data_tests:
- not_null
- name: calendar_year
data_type: integer
description: The calendar year associated with the data.
data_tests:
- not_null
- name: financial_year
data_type: integer
description: The financial year associated with the data.
data_tests:
- not_null
- name: previous_year_date
data_type: date
description: |
The equivalent date in the previous year. It can be null if the
metric is not available in the previous year
- name: id_metric
data_type: integer
description: |
Unique ID for this metric. It is preferable to use this ID when
building a report to ensure changes in the metric name do not
affect the report.
data_tests:
- not_null
- name: metric_name
data_type: string
description: |
Name of the metric. It is preferable to use the ID of the metric
when building a report to ensure changes in the metric name do not
affect the report.
data_tests:
- not_null
- name: requires_invoicing_data
data_type: boolean
description: |
Flag to indicate if the metric requires invoicing data to be calculated.
This will limit the display for reporting purposes.
data_tests:
- not_null
- name: current_month_mtd
data_type: numeric
description: |
Value of the metric for the current month MTD.
- name: previous_month_eom
data_type: numeric
description: |
Value of the metric for the previous month EOM.
- name: previous_year_mtd
data_type: numeric
description: |
Value of the metric for the previous year MTD.
- name: current_year_ytd
data_type: numeric
description: |
Value of the metric for the current year YTD.
- name: previous_year_ytd
data_type: numeric
description: |
Value of the metric for the previous year YTD.
- name: diff_current_month_mtd_vs_previous_month_eom
data_type: numeric
description: |
Difference between the current month MTD and the previous month EOM.
- name: diff_current_month_mtd_vs_previous_year_mtd
data_type: numeric
description: |
Difference between the current month MTD and the previous year MTD.
- name: diff_current_ytd_vs_previous_ytd
data_type: numeric
description: |
Difference between the current year YTD and the previous year YTD.
- name: rel_diff_current_month_mtd_vs_previous_month_eom
data_type: numeric
description: |
Relative difference between the current month MTD and the previous month EOM.
- name: rel_diff_current_month_mtd_vs_previous_year_mtd
data_type: numeric
description: |
Relative difference between the current month MTD and the previous year MTD.
- name: rel_diff_current_ytd_vs_previous_ytd
data_type: numeric
description: |
Relative difference between the current year YTD and the previous year YTD.