From 338ae3a9974d344d4246e581375913c8b5d676f8 Mon Sep 17 00:00:00 2001 From: fivetran-catfritz <111930712+fivetran-catfritz@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:52:07 -0500 Subject: [PATCH 1/6] cast to date --- .../int_zendesk__agent_work_time_business_hours.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql b/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql index 5abad813..19f1dc37 100644 --- a/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql +++ b/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql @@ -129,8 +129,8 @@ with agent_work_time_filtered_statuses as ( and weekly_period_agent_work_time.schedule_id = schedule.schedule_id -- this chooses the Daylight Savings Time or Standard Time version of the schedule -- We have everything calculated within a week, so take us to the appropriate week first by adding the week_number * minutes-in-a-week to the minute-mark where we start and stop counting for the week - and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_end_time_minute', from_date_or_timestamp='start_week_date') }} as {{ dbt.type_timestamp() }}) > cast(schedule.valid_from as {{ dbt.type_timestamp() }}) - and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_start_time_minute', from_date_or_timestamp='start_week_date') }} as {{ dbt.type_timestamp() }}) < cast(schedule.valid_until as {{ dbt.type_timestamp() }}) + and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_end_time_minute', from_date_or_timestamp='start_week_date') }} as date) > cast(schedule.valid_from as date) + and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_start_time_minute', from_date_or_timestamp='start_week_date') }} as date) < cast(schedule.valid_until as date) ), intercepted_periods_with_running_total as ( From a72165f0cc75f941f458d713a15c95e3b739b85a Mon Sep 17 00:00:00 2001 From: fivetran-catfritz <111930712+fivetran-catfritz@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:07:53 -0500 Subject: [PATCH 2/6] initial commit --- .../int_zendesk__ticket_schedules.sql | 22 +++++++++++++++++-- ...endesk__agent_work_time_business_hours.sql | 16 ++++++++------ ...sk__requester_wait_time_business_hours.sql | 10 +++++---- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/models/intermediate/int_zendesk__ticket_schedules.sql b/models/intermediate/int_zendesk__ticket_schedules.sql index db8e03f0..d1332230 100644 --- a/models/intermediate/int_zendesk__ticket_schedules.sql +++ b/models/intermediate/int_zendesk__ticket_schedules.sql @@ -10,11 +10,20 @@ with ticket as ( select * from {{ ref('stg_zendesk__ticket_schedule') }} -), schedule as ( +), schedules as ( select * from {{ ref('stg_zendesk__schedule') }} +), timezones as ( + + select * + from {{ var('time_zone') }} + +), daylight_time as ( + + select * + from {{ var('daylight_time') }} ), default_schedule_events as ( -- Goal: understand the working schedules applied to tickets, so that we can then determine the applicable business hours/schedule. @@ -79,7 +88,16 @@ with ticket as ( , {{ fivetran_utils.timestamp_add("hour", 1000, "" ~ dbt.current_timestamp_backcompat() ~ "") }} ) as schedule_invalidated_at from schedule_events +), ticket_schedules_with_timezone_offset as ( + select + ticket_schedules.*, + coalesce(timezones.standard_offset_minutes, 0) as standard_offset_minutes + from ticket_schedules + left join schedules + on schedules.schedule_id = ticket_schedules.schedule_id + left join timezones + on timezones.time_zone = schedules.time_zone ) select * -from ticket_schedules \ No newline at end of file +from ticket_schedules_with_timezone_offset \ No newline at end of file diff --git a/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql b/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql index 19f1dc37..8e4deb7e 100644 --- a/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql +++ b/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql @@ -19,7 +19,7 @@ with agent_work_time_filtered_statuses as ( select * from {{ ref('int_zendesk__ticket_schedules') }} - + -- cross schedules with work time ), ticket_status_crossed_with_schedule as ( @@ -29,6 +29,7 @@ with agent_work_time_filtered_statuses as ( agent_work_time_filtered_statuses.target, agent_work_time_filtered_statuses.sla_policy_name, ticket_schedules.schedule_id, + ticket_schedules.standard_offset_minutes, -- take the intersection of the intervals in which the status and the schedule were both active, for calculating the business minutes spent working on the ticket greatest(valid_starting_at, schedule_created_at) as valid_starting_at, @@ -61,13 +62,14 @@ with agent_work_time_filtered_statuses as ( ({{ dbt.datediff( "cast(" ~ dbt_date.week_start('ticket_status_crossed_with_schedule.valid_starting_at','UTC') ~ "as " ~ dbt.type_timestamp() ~ ")", "cast(ticket_status_crossed_with_schedule.valid_starting_at as " ~ dbt.type_timestamp() ~ ")", - 'second') }} /60 + 'second') }} + /60 - standard_offset_minutes ) as valid_starting_at_in_minutes_from_week, - ({{ dbt.datediff( - 'ticket_status_crossed_with_schedule.valid_starting_at', - 'ticket_status_crossed_with_schedule.valid_ending_at', - 'second') }} /60 - ) as raw_delta_in_minutes, + ({{ dbt.datediff( + 'ticket_status_crossed_with_schedule.valid_starting_at', + 'ticket_status_crossed_with_schedule.valid_ending_at', + 'second') }} /60 + ) as raw_delta_in_minutes, {{ dbt_date.week_start('ticket_status_crossed_with_schedule.valid_starting_at','UTC') }} as start_week_date from ticket_status_crossed_with_schedule diff --git a/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql b/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql index 53b09dca..4740ea6d 100644 --- a/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql +++ b/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql @@ -29,6 +29,7 @@ with requester_wait_time_filtered_statuses as ( requester_wait_time_filtered_statuses.target, requester_wait_time_filtered_statuses.sla_policy_name, ticket_schedules.schedule_id, + ticket_schedules.standard_offset_minutes, -- take the intersection of the intervals in which the status and the schedule were both active, for calculating the business minutes spent working on the ticket greatest(valid_starting_at, schedule_created_at) as valid_starting_at, @@ -59,10 +60,11 @@ with requester_wait_time_filtered_statuses as ( status_valid_starting_at, status_valid_ending_at, ({{ dbt.datediff( - "cast(" ~ dbt_date.week_start('ticket_status_crossed_with_schedule.valid_starting_at','UTC') ~ "as " ~ dbt.type_timestamp() ~ ")", - "cast(ticket_status_crossed_with_schedule.valid_starting_at as " ~ dbt.type_timestamp() ~ ")", - 'second') }} /60 - ) as valid_starting_at_in_minutes_from_week, + "cast(" ~ dbt_date.week_start('ticket_status_crossed_with_schedule.valid_starting_at','UTC') ~ "as " ~ dbt.type_timestamp() ~ ")", + "cast(ticket_status_crossed_with_schedule.valid_starting_at as " ~ dbt.type_timestamp() ~ ")", + 'second') }} + /60 - standard_offset_minutes + ) as valid_starting_at_in_minutes_from_week, ({{ dbt.datediff( 'ticket_status_crossed_with_schedule.valid_starting_at', 'ticket_status_crossed_with_schedule.valid_ending_at', From 0fe373c2fffde93e34e45c0a8cc47c5921c319eb Mon Sep 17 00:00:00 2001 From: fivetran-catfritz <111930712+fivetran-catfritz@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:53:56 -0500 Subject: [PATCH 3/6] add dst to agent and requester --- .../int_zendesk__ticket_schedules.sql | 22 +++-- .../int_zendesk__timezones_with_dst.sql | 87 +++++++++++++++++++ ...endesk__agent_work_time_business_hours.sql | 9 +- ...sk__requester_wait_time_business_hours.sql | 10 ++- 4 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 models/intermediate/int_zendesk__timezones_with_dst.sql diff --git a/models/intermediate/int_zendesk__ticket_schedules.sql b/models/intermediate/int_zendesk__ticket_schedules.sql index d1332230..e40560e0 100644 --- a/models/intermediate/int_zendesk__ticket_schedules.sql +++ b/models/intermediate/int_zendesk__ticket_schedules.sql @@ -15,10 +15,10 @@ with ticket as ( select * from {{ ref('stg_zendesk__schedule') }} -), timezones as ( +), timezones_with_dst as ( select * - from {{ var('time_zone') }} + from {{ ref('int_zendesk__timezones_with_dst') }} ), daylight_time as ( @@ -90,13 +90,21 @@ with ticket as ( ), ticket_schedules_with_timezone_offset as ( select - ticket_schedules.*, - coalesce(timezones.standard_offset_minutes, 0) as standard_offset_minutes + ticket_schedules.ticket_id, + ticket_schedules.schedule_id, + ticket_schedules.schedule_created_at, + ticket_schedules.schedule_invalidated_at, + coalesce(timezones_with_dst.offset_minutes, 0) as offset_minutes, + timezones_with_dst.valid_from, + timezones_with_dst.valid_until from ticket_schedules left join schedules - on schedules.schedule_id = ticket_schedules.schedule_id - left join timezones - on timezones.time_zone = schedules.time_zone + on ticket_schedules.schedule_id = schedules.schedule_id + left join timezones_with_dst + on schedules.time_zone = timezones_with_dst.time_zone + and cast(ticket_schedules.schedule_created_at as date) >= cast(timezones_with_dst.valid_from as date) + and cast(ticket_schedules.schedule_created_at as date) < cast(timezones_with_dst.valid_until as date) + group by 1,2,3,4,5,6,7 ) select * diff --git a/models/intermediate/int_zendesk__timezones_with_dst.sql b/models/intermediate/int_zendesk__timezones_with_dst.sql new file mode 100644 index 00000000..565ea5a7 --- /dev/null +++ b/models/intermediate/int_zendesk__timezones_with_dst.sql @@ -0,0 +1,87 @@ +with timezone as ( + + select * + from {{ var('time_zone') }} + +), daylight_time as ( + + select * + from {{ var('daylight_time') }} + +), timezone_with_dt as ( + + select + timezone.*, + daylight_time.daylight_start_utc, + daylight_time.daylight_end_utc, + daylight_time.daylight_offset_minutes + + from timezone + left join daylight_time + on timezone.time_zone = daylight_time.time_zone + +), order_timezone_dt as ( + + select + *, + -- will be null for timezones without any daylight savings records (and the first entry) + -- we will coalesce the first entry date with .... the X years ago + lag(daylight_end_utc, 1) over (partition by time_zone order by daylight_end_utc asc) as last_daylight_end_utc, + -- will be null for timezones without any daylight savings records (and the last entry) + -- we will coalesce the last entry date with the current date + lead(daylight_start_utc, 1) over (partition by time_zone order by daylight_start_utc asc) as next_daylight_start_utc + + from timezone_with_dt + +), split_timezones as ( + + -- standard schedule (includes timezones without DT) + -- starts: when the last Daylight Savings ended + -- ends: when the next Daylight Savings starts + select + time_zone, + standard_offset_minutes as offset_minutes, + + -- last_daylight_end_utc is null for the first record of the time_zone's daylight time, or if the TZ doesn't use DT + coalesce(last_daylight_end_utc, cast('1970-01-01' as date)) as valid_from, + + -- daylight_start_utc is null for timezones that don't use DT + coalesce(daylight_start_utc, cast( {{ dbt.dateadd('year', 1, dbt.current_timestamp_backcompat()) }} as date)) as valid_until + + from order_timezone_dt + + union all + + -- DT schedule (excludes timezones without it) + -- starts: when this Daylight Savings started + -- ends: when this Daylight Savings ends + select + time_zone, + -- Pacific Time is -8h during standard time and -7h during DT + standard_offset_minutes + daylight_offset_minutes as offset_minutes, + daylight_start_utc as valid_from, + daylight_end_utc as valid_until + + from order_timezone_dt + where daylight_offset_minutes is not null + + union all + + select + time_zone, + standard_offset_minutes as offset_minutes, + + -- Get the latest daylight_end_utc time and set that as the valid_from + max(daylight_end_utc) as valid_from, + + -- If the latest_daylight_end_time_utc is less than todays timestamp, that means DST has ended. Therefore, we will make the valid_until in the future. + cast( {{ dbt.dateadd('year', 1, dbt.current_timestamp_backcompat()) }} as date) as valid_until + + from order_timezone_dt + group by 1, 2 + -- We only want to apply this logic to time_zone's that had daylight saving time and it ended at a point. For example, Hong Kong ended DST in 1979. + having cast(max(daylight_end_utc) as date) < cast({{ dbt.current_timestamp_backcompat() }} as date) +) + +select * +from split_timezones \ No newline at end of file diff --git a/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql b/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql index 8e4deb7e..84d6eac0 100644 --- a/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql +++ b/models/sla_policy/agent_work_time/int_zendesk__agent_work_time_business_hours.sql @@ -29,7 +29,7 @@ with agent_work_time_filtered_statuses as ( agent_work_time_filtered_statuses.target, agent_work_time_filtered_statuses.sla_policy_name, ticket_schedules.schedule_id, - ticket_schedules.standard_offset_minutes, + ticket_schedules.offset_minutes, -- take the intersection of the intervals in which the status and the schedule were both active, for calculating the business minutes spent working on the ticket greatest(valid_starting_at, schedule_created_at) as valid_starting_at, @@ -42,6 +42,8 @@ with agent_work_time_filtered_statuses as ( from agent_work_time_filtered_statuses left join ticket_schedules on agent_work_time_filtered_statuses.ticket_id = ticket_schedules.ticket_id + and cast(agent_work_time_filtered_statuses.valid_starting_at as date) >= cast(ticket_schedules.valid_from as date) + and cast(agent_work_time_filtered_statuses.valid_starting_at as date) < cast(ticket_schedules.valid_until as date) where {{ dbt.datediff( 'greatest(valid_starting_at, schedule_created_at)', 'least(valid_ending_at, schedule_invalidated_at)', @@ -63,7 +65,7 @@ with agent_work_time_filtered_statuses as ( "cast(" ~ dbt_date.week_start('ticket_status_crossed_with_schedule.valid_starting_at','UTC') ~ "as " ~ dbt.type_timestamp() ~ ")", "cast(ticket_status_crossed_with_schedule.valid_starting_at as " ~ dbt.type_timestamp() ~ ")", 'second') }} - /60 - standard_offset_minutes + /60 - offset_minutes ) as valid_starting_at_in_minutes_from_week, ({{ dbt.datediff( 'ticket_status_crossed_with_schedule.valid_starting_at', @@ -126,7 +128,8 @@ with agent_work_time_filtered_statuses as ( schedule.end_time_utc as schedule_end_time, least(ticket_week_end_time_minute, schedule.end_time_utc) - greatest(weekly_period_agent_work_time.ticket_week_start_time_minute, schedule.start_time_utc) as scheduled_minutes from weekly_period_agent_work_time - join schedule on ticket_week_start_time_minute <= schedule.end_time_utc + join schedule + on ticket_week_start_time_minute <= schedule.end_time_utc and ticket_week_end_time_minute >= schedule.start_time_utc and weekly_period_agent_work_time.schedule_id = schedule.schedule_id -- this chooses the Daylight Savings Time or Standard Time version of the schedule diff --git a/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql b/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql index 4740ea6d..1672c9f5 100644 --- a/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql +++ b/models/sla_policy/requester_wait_time/int_zendesk__requester_wait_time_business_hours.sql @@ -29,7 +29,7 @@ with requester_wait_time_filtered_statuses as ( requester_wait_time_filtered_statuses.target, requester_wait_time_filtered_statuses.sla_policy_name, ticket_schedules.schedule_id, - ticket_schedules.standard_offset_minutes, + ticket_schedules.offset_minutes, -- take the intersection of the intervals in which the status and the schedule were both active, for calculating the business minutes spent working on the ticket greatest(valid_starting_at, schedule_created_at) as valid_starting_at, @@ -42,6 +42,8 @@ with requester_wait_time_filtered_statuses as ( from requester_wait_time_filtered_statuses left join ticket_schedules on requester_wait_time_filtered_statuses.ticket_id = ticket_schedules.ticket_id + and cast(requester_wait_time_filtered_statuses.valid_starting_at as date) >= cast(ticket_schedules.valid_from as date) + and cast(requester_wait_time_filtered_statuses.valid_starting_at as date) < cast(ticket_schedules.valid_until as date) where {{ dbt.datediff( 'greatest(valid_starting_at, schedule_created_at)', 'least(valid_ending_at, schedule_invalidated_at)', @@ -63,7 +65,7 @@ with requester_wait_time_filtered_statuses as ( "cast(" ~ dbt_date.week_start('ticket_status_crossed_with_schedule.valid_starting_at','UTC') ~ "as " ~ dbt.type_timestamp() ~ ")", "cast(ticket_status_crossed_with_schedule.valid_starting_at as " ~ dbt.type_timestamp() ~ ")", 'second') }} - /60 - standard_offset_minutes + /60 - offset_minutes ) as valid_starting_at_in_minutes_from_week, ({{ dbt.datediff( 'ticket_status_crossed_with_schedule.valid_starting_at', @@ -131,8 +133,8 @@ with requester_wait_time_filtered_statuses as ( and weekly_period_requester_wait_time.schedule_id = schedule.schedule_id -- this chooses the Daylight Savings Time or Standard Time version of the schedule -- We have everything calculated within a week, so take us to the appropriate week first by adding the week_number * minutes-in-a-week to the minute-mark where we start and stop counting for the week - and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_end_time_minute', from_date_or_timestamp='start_week_date') }} as {{ dbt.type_timestamp() }}) > cast(schedule.valid_from as {{ dbt.type_timestamp() }}) - and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_start_time_minute', from_date_or_timestamp='start_week_date') }} as {{ dbt.type_timestamp() }}) < cast(schedule.valid_until as {{ dbt.type_timestamp() }}) + and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_end_time_minute', from_date_or_timestamp='start_week_date') }} as date) > cast(schedule.valid_from as date) + and cast( {{ dbt.dateadd(datepart='minute', interval='week_number * (7*24*60) + ticket_week_start_time_minute', from_date_or_timestamp='start_week_date') }} as date) < cast(schedule.valid_until as date) ), intercepted_periods_with_running_total as ( From fd4618b6bee46b1a967721e6954b40126eb5e20b Mon Sep 17 00:00:00 2001 From: fivetran-catfritz <111930712+fivetran-catfritz@users.noreply.github.com> Date: Tue, 20 Aug 2024 19:56:23 -0500 Subject: [PATCH 4/6] update ticket_schedules --- models/intermediate/int_zendesk__ticket_schedules.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/intermediate/int_zendesk__ticket_schedules.sql b/models/intermediate/int_zendesk__ticket_schedules.sql index e40560e0..b4368165 100644 --- a/models/intermediate/int_zendesk__ticket_schedules.sql +++ b/models/intermediate/int_zendesk__ticket_schedules.sql @@ -104,7 +104,7 @@ with ticket as ( on schedules.time_zone = timezones_with_dst.time_zone and cast(ticket_schedules.schedule_created_at as date) >= cast(timezones_with_dst.valid_from as date) and cast(ticket_schedules.schedule_created_at as date) < cast(timezones_with_dst.valid_until as date) - group by 1,2,3,4,5,6,7 + {{ dbt_utils.group_by(n=7) }} ) select * From 0bf297e89c33e4015585cffe3a1a9a610488b83b Mon Sep 17 00:00:00 2001 From: fivetran-catfritz <111930712+fivetran-catfritz@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:28:41 -0500 Subject: [PATCH 5/6] add config and move to int --- .../int_zendesk__schedule_spine.sql | 87 +------------------ .../int_zendesk__timezones_with_dst.sql | 2 + 2 files changed, 6 insertions(+), 83 deletions(-) diff --git a/models/intermediate/int_zendesk__schedule_spine.sql b/models/intermediate/int_zendesk__schedule_spine.sql index 0110f28e..1c2d6241 100644 --- a/models/intermediate/int_zendesk__schedule_spine.sql +++ b/models/intermediate/int_zendesk__schedule_spine.sql @@ -5,15 +5,10 @@ End result will include `valid_from` and `valid_until` columns which we will use downstream to determine which schedule-offset to associate with each ticket (ie standard time vs daylight time) */ -with timezone as ( +with timezones_with_dst as ( select * - from {{ var('time_zone') }} - -), daylight_time as ( - - select * - from {{ var('daylight_time') }} + from {{ ref('int_zendesk__timezones_with_dst') }} ), schedule as ( @@ -36,80 +31,6 @@ with timezone as ( on holiday_start_date_at <= cast(date_day as {{ dbt.type_timestamp() }} ) and holiday_end_date_at >= cast(date_day as {{ dbt.type_timestamp() }} ) -), timezone_with_dt as ( - - select - timezone.*, - daylight_time.daylight_start_utc, - daylight_time.daylight_end_utc, - daylight_time.daylight_offset_minutes - - from timezone - left join daylight_time - on timezone.time_zone = daylight_time.time_zone - -), order_timezone_dt as ( - - select - *, - -- will be null for timezones without any daylight savings records (and the first entry) - -- we will coalesce the first entry date with .... the X years ago - lag(daylight_end_utc, 1) over (partition by time_zone order by daylight_end_utc asc) as last_daylight_end_utc, - -- will be null for timezones without any daylight savings records (and the last entry) - -- we will coalesce the last entry date with the current date - lead(daylight_start_utc, 1) over (partition by time_zone order by daylight_start_utc asc) as next_daylight_start_utc - - from timezone_with_dt - -), split_timezones as ( - - -- standard schedule (includes timezones without DT) - -- starts: when the last Daylight Savings ended - -- ends: when the next Daylight Savings starts - select - time_zone, - standard_offset_minutes as offset_minutes, - - -- last_daylight_end_utc is null for the first record of the time_zone's daylight time, or if the TZ doesn't use DT - coalesce(last_daylight_end_utc, cast('1970-01-01' as date)) as valid_from, - - -- daylight_start_utc is null for timezones that don't use DT - coalesce(daylight_start_utc, cast( {{ dbt.dateadd('year', 1, dbt.current_timestamp_backcompat()) }} as date)) as valid_until - - from order_timezone_dt - - union all - - -- DT schedule (excludes timezones without it) - -- starts: when this Daylight Savings started - -- ends: when this Daylight Savings ends - select - time_zone, - -- Pacific Time is -8h during standard time and -7h during DT - standard_offset_minutes + daylight_offset_minutes as offset_minutes, - daylight_start_utc as valid_from, - daylight_end_utc as valid_until - - from order_timezone_dt - where daylight_offset_minutes is not null - - union all - - select - time_zone, - standard_offset_minutes as offset_minutes, - - -- Get the latest daylight_end_utc time and set that as the valid_from - max(daylight_end_utc) as valid_from, - - -- If the latest_daylight_end_time_utc is less than todays timestamp, that means DST has ended. Therefore, we will make the valid_until in the future. - cast( {{ dbt.dateadd('year', 1, dbt.current_timestamp_backcompat()) }} as date) as valid_until - - from order_timezone_dt - group by 1, 2 - -- We only want to apply this logic to time_zone's that had daylight saving time and it ended at a point. For example, Hong Kong ended DST in 1979. - having cast(max(daylight_end_utc) as date) < cast({{ dbt.current_timestamp_backcompat() }} as date) - ), calculate_schedules as ( select @@ -127,8 +48,8 @@ with timezone as ( cast(split_timezones.valid_until as {{ dbt.type_timestamp() }}) as valid_until from schedule - left join split_timezones - on split_timezones.time_zone = schedule.time_zone + left join timezones_with_dst + on timezones_with_dst.time_zone = schedule.time_zone -- Now we need take holiday's into consideration and perform the following transformations to account for Holidays in existing schedules ), holiday_start_end_times as ( diff --git a/models/intermediate/int_zendesk__timezones_with_dst.sql b/models/intermediate/int_zendesk__timezones_with_dst.sql index 565ea5a7..52ae625a 100644 --- a/models/intermediate/int_zendesk__timezones_with_dst.sql +++ b/models/intermediate/int_zendesk__timezones_with_dst.sql @@ -1,3 +1,5 @@ +{{ config(enabled=var('using_schedules', True)) }} + with timezone as ( select * From 76a6b963485d06062f868cea0c29d3b315228df4 Mon Sep 17 00:00:00 2001 From: fivetran-catfritz <111930712+fivetran-catfritz@users.noreply.github.com> Date: Tue, 20 Aug 2024 20:32:58 -0500 Subject: [PATCH 6/6] add config and move to int --- .../int_zendesk__schedule_spine.sql | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/models/intermediate/int_zendesk__schedule_spine.sql b/models/intermediate/int_zendesk__schedule_spine.sql index 1c2d6241..5fe9be3b 100644 --- a/models/intermediate/int_zendesk__schedule_spine.sql +++ b/models/intermediate/int_zendesk__schedule_spine.sql @@ -5,7 +5,12 @@ End result will include `valid_from` and `valid_until` columns which we will use downstream to determine which schedule-offset to associate with each ticket (ie standard time vs daylight time) */ -with timezones_with_dst as ( +with timezone as ( + + select * + from {{ var('time_zone') }} + +), timezones_with_dst as ( select * from {{ ref('int_zendesk__timezones_with_dst') }} @@ -40,12 +45,12 @@ with timezones_with_dst as ( schedule.end_time, schedule.created_at, schedule.schedule_name, - schedule.start_time - coalesce(split_timezones.offset_minutes, 0) as start_time_utc, - schedule.end_time - coalesce(split_timezones.offset_minutes, 0) as end_time_utc, - coalesce(split_timezones.offset_minutes, 0) as offset_minutes_to_add, + schedule.start_time - coalesce(timezones_with_dst.offset_minutes, 0) as start_time_utc, + schedule.end_time - coalesce(timezones_with_dst.offset_minutes, 0) as end_time_utc, + coalesce(timezones_with_dst.offset_minutes, 0) as offset_minutes_to_add, -- we'll use these to determine which schedule version to associate tickets with - cast(split_timezones.valid_from as {{ dbt.type_timestamp() }}) as valid_from, - cast(split_timezones.valid_until as {{ dbt.type_timestamp() }}) as valid_until + cast(timezones_with_dst.valid_from as {{ dbt.type_timestamp() }}) as valid_from, + cast(timezones_with_dst.valid_until as {{ dbt.type_timestamp() }}) as valid_until from schedule left join timezones_with_dst