Merged PR 4628: Churn deals
# Description New model for Churn report. It contains all deals that are churned/cancelled according to HubSpot on a monthly basis, it includes revenue, bookings created (by time windows) and number of listings per deal # 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: #28190
This commit is contained in:
commit
cc9b4ade71
7 changed files with 227 additions and 0 deletions
|
|
@ -13,6 +13,9 @@ with
|
||||||
and is_end_of_month = true
|
and is_end_of_month = true
|
||||||
),
|
),
|
||||||
daily_deal_lifecycle as (select * from {{ ref("int_kpis__lifecycle_daily_deal") }}),
|
daily_deal_lifecycle as (select * from {{ ref("int_kpis__lifecycle_daily_deal") }}),
|
||||||
|
int_kpis__dimension_daily_accommodation as (
|
||||||
|
select * from {{ ref("int_kpis__dimension_daily_accommodation") }}
|
||||||
|
),
|
||||||
listings as (
|
listings as (
|
||||||
select *
|
select *
|
||||||
from {{ ref("int_kpis__agg_daily_listings") }}
|
from {{ ref("int_kpis__agg_daily_listings") }}
|
||||||
|
|
@ -83,6 +86,9 @@ select
|
||||||
ikdd.main_deal_name,
|
ikdd.main_deal_name,
|
||||||
ikdd.has_active_pms,
|
ikdd.has_active_pms,
|
||||||
ikdd.active_pms_list,
|
ikdd.active_pms_list,
|
||||||
|
coalesce(
|
||||||
|
dda.active_accommodations_per_deal_segmentation, 'UNSET'
|
||||||
|
) as active_accommodations_per_deal_segmentation,
|
||||||
ikdd.main_billing_country_iso_3_per_deal,
|
ikdd.main_billing_country_iso_3_per_deal,
|
||||||
|
|
||||||
-- DEAL LIFECYCLE --
|
-- DEAL LIFECYCLE --
|
||||||
|
|
@ -279,6 +285,10 @@ left join
|
||||||
daily_deal_lifecycle
|
daily_deal_lifecycle
|
||||||
on d.date = daily_deal_lifecycle.date
|
on d.date = daily_deal_lifecycle.date
|
||||||
and d.dimension_value = daily_deal_lifecycle.id_deal
|
and d.dimension_value = daily_deal_lifecycle.id_deal
|
||||||
|
left join
|
||||||
|
int_kpis__dimension_daily_accommodation as dda
|
||||||
|
on d.date = dda.date
|
||||||
|
and d.dimension_value = dda.id_deal
|
||||||
left join
|
left join
|
||||||
created_bookings
|
created_bookings
|
||||||
on d.date = created_bookings.end_date
|
on d.date = created_bookings.end_date
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
-- HubSpot stage for live deals
|
||||||
|
{% set live_stage = "Live" %}
|
||||||
|
{% set churned_state = "05-Churning" %}
|
||||||
|
|
||||||
{{ config(materialized="table", unique_key=["date", "id_deal"]) }}
|
{{ config(materialized="table", unique_key=["date", "id_deal"]) }}
|
||||||
with
|
with
|
||||||
int_monthly_aggregated_metrics_history_by_deal as (
|
int_monthly_aggregated_metrics_history_by_deal as (
|
||||||
|
|
@ -12,6 +16,7 @@ with
|
||||||
main_deal_name,
|
main_deal_name,
|
||||||
has_active_pms,
|
has_active_pms,
|
||||||
active_pms_list,
|
active_pms_list,
|
||||||
|
active_accommodations_per_deal_segmentation,
|
||||||
main_billing_country_iso_3_per_deal,
|
main_billing_country_iso_3_per_deal,
|
||||||
deal_lifecycle_state,
|
deal_lifecycle_state,
|
||||||
'All History' as time_window,
|
'All History' as time_window,
|
||||||
|
|
@ -126,6 +131,7 @@ with
|
||||||
main_deal_name,
|
main_deal_name,
|
||||||
has_active_pms,
|
has_active_pms,
|
||||||
active_pms_list,
|
active_pms_list,
|
||||||
|
active_accommodations_per_deal_segmentation,
|
||||||
main_billing_country_iso_3_per_deal,
|
main_billing_country_iso_3_per_deal,
|
||||||
deal_lifecycle_state,
|
deal_lifecycle_state,
|
||||||
'Previous 12 months' as time_window,
|
'Previous 12 months' as time_window,
|
||||||
|
|
@ -225,6 +231,7 @@ with
|
||||||
main_deal_name,
|
main_deal_name,
|
||||||
has_active_pms,
|
has_active_pms,
|
||||||
active_pms_list,
|
active_pms_list,
|
||||||
|
active_accommodations_per_deal_segmentation,
|
||||||
main_billing_country_iso_3_per_deal,
|
main_billing_country_iso_3_per_deal,
|
||||||
deal_lifecycle_state,
|
deal_lifecycle_state,
|
||||||
'Previous 6 months' as time_window,
|
'Previous 6 months' as time_window,
|
||||||
|
|
@ -324,6 +331,7 @@ with
|
||||||
main_deal_name,
|
main_deal_name,
|
||||||
has_active_pms,
|
has_active_pms,
|
||||||
active_pms_list,
|
active_pms_list,
|
||||||
|
active_accommodations_per_deal_segmentation,
|
||||||
main_billing_country_iso_3_per_deal,
|
main_billing_country_iso_3_per_deal,
|
||||||
deal_lifecycle_state,
|
deal_lifecycle_state,
|
||||||
'Previous 3 months' as time_window,
|
'Previous 3 months' as time_window,
|
||||||
|
|
@ -423,6 +431,7 @@ with
|
||||||
main_deal_name,
|
main_deal_name,
|
||||||
has_active_pms,
|
has_active_pms,
|
||||||
active_pms_list,
|
active_pms_list,
|
||||||
|
active_accommodations_per_deal_segmentation,
|
||||||
main_billing_country_iso_3_per_deal,
|
main_billing_country_iso_3_per_deal,
|
||||||
deal_lifecycle_state,
|
deal_lifecycle_state,
|
||||||
'Previous month' as time_window,
|
'Previous month' as time_window,
|
||||||
|
|
@ -545,12 +554,59 @@ select
|
||||||
mabd.main_deal_name,
|
mabd.main_deal_name,
|
||||||
mabd.has_active_pms,
|
mabd.has_active_pms,
|
||||||
mabd.active_pms_list,
|
mabd.active_pms_list,
|
||||||
|
mabd.active_accommodations_per_deal_segmentation,
|
||||||
mabd.main_billing_country_iso_3_per_deal,
|
mabd.main_billing_country_iso_3_per_deal,
|
||||||
mabd.deal_lifecycle_state,
|
mabd.deal_lifecycle_state,
|
||||||
d.deal_hubspot_stage,
|
d.deal_hubspot_stage,
|
||||||
d.account_manager,
|
d.account_manager,
|
||||||
d.live_date_utc,
|
d.live_date_utc,
|
||||||
d.cancellation_date_utc,
|
d.cancellation_date_utc,
|
||||||
|
case
|
||||||
|
when mabd.deal_lifecycle_state = '{{churned_state}}'
|
||||||
|
then
|
||||||
|
date_part(
|
||||||
|
'month',
|
||||||
|
age(coalesce(d.cancellation_date_utc, mabd.date), d.live_date_utc)
|
||||||
|
)
|
||||||
|
+ 12
|
||||||
|
* date_part(
|
||||||
|
'year',
|
||||||
|
age(coalesce(d.cancellation_date_utc, mabd.date), d.live_date_utc)
|
||||||
|
)
|
||||||
|
else null
|
||||||
|
end as months_between_live_and_churn,
|
||||||
|
d.last_contacted_date_utc,
|
||||||
|
case
|
||||||
|
when mabd.deal_lifecycle_state = '{{churned_state}}'
|
||||||
|
then
|
||||||
|
case
|
||||||
|
when
|
||||||
|
coalesce(d.cancellation_date_utc, mabd.date)
|
||||||
|
- d.last_contacted_date_utc
|
||||||
|
< 0
|
||||||
|
then null
|
||||||
|
else
|
||||||
|
coalesce(d.cancellation_date_utc, mabd.date)
|
||||||
|
- d.last_contacted_date_utc
|
||||||
|
end
|
||||||
|
else null
|
||||||
|
end as days_between_last_contacted_and_churn,
|
||||||
|
d.amount_times_contacted,
|
||||||
|
d.cancellation_category,
|
||||||
|
case
|
||||||
|
when mabd.deal_lifecycle_state = '{{churned_state}}' then true else false
|
||||||
|
end as is_churning,
|
||||||
|
case
|
||||||
|
when
|
||||||
|
mabd.deal_lifecycle_state = '{{churned_state}}'
|
||||||
|
and d.cancellation_date_utc is null
|
||||||
|
then 'INACTIVITY'
|
||||||
|
when
|
||||||
|
mabd.deal_lifecycle_state = '{{churned_state}}'
|
||||||
|
and d.cancellation_date_utc is not null
|
||||||
|
then 'ACCOUNT CANCELLATION'
|
||||||
|
else null
|
||||||
|
end as churn_reason,
|
||||||
|
|
||||||
-- Windowed metrics
|
-- Windowed metrics
|
||||||
coalesce(mabd.sum_created_bookings, 0) as created_bookings,
|
coalesce(mabd.sum_created_bookings, 0) as created_bookings,
|
||||||
|
|
|
||||||
|
|
@ -385,6 +385,22 @@ models:
|
||||||
Name of the active PMS associated with the deal. It can have more than
|
Name of the active PMS associated with the deal. It can have more than
|
||||||
one PMS associated with it. It can be null if it doesn't have any PMS associated.
|
one PMS associated with it. It can be null if it doesn't have any PMS associated.
|
||||||
|
|
||||||
|
- name: active_accommodations_per_deal_segmentation
|
||||||
|
data_type: string
|
||||||
|
description: |
|
||||||
|
Segment value based on the number of listings booked in 12 months
|
||||||
|
for a given deal and date.
|
||||||
|
data_tests:
|
||||||
|
- not_null
|
||||||
|
- accepted_values:
|
||||||
|
values:
|
||||||
|
- "0"
|
||||||
|
- "01-05"
|
||||||
|
- "06-20"
|
||||||
|
- "21-60"
|
||||||
|
- "61+"
|
||||||
|
- "UNSET"
|
||||||
|
|
||||||
- name: main_billing_country_iso_3_per_deal
|
- name: main_billing_country_iso_3_per_deal
|
||||||
data_type: string
|
data_type: string
|
||||||
description: |
|
description: |
|
||||||
|
|
@ -1568,6 +1584,22 @@ models:
|
||||||
Name of the active PMS associated with the deal. It can have more than
|
Name of the active PMS associated with the deal. It can have more than
|
||||||
one PMS associated with it. It can be null if it doesn't have any PMS associated.
|
one PMS associated with it. It can be null if it doesn't have any PMS associated.
|
||||||
|
|
||||||
|
- name: active_accommodations_per_deal_segmentation
|
||||||
|
data_type: string
|
||||||
|
description: |
|
||||||
|
Segment value based on the number of listings booked in 12 months
|
||||||
|
for a given deal and date.
|
||||||
|
data_tests:
|
||||||
|
- not_null
|
||||||
|
- accepted_values:
|
||||||
|
values:
|
||||||
|
- "0"
|
||||||
|
- "01-05"
|
||||||
|
- "06-20"
|
||||||
|
- "21-60"
|
||||||
|
- "61+"
|
||||||
|
- "UNSET"
|
||||||
|
|
||||||
- name: main_billing_country_iso_3_per_deal
|
- name: main_billing_country_iso_3_per_deal
|
||||||
data_type: string
|
data_type: string
|
||||||
description: |
|
description: |
|
||||||
|
|
@ -1604,6 +1636,53 @@ models:
|
||||||
Hubspot. It can be null if the deal has never
|
Hubspot. It can be null if the deal has never
|
||||||
churned.
|
churned.
|
||||||
|
|
||||||
|
- name: months_between_live_and_churn
|
||||||
|
data_type: integer
|
||||||
|
description: |
|
||||||
|
Number of months between the live date and the
|
||||||
|
churn date.
|
||||||
|
data_tests:
|
||||||
|
- dbt_expectations.expect_column_values_to_be_between:
|
||||||
|
min_value: 0
|
||||||
|
strictly: false
|
||||||
|
|
||||||
|
- name: last_contacted_date_utc
|
||||||
|
data_type: date
|
||||||
|
description: |
|
||||||
|
Date when the deal was last contacted according to
|
||||||
|
Hubspot.
|
||||||
|
|
||||||
|
- name: days_between_last_contacted_and_churn
|
||||||
|
data_type: integer
|
||||||
|
description: |
|
||||||
|
Number of days between the last contacted date
|
||||||
|
and the churn date.
|
||||||
|
data_tests:
|
||||||
|
- dbt_expectations.expect_column_values_to_be_between:
|
||||||
|
min_value: 0
|
||||||
|
strictly: false
|
||||||
|
|
||||||
|
- name: amount_times_contacted
|
||||||
|
data_type: integer
|
||||||
|
description: |
|
||||||
|
Number of times the deal was contacted according
|
||||||
|
to Hubspot.
|
||||||
|
|
||||||
|
- name: is_churning
|
||||||
|
data_type: boolean
|
||||||
|
description: |
|
||||||
|
Flag to identify if the deal is churning or not.
|
||||||
|
|
||||||
|
- name: churn_reason
|
||||||
|
data_type: string
|
||||||
|
description: |
|
||||||
|
Reason why the deal is churning.
|
||||||
|
data_tests:
|
||||||
|
- accepted_values:
|
||||||
|
values:
|
||||||
|
- "INACTIVITY"
|
||||||
|
- "ACCOUNT CANCELLATION"
|
||||||
|
|
||||||
- name: created_bookings
|
- name: created_bookings
|
||||||
data_type: integer
|
data_type: integer
|
||||||
description: |
|
description: |
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ select
|
||||||
d.cancellation_category,
|
d.cancellation_category,
|
||||||
d.cancellation_details,
|
d.cancellation_details,
|
||||||
d.amount_of_properties,
|
d.amount_of_properties,
|
||||||
|
d.last_contacted_date_utc,
|
||||||
|
d.amount_times_contacted,
|
||||||
d.created_at_utc,
|
d.created_at_utc,
|
||||||
d.created_date_utc,
|
d.created_date_utc,
|
||||||
d.updated_at_utc,
|
d.updated_at_utc,
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,14 @@ models:
|
||||||
Amount of properties the owner told us they manage. This is not necessarily the
|
Amount of properties the owner told us they manage. This is not necessarily the
|
||||||
amount of properties that will be finally booked in our business.
|
amount of properties that will be finally booked in our business.
|
||||||
|
|
||||||
|
- name: last_contacted_date_utc
|
||||||
|
data_type: date
|
||||||
|
description: Date in which the account was last contacted
|
||||||
|
|
||||||
|
- name: amount_times_contacted
|
||||||
|
data_type: integer
|
||||||
|
description: Amount of times the account has been contacted
|
||||||
|
|
||||||
- name: created_at_utc
|
- name: created_at_utc
|
||||||
data_type: timestamp with time zone
|
data_type: timestamp with time zone
|
||||||
description: Timestamp of when the record was created in Hubspot
|
description: Timestamp of when the record was created in Hubspot
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,21 @@ select
|
||||||
has_active_pms as has_active_pms,
|
has_active_pms as has_active_pms,
|
||||||
client_type as client_type,
|
client_type as client_type,
|
||||||
active_pms_list as active_pms_list,
|
active_pms_list as active_pms_list,
|
||||||
|
active_accommodations_per_deal_segmentation
|
||||||
|
as active_accommodations_per_deal_segmentation,
|
||||||
main_billing_country_iso_3_per_deal as main_billing_country_iso_3_per_deal,
|
main_billing_country_iso_3_per_deal as main_billing_country_iso_3_per_deal,
|
||||||
deal_lifecycle_state as deal_lifecycle_state,
|
deal_lifecycle_state as deal_lifecycle_state,
|
||||||
deal_hubspot_stage as deal_hubspot_stage,
|
deal_hubspot_stage as deal_hubspot_stage,
|
||||||
account_manager as account_manager,
|
account_manager as account_manager,
|
||||||
live_date_utc as live_date_utc,
|
live_date_utc as live_date_utc,
|
||||||
cancellation_date_utc as cancellation_date_utc,
|
cancellation_date_utc as cancellation_date_utc,
|
||||||
|
months_between_live_and_churn as months_between_live_and_churn,
|
||||||
|
last_contacted_date_utc as last_contacted_date_utc,
|
||||||
|
days_between_last_contacted_and_churn as days_between_last_contacted_and_churn,
|
||||||
|
amount_times_contacted as amount_times_contacted,
|
||||||
|
cancellation_category as cancellation_category,
|
||||||
|
is_churning as is_churning,
|
||||||
|
churn_reason as churn_reason,
|
||||||
created_bookings as created_bookings,
|
created_bookings as created_bookings,
|
||||||
listings_booked_in_month as listings_booked_in_month,
|
listings_booked_in_month as listings_booked_in_month,
|
||||||
total_revenue_in_gbp as total_revenue_in_gbp,
|
total_revenue_in_gbp as total_revenue_in_gbp,
|
||||||
|
|
|
||||||
|
|
@ -1560,6 +1560,22 @@ models:
|
||||||
Name of the active PMS associated with the deal. It can have more than
|
Name of the active PMS associated with the deal. It can have more than
|
||||||
one PMS associated with it. It can be null if it doesn't have any PMS associated.
|
one PMS associated with it. It can be null if it doesn't have any PMS associated.
|
||||||
|
|
||||||
|
- name: active_accommodations_per_deal_segmentation
|
||||||
|
data_type: string
|
||||||
|
description: |
|
||||||
|
Segment value based on the number of listings booked in 12 months
|
||||||
|
for a given deal and date.
|
||||||
|
data_tests:
|
||||||
|
- not_null
|
||||||
|
- accepted_values:
|
||||||
|
values:
|
||||||
|
- "0"
|
||||||
|
- "01-05"
|
||||||
|
- "06-20"
|
||||||
|
- "21-60"
|
||||||
|
- "61+"
|
||||||
|
- "UNSET"
|
||||||
|
|
||||||
- name: main_billing_country_iso_3_per_deal
|
- name: main_billing_country_iso_3_per_deal
|
||||||
data_type: string
|
data_type: string
|
||||||
description: |
|
description: |
|
||||||
|
|
@ -1596,6 +1612,53 @@ models:
|
||||||
Hubspot. It can be null if the deal has never
|
Hubspot. It can be null if the deal has never
|
||||||
churned.
|
churned.
|
||||||
|
|
||||||
|
- name: months_between_live_and_churn
|
||||||
|
data_type: integer
|
||||||
|
description: |
|
||||||
|
Number of months between the live date and the
|
||||||
|
churn date.
|
||||||
|
data_tests:
|
||||||
|
- dbt_expectations.expect_column_values_to_be_between:
|
||||||
|
min_value: 0
|
||||||
|
strictly: false
|
||||||
|
|
||||||
|
- name: last_contacted_date_utc
|
||||||
|
data_type: date
|
||||||
|
description: |
|
||||||
|
Date when the deal was last contacted according to
|
||||||
|
Hubspot.
|
||||||
|
|
||||||
|
- name: days_between_last_contacted_and_churn
|
||||||
|
data_type: integer
|
||||||
|
description: |
|
||||||
|
Number of days between the last contacted date
|
||||||
|
and the churn date.
|
||||||
|
data_tests:
|
||||||
|
- dbt_expectations.expect_column_values_to_be_between:
|
||||||
|
min_value: 0
|
||||||
|
strictly: false
|
||||||
|
|
||||||
|
- name: amount_times_contacted
|
||||||
|
data_type: integer
|
||||||
|
description: |
|
||||||
|
Number of times the deal was contacted according
|
||||||
|
to Hubspot.
|
||||||
|
|
||||||
|
- name: is_churning
|
||||||
|
data_type: boolean
|
||||||
|
description: |
|
||||||
|
Flag to identify if the deal is churning or not.
|
||||||
|
|
||||||
|
- name: churn_reason
|
||||||
|
data_type: string
|
||||||
|
description: |
|
||||||
|
Reason why the deal is churning.
|
||||||
|
data_tests:
|
||||||
|
- accepted_values:
|
||||||
|
values:
|
||||||
|
- "INACTIVITY"
|
||||||
|
- "ACCOUNT CANCELLATION"
|
||||||
|
|
||||||
- name: created_bookings
|
- name: created_bookings
|
||||||
data_type: integer
|
data_type: integer
|
||||||
description: |
|
description: |
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue