From 7260368bad413c727d0447a28f936f11aef8ecb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oriol=20Roqu=C3=A9=20Paniagua?= Date: Tue, 18 Feb 2025 15:45:24 +0000 Subject: [PATCH] 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 --- ...d_mtd_aggregated_main_metrics_overview.sql | 171 ++++++++++++++++++ models/intermediate/cross/schema.yml | 141 +++++++++++++++ 2 files changed, 312 insertions(+) create mode 100644 models/intermediate/cross/int_ytd_mtd_aggregated_main_metrics_overview.sql diff --git a/models/intermediate/cross/int_ytd_mtd_aggregated_main_metrics_overview.sql b/models/intermediate/cross/int_ytd_mtd_aggregated_main_metrics_overview.sql new file mode 100644 index 0000000..ec8b6f2 --- /dev/null +++ b/models/intermediate/cross/int_ytd_mtd_aggregated_main_metrics_overview.sql @@ -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 %} diff --git a/models/intermediate/cross/schema.yml b/models/intermediate/cross/schema.yml index 73ccd8f..8bac136 100644 --- a/models/intermediate/cross/schema.yml +++ b/models/intermediate/cross/schema.yml @@ -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.