Merged PR 5256: Reporting version of New Dash Onboarding

# Description

Reporting version of New Dash Onboarding

It also adds a missing description of a field.
It also adapts the logic for Hubspot Onboarding Owner, after a discussion with Alex. It still does not cover 100% of the cases but he's investigating the rest.

# 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.
- [ ] I have checked for DRY opportunities with other models and docs.
- [ ] I've picked the right materialization for the affected models.

# Other

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

Related work items: #30249
This commit is contained in:
Oriol Roqué Paniagua 2025-05-19 15:41:48 +00:00
parent 7b6f0d13f6
commit 56aeb701cd
5 changed files with 439 additions and 8 deletions

View file

@ -3874,6 +3874,14 @@ models:
List of all distinct services that are applied in all listings
for this account, separated by "|" and ordered alphabetically.
- name: active_services_in_programs_applied_to_listings
data_type: text
description: |
List of all distinct services that are currently active i.e., that
are applied in active listings for this account, separated by "|"
and ordered alphabetically.
These are the current services that can be applied to new bookings.
- name: has_churned
data_type: boolean
description: |

View file

@ -1,5 +1,6 @@
{% set id_deal_pipelines_excluded = "('15380854')" %}
{% set generic_account_manager_names = "('Host Services')" %}
{% set generic_account_manager_names = "('HOST SERVICES')" %}
{% set guardhog_customer_conversion_source = "('GUARDHOG CUSTOMER CONVERSION')" %}
with
stg_hubspot__deals as (select * from {{ ref("stg_hubspot__deals") }}),
@ -20,13 +21,29 @@ select
d.live_date_utc,
d.cancellation_date_utc,
d.account_manager,
-- Following logic discussed with Alex A. on 2025-05-19 to determine the
-- onboarding owner
case
when d.onboarding_owner is not null
then onboarding_owner
when
d.onboarding_owner is null
and d.account_manager in {{ generic_account_manager_names }}
-- 1. If the cloned onboarding owner is not null, use that. This should reflect
-- most of the cases.
when d.onboarding_owner__cloned_ is not null
then d.onboarding_owner__cloned_
-- 2. If the cloned onboarding owner is null and the onboarding owner is not
-- null, use the second. It should cover few exceptional cases.
when d.onboarding_owner__cloned_ is null and d.onboarding_owner is not null
then d.onboarding_owner
-- 3. If the deal is a conversion from Guardhog to Truvi, the onboarding owner
-- should always be the HubSpot account owner.
when upper(d.deal_source) in {{ guardhog_customer_conversion_source }}
then hao.hubspot_account_owner
-- 4. If the onboarding owner is null and the account manager is in the generic
-- account manager names, use the HubSpot account owner. This is because is
-- actually a Sales person that handles the onboarding.
when
d.onboarding_owner__cloned_ is null
and upper(d.account_manager) in {{ generic_account_manager_names }}
then hao.hubspot_account_owner
-- For all other cases, set the onboarding owner to null.
else null
end as onboarding_owner,
dp.deal_pipeline_name as deal_pipeline,

View file

@ -0,0 +1,47 @@
with
int_new_dash_deal_onboarding as (
select * from {{ ref("int_new_dash_deal_onboarding") }}
)
select
id_deal,
deal_name,
id_deal || '-' || coalesce(deal_name, '') as deal,
onboarding_owner,
account_manager,
platform_company_name,
count_platform_accounts,
count_listings,
count_active_listings,
count_listings_with_upgraded_programs,
count_active_listings_with_active_upgraded_programs,
count_bookings,
count_bookings_with_paid_service,
count_programs_at_deal_level,
count_upgraded_programs_at_deal_level,
count_upgraded_programs_at_listing_level,
count_active_upgraded_programs_at_active_listing_level,
contract_signed_date_utc,
live_date_utc,
cancellation_date_utc,
backend_account_creation_utc,
first_listing_created_at_utc,
first_booking_created_at_utc,
first_program_created_at_utc,
first_upgraded_program_created_at_utc,
first_upgraded_program_applied_to_listing_at_utc,
first_booking_with_paid_services_created_at_utc,
first_invoice_at_utc,
expressed_service_interest,
services_in_programs_at_deal_level,
services_in_programs_applied_to_listings,
active_services_in_programs_applied_to_listings,
has_churned,
has_listings,
has_active_listings,
has_bookings,
has_been_invoiced,
are_all_bookings_free,
is_account_no_longer_generating_paid_bookings,
has_account_changed_services_applied_in_listings,
are_active_services_different_from_expressed_interest
from int_new_dash_deal_onboarding

View file

@ -2692,3 +2692,346 @@ models:
Flag indicating if the account has switched to major decline in the
current month.
1 for yes, 0 for no.
- name: new_dash_deal_onboarding
description: |
A dedicated model to track the onboarding stages of new accounts (deals)
in New Dash.
This excludes any deal that has been migrated from Old Dash, so it just
contains "new business".
columns:
- name: id_deal
data_type: text
description: |
Unique identifier of an account.
data_tests:
- not_null
- unique
- name: deal_name
data_type: text
description: |
Name of the deal according to HubSpot.
data_tests:
- not_null
- unique
- name: deal
data_type: text
description: |
Combination of the ID and the Name of the deal.
- name: onboarding_owner
data_type: text
description: |
Name of the person that is in charge of onboarding this account.
- name: account_manager
data_type: text
description: |
Account manager in charge of the account.
- name: platform_company_name
data_type: text
description: |
Name of the company in Truvi's backend.
- name: count_platform_accounts
data_type: integer
description: |
Amount of Backend accounts (users) linked to this Deal.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 1
max_value: 1
strictly: false
- name: count_programs_at_deal_level
data_type: integer
description: |
Total amount of programs that this account has. These might not
necessarily be applied to a Listing.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
strictly: false
- name: count_listings
data_type: integer
description: |
Total count of Listings from this account.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
strictly: false
- name: count_active_listings
data_type: integer
description: |
Count of Listings that are currently active, meaning, that have not
been deactivated.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_listings
strictly: false
- name: count_listings_with_upgraded_programs
data_type: integer
description: |
Count of Listings that have had a program applied that contains at least
one service different to Basic Screening.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_listings
strictly: false
- name: count_active_listings_with_active_upgraded_programs
data_type: integer
description: |
Count of Listings that are currently active and that currently have an
active upgraded program, meaning, that contains at least one service
different to Basic Screening.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_active_listings
strictly: false
- name: count_bookings
data_type: integer
description: |
Total count of Bookings generated from this account.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
strictly: false
- name: count_bookings_with_paid_service
data_type: integer
description: |
Count of Bookings that have at least one paid service.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_bookings
strictly: false
- name: count_upgraded_programs_at_deal_level
data_type: integer
description: |
Count of programs that this account has that contain, at least, one
service different to Basic Screening. These might not necessarily
be applied to a Listing.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_programs_at_deal_level
strictly: false
- name: count_upgraded_programs_at_listing_level
data_type: integer
description: |
Count of programs that contain at least one service different to
Basic Screening that have been applied to a Listing.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_upgraded_programs_at_deal_level
strictly: false
- name: count_active_upgraded_programs_at_active_listing_level
data_type: integer
description: |
Count of programs that contain at least one service different to
Basic Screening that are currently active and applied to an
active Listing.
data_tests:
- not_null
- dbt_expectations.expect_column_values_to_be_between:
min_value: 0
max_value: count_upgraded_programs_at_listing_level
strictly: false
- name: contract_signed_date_utc
data_type: date
description: |
Date in which the contract was signed according to HubSpot.
- name: live_date_utc
data_type: date
description: |
Date in which the Deal went live according to HubSpot.
- name: cancellation_date_utc
data_type: date
description: |
Date in which the Deal was cancelled according to HubSpot.
- name: backend_account_creation_utc
data_type: timestamp without timezone
description: |
Timestamp in which the account was created in the backend.
- name: first_listing_created_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first listing was created in the backend.
- name: first_booking_created_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first booking was created in the backend.
- name: first_program_created_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first program was created at account level
in the backend.
- name: first_upgraded_program_created_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first program was applied to a listing
for this account, in the backend.
- name: first_upgraded_program_applied_to_listing_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first upgraded program was applied to a listing
for this account, in the backend.
- name: first_booking_with_paid_services_created_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first booking that contained paid services
was created for this account, in the backend.
- name: first_invoice_at_utc
data_type: timestamp without timezone
description: |
Timestamp in which the first invoice happened for this account in Xero.
- name: expressed_service_interest
data_type: text
description: |
List of services that during onboarding generated interest
to the client.
- name: services_in_programs_at_deal_level
data_type: text
description: |
List of all distinct services that appear in programs at
deal level, separated by "|" and ordered alphabetically.
- name: services_in_programs_applied_to_listings
data_type: text
description: |
List of all distinct services that are applied in all listings
for this account, separated by "|" and ordered alphabetically.
- name: active_services_in_programs_applied_to_listings
data_type: text
description: |
List of all distinct services that are currently active i.e., that
are applied in active listings for this account, separated by "|"
and ordered alphabetically.
These are the current services that can be applied to new bookings.
- name: has_churned
data_type: boolean
description: |
True if the account has a cancellation date in HubSpot,
False otherwise.
data_tests:
- not_null
- name: has_listings
data_type: boolean
description: |
True if the account has at least one listing appearing in
the backend, False otherwise.
data_tests:
- not_null
- name: has_active_listings
data_type: boolean
description: |
True if the account has at least one listing that is currently
active in the backend, False otherwise.
data_tests:
- not_null
- name: has_bookings
data_type: boolean
description: |
True if the account has at least one booking appearing in
the backend, False otherwise.
data_tests:
- not_null
- name: has_been_invoiced
data_type: boolean
description: |
True if the account has at least one invoice appearing in
Xero, False otherwise.
data_tests:
- not_null
- name: are_all_bookings_free
data_type: boolean
description: |
True if the account has bookings but all of them are free,
meaning, there's not a single service being paid.
data_tests:
- not_null
- name: is_account_no_longer_generating_paid_bookings
data_type: boolean
description: |
True if the account has had in the past paid bookings but
at the moment there's not a single listing that contains
an active upgraded program.
Encouraged to be used alongside a filter to determine if
the account has churned or not.
data_tests:
- not_null
- name: has_account_changed_services_applied_in_listings
data_type: boolean
description: |
True if the active services in programs applied to listings
is different than the services that were historically applied.
By nature, this always means that at least one service was
being applied before that is no longer being applied. This can
indicate a real decrease in services applied that could be linked to
a potential revenue loss (decrease in booking fees),
although it's also possible that the account has changed from a
certain low-level tier to a higher-level one (ex: from Basic
Protection to Protection Pro).
data_tests:
- not_null
- name: are_active_services_different_from_expressed_interest
data_type: boolean
description: |
True if the services that are currently applied to listings
are different than the ones that were expressed as interest
during onboarding.
This can indicate a potential need for upselling for business
teams to act upon, although it's also possible that the account
has added new services that where not expressed as interest
during onboarding.
data_tests:
- not_null

View file

@ -3,5 +3,21 @@
"679781281",Cali Bowen
"203088812",Chloe Fraser
"1837277529",Danielle Miller
"76054743",María belén Florio
"76054743",María Belén Florio
"76054690",Paola Zapata
"208877189",Evan Roll
"52620291",Lucy Hiden
"26221498",Steven Hughes
"49206237",Cailtin Ayliffe
"67553424",Mackenzie Kapral
"63001264",Emyr Hyde
"66104586",Sally Farrell
"13487398",Sarah Barrett
"46718836",Francisco Ochoa
"46715149",Tony Amigleo
"67553422",Abby Matlin
"48878520",Nicole Lamb
"48026832",Kat Volkova
"46715149",Tony Amigleo
"11891326",Hannah Audin
"9580086",Hannah Audin
1 id_hubspot_account_owner hubspot_account_owner
3 679781281 Cali Bowen
4 203088812 Chloe Fraser
5 1837277529 Danielle Miller
6 76054743 María belén Florio María Belén Florio
7 76054690 Paola Zapata
8 208877189 Evan Roll
9 52620291 Lucy Hiden
10 26221498 Steven Hughes
11 49206237 Cailtin Ayliffe
12 67553424 Mackenzie Kapral
13 63001264 Emyr Hyde
14 66104586 Sally Farrell
15 13487398 Sarah Barrett
16 46718836 Francisco Ochoa
17 46715149 Tony Amigleo
18 67553422 Abby Matlin
19 48878520 Nicole Lamb
20 48026832 Kat Volkova
21 46715149 Tony Amigleo
22 11891326 Hannah Audin
23 9580086 Hannah Audin