diff --git a/models/marts/reporting/rep_exchange__company_conversion_funnels.sql b/models/marts/reporting/rep_exchange__company_conversion_funnels.sql index df53b08..3150e13 100644 --- a/models/marts/reporting/rep_exchange__company_conversion_funnels.sql +++ b/models/marts/reporting/rep_exchange__company_conversion_funnels.sql @@ -54,22 +54,20 @@ clean_company_bookings AS ( ON (bookings.company_id = remove_supplier_company.company_id) ), - company_first_time_order_date AS ( SELECT - transaction_order_id, + order_id, company_id, order_created_datetime FROM clean_company_transaction_orders WHERE - is_first_time_company_completed = '1' + is_first_time_order_company_completed = 1 ), - ---start defind funnel activity +--start define funnel activity repeat_completed_order_after_60days_activities AS ( SELECT clean_company_transaction_orders.company_id, @@ -121,7 +119,7 @@ first_time_order_completed_activities AS ( FROM clean_company_transaction_orders WHERE - clean_company_transaction_orders.is_first_time_company_completed = 1 + clean_company_transaction_orders.is_first_time_order_company_completed = 1 GROUP BY clean_company_transaction_orders.company_id @@ -138,7 +136,7 @@ first_time_order_activities AS ( FROM clean_company_transaction_orders WHERE - clean_company_transaction_orders.is_first_time_company = 1 + clean_company_transaction_orders.is_first_time_order_company = 1 GROUP BY clean_company_transaction_orders.company_id diff --git a/models/marts/reporting/rep_exchange__company_engagement_behaviors.sql b/models/marts/reporting/rep_exchange__company_engagement_behaviors.sql index 312bba9..9aacb52 100644 --- a/models/marts/reporting/rep_exchange__company_engagement_behaviors.sql +++ b/models/marts/reporting/rep_exchange__company_engagement_behaviors.sql @@ -1,13 +1,14 @@ -- AVAILALE FILTER VALUE {% set day_use_to_churn = 61 %} + -- IMPORT WITH companies AS ( SELECT * FROM {{ ref('dim_exchange__companies') }} ), transaction_orders AS ( - SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} + SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} ), @@ -18,15 +19,15 @@ remove_supplier_company AS ( FROM companies WHERE business_type = 'IMPORTER' + ), - order_date_row_rank AS ( SELECT *, row_number() OVER - (PARTITION BY transaction_orders.company_id - ORDER BY transaction_orders.order_created_datetime) AS row_rank_index + (PARTITION BY company_id + ORDER BY order_created_datetime, order_id) AS row_rank_index FROM transaction_orders @@ -36,54 +37,54 @@ get_next_and_previous_order_date_orders AS ( SELECT order_date_row_rank.*, companies.is_migrated_company, - next_order_date_row_rank_clone.order_created_datetime AS next_order_created_datetime, - previous_order_date_row_rank_clone.order_created_datetime AS previous_order_created_datetime, + previous_order_date_row_rank_clone.order_created_datetime AS previous_order_created_datetime, companies.company_marking_id, - companies.company_created_datetime + companies.company_created_datetime FROM order_date_row_rank LEFT JOIN companies ON (order_date_row_rank.company_id = companies.company_id) - LEFT JOIN order_date_row_rank AS next_order_date_row_rank_clone + LEFT JOIN order_date_row_rank AS next_order_date_row_rank_clone ON order_date_row_rank.row_rank_index = next_order_date_row_rank_clone.row_rank_index - 1 AND order_date_row_rank.company_id = next_order_date_row_rank_clone.company_id - LEFT JOIN order_date_row_rank AS previous_order_date_row_rank_clone + LEFT JOIN order_date_row_rank AS previous_order_date_row_rank_clone ON order_date_row_rank.row_rank_index = previous_order_date_row_rank_clone.row_rank_index + 1 - AND order_date_row_rank.company_id = previous_order_date_row_rank_clone.company_id + AND order_date_row_rank.company_id = previous_order_date_row_rank_clone.company_id ), -- Register / Churn / Register; Churn company_register_events AS ( SELECT - remove_supplier_company.company_id AS company_id, + remove_supplier_company.company_id AS company_id, remove_supplier_company.is_migrated_company, - IFF(MAX(transaction_orders.company_id) IS NULL, 1, 0) AS is_never_order_company, + IFF(MAX(transaction_orders.company_id) IS NULL, 1, 0) AS is_never_order_company, remove_supplier_company.company_marking_id, - 'Register' AS register_event, + 'Register' AS register_event, IFF( DATEDIFF( day, remove_supplier_company.company_created_datetime, COALESCE(MIN(transaction_orders.order_created_datetime), CURRENT_DATE()) ) - >= {{day_use_to_churn}}, - 'Churn', - NULL) AS churn_event, - - RTRIM(CONCAT( - CASE WHEN register_event IS NOT NULL THEN 'Register, ' ELSE '' END, - CASE WHEN churn_event IS NOT NULL THEN 'Churn, ' ELSE '' END ),', ' ) AS concat_event, - - remove_supplier_company.company_created_datetime AS event_datetime + >= {{day_use_to_churn}}, 'Churn', NULL + ) AS churn_event, + + RTRIM( + CONCAT( + CASE WHEN register_event IS NOT NULL THEN 'Register, ' ELSE '' END, + CASE WHEN churn_event IS NOT NULL THEN 'Churn, ' ELSE '' END ),', ' + ) AS concat_event, + + remove_supplier_company.company_created_datetime AS event_datetime FROM remove_supplier_company - + LEFT JOIN transaction_orders - ON (remove_supplier_company.company_id = transaction_orders.company_id) - + ON (remove_supplier_company.company_id = transaction_orders.company_id) + GROUP BY remove_supplier_company.company_id, remove_supplier_company.company_marking_id, @@ -98,7 +99,65 @@ firsttime_repeat_churn_reactive_order_events AS ( company_id, company_marking_id, is_migrated_company, - 0 AS is_never_order_company, + 0 AS is_never_order_company, + order_id AS transaction_order_id, + order_status, + order_payment_method AS payment_method, + base_currency_id, + quote_currency_id, + order_base_to_quote_currency_exchange_rate AS base_to_quote_currency_exchange_rate, + order_value_rm AS value_rm, + order_tax_rm AS tax_rm, + order_service_charge_rm AS service_charge_rm, + + IFF(is_first_time_order_company = 1, 'First Time Order', NULL) AS first_time_order_event, + IFF(is_first_time_order_company = 0, 'Repeat', NULL) AS repeat_event, + IFF(DATEDIFF(day, order_created_datetime, COALESCE(next_order_created_datetime, CURRENT_DATE())) >= {{day_use_to_churn}}, 'Churn', NULL ) AS churn_event, + IFF(DATEDIFF(day, COALESCE(previous_order_created_datetime, company_created_datetime), order_created_datetime) >= {{day_use_to_churn}}, 'Reactive', NULL) AS reactive_event, + + RTRIM(CONCAT( + CASE WHEN first_time_order_event IS NOT NULL THEN 'First Time Order, ' ELSE '' END, + CASE WHEN repeat_event IS NOT NULL THEN 'Repeat, ' ELSE '' END, + CASE WHEN reactive_event IS NOT NULL THEN 'Reactive, ' ELSE '' END, + CASE WHEN churn_event IS NOT NULL THEN 'Churn, ' ELSE '' END ),', ' ) AS concat_event, + + order_created_datetime AS event_datetime + + FROM get_next_and_previous_order_date_orders +), + +union_event_tables AS ( + SELECT + company_id, + company_marking_id, + is_migrated_company, + is_never_order_company, + NULL AS transaction_order_id, + NULL AS order_status, + NULL AS payment_method, + NULL AS base_currency_id, + NULL AS quote_currency_id, + NULL AS base_to_quote_currency_exchange_rate, + NULL AS value_rm, + NULL AS tax_rm, + NULL AS service_charge_rm, + register_event, + NULL AS first_time_order_event, + NULL AS repeat_event, + churn_event, + NULL AS reactive_event, + concat_event, + event_datetime + + FROM company_register_events + + UNION + + SELECT + company_id, + company_marking_id, + is_migrated_company, + is_never_order_company, transaction_order_id, order_status, payment_method, @@ -108,72 +167,15 @@ firsttime_repeat_churn_reactive_order_events AS ( value_rm, tax_rm, service_charge_rm, - IFF(is_first_time_company = 1, 'First Time Order', NULL) AS first_time_order_event, - IFF(is_first_time_company = 0, 'Repeat', NULL) AS repeat_event, - IFF(DATEDIFF(day, order_created_datetime, COALESCE(next_order_created_datetime, CURRENT_DATE())) >= {{day_use_to_churn}}, 'Churn', NULL ) AS churn_event, - IFF(DATEDIFF(day, COALESCE(previous_order_created_datetime, company_created_datetime), order_created_datetime) >= {{day_use_to_churn}}, 'Reactive', NULL) AS reactive_event, - - RTRIM(CONCAT( - CASE WHEN first_time_order_event IS NOT NULL THEN 'First Time Order, ' ELSE '' END, - CASE WHEN repeat_event IS NOT NULL THEN 'Repeat, ' ELSE '' END, - CASE WHEN reactive_event IS NOT NULL THEN 'Reactive, ' ELSE '' END, - CASE WHEN churn_event IS NOT NULL THEN 'Churn, ' ELSE '' END ),', ' ) AS concat_event, + NULL AS register_event, + first_time_order_event, + repeat_event, + churn_event, + reactive_event, + concat_event, + event_datetime - order_created_datetime AS event_datetime - - FROM get_next_and_previous_order_date_orders -), - -union_event_tables AS ( - SELECT - company_id, - company_marking_id, - is_migrated_company, - is_never_order_company, - NULL AS transaction_order_id, - NULL AS order_status, - NULL AS payment_method, - NULL AS base_currency_id, - NULL AS quote_currency_id, - NULL AS base_to_quote_currency_exchange_rate, - NULL AS value_rm, - NULL AS tax_rm, - NULL AS service_charge_rm, - register_event, - NULL AS first_time_order_event, - NULL AS repeat_event, - churn_event, - NULL AS reactive_event, - concat_event, - event_datetime - - FROM company_register_events - - UNION - - SELECT - company_id, - company_marking_id, - is_migrated_company, - is_never_order_company, - transaction_order_id, - order_status, - payment_method, - base_currency_id, - quote_currency_id, - base_to_quote_currency_exchange_rate, - value_rm, - tax_rm, - service_charge_rm, - NULL AS register_event, - first_time_order_event, - repeat_event, - churn_event, - reactive_event, - concat_event, - event_datetime - - FROM firsttime_repeat_churn_reactive_order_events + FROM firsttime_repeat_churn_reactive_order_events ), -- FINAL @@ -209,7 +211,7 @@ final__rep_exchange__company_engagement_behaviors AS ( -- metadata '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime - + FROM union_event_tables ) diff --git a/models/marts/reporting/rep_exchange__company_lists.sql b/models/marts/reporting/rep_exchange__company_lists.sql index 793ac3d..f6cd067 100644 --- a/models/marts/reporting/rep_exchange__company_lists.sql +++ b/models/marts/reporting/rep_exchange__company_lists.sql @@ -1,47 +1,46 @@ --- AVAILALE FILTER VALUE +-- AVAILABLE FILTER VALUE -- Source:preset_custom_filter Column:day_use_to_churn {% set day_use_to_churn = 61 %} -- IMPORT WITH companies AS ( - SELECT * FROM {{ ref('dim_exchange__companies') }} + SELECT * FROM {{ ref('dim_exchange__companies') }} ), transaction_orders AS ( - SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} + SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} ), -- LOGIC company_agg AS ( - SELECT - companies.company_id, - companies.is_migrated_company, - companies.company_marking_id, - companies.company_created_datetime, - COUNT(transaction_orders.transaction_order_id) AS count_order, - COUNT(IFF(transaction_orders.order_status = 'COMPLETED', transaction_orders.transaction_order_id, null)) AS count_completed_order, - MAX(transaction_orders.order_created_datetime) AS last_order_datetime, - COALESCE(last_order_datetime, company_created_datetime) AS last_activity_datetime, - IFF(companies.company_created_datetime < '2021-07-01', 1, 0) AS is_wrong_created_datetime_company, - IFF(MAX(transaction_orders.order_created_datetime) IS NULL, 1, 0) AS is_never_order_company, - IFF(DATEDIFF(day, last_activity_datetime, CURRENT_DATE()) >= {{day_use_to_churn}}, 1, 0 ) AS is_churn_company, - IFF( is_churn_company = 1, DATEDIFF(day, company_created_datetime, last_activity_datetime) + {{day_use_to_churn}}, NULL) AS create_to_churn_day, + SELECT + companies.company_id, + companies.is_migrated_company, + companies.company_marking_id, + companies.company_created_datetime, + COUNT(transaction_orders.order_id) AS count_order, + COUNT(IFF(transaction_orders.order_status = 'COMPLETED', transaction_orders.order_id, null)) AS count_completed_order, + MAX(transaction_orders.order_created_datetime) AS last_order_datetime, + COALESCE(last_order_datetime, company_created_datetime) AS last_activity_datetime, + IFF(companies.company_created_datetime < '2021-07-01', 1, 0) AS is_wrong_created_datetime_company, + IFF(MAX(transaction_orders.order_created_datetime) IS NULL, 1, 0) AS is_never_order_company, + IFF(DATEDIFF(day, last_activity_datetime, CURRENT_DATE()) >= {{day_use_to_churn}}, 1, 0 ) AS is_churn_company, + IFF( is_churn_company = 1, DATEDIFF(day, company_created_datetime, last_activity_datetime) + {{day_use_to_churn}}, NULL) AS create_to_churn_day, - '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime + '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime + + FROM companies - FROM - companies - - LEFT JOIN transaction_orders - ON (companies.company_id = transaction_orders.company_id) - - GROUP BY - companies.company_id, - companies.is_migrated_company, - companies.company_marking_id, - companies.company_created_datetime + LEFT JOIN transaction_orders + ON (companies.company_id = transaction_orders.company_id) + + GROUP BY + companies.company_id, + companies.is_migrated_company, + companies.company_marking_id, + companies.company_created_datetime ), -- FINAL @@ -62,7 +61,6 @@ final__rep_exchange__company_lists AS ( count_completed_order, create_to_churn_day, - -- date/times company_created_datetime, last_order_datetime, @@ -74,5 +72,4 @@ final__rep_exchange__company_lists AS ( FROM company_agg ) - SELECT * FROM final__rep_exchange__company_lists \ No newline at end of file diff --git a/models/marts/reporting/rep_exchange__daily_orders.sql b/models/marts/reporting/rep_exchange__daily_orders.sql index 6f747ca..8d3e0e9 100644 --- a/models/marts/reporting/rep_exchange__daily_orders.sql +++ b/models/marts/reporting/rep_exchange__daily_orders.sql @@ -1,16 +1,8 @@ -- IMPORT -WITH transaction_orders AS ( +WITH orders AS ( SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} ), -bookings AS ( - SELECT * FROM {{ ref('fct_exchange__bookings') }} -), - -transaction_costs AS ( - SELECT * FROM {{ ref('fct_exchange__transaction_costs') }} -), - companies AS ( SELECT * FROM {{ ref('dim_exchange__companies') }} ), @@ -23,23 +15,18 @@ dates AS ( SELECT * FROM {{ ref('dim__dates') }} ), - ---LOGIC -transaction_orders_get_next_order_created_datetime AS ( - SELECT - *, - LEAD(order_created_datetime) OVER (PARTITION BY company_id ORDER BY order_created_datetime, transaction_order_id) AS next_order_created_datetime - - FROM - transaction_orders +users AS ( + SELECT * FROM {{ ref('dim_exchange__users') }} ), +--LOGIC fct_and_dim_joins AS ( SELECT - bookings.booking_id, - bookings.booking_marking_id, - bookings.company_id, + orders.booking_id, + orders.booking_marking_id, + orders.company_id, + companies.name AS company_name, companies.company_marking_id AS company_marking_id, companies.autocount_id AS company_autocount_id, companies.company_type AS company_type, @@ -54,107 +41,162 @@ fct_and_dim_joins AS ( companies.latitude AS company_latitude, companies.longitude AS company_longitude, - bookings.user_id, - bookings.bank_id, + orders.user_id, + orders.bank_id, - fix_currencies.currency_name AS fix_currency_name, + fix_currencies.currency_name AS fix_currency_name, - quote_currencies.currency_name AS quote_currency_name, + quote_currencies.currency_name AS quote_currency_name, - base_currencies.currency_name AS base_currency_name, + base_currencies.currency_name AS base_currency_name, - bookings.service_type, - bookings.status AS booking_status, - bookings.is_first_time_company AS is_first_time_booking_company, - bookings.is_first_time_company_completed AS is_first_time_booking_company_completed, - bookings.is_first_time_user AS is_first_time_booking_user, - bookings.is_first_time_user_completed AS is_first_time_booking_user_completed, - bookings.estimate_base_to_quote_currency_exchange_rate AS estimate_booking_base_to_quote_currency_exchange_rate, - bookings.estimate_quote_value AS estimate_booking_quote_value, - bookings.estimate_base_value AS estimate_booking_base_value, - bookings.estimate_value_rm AS estimate_booking_value_rm, - bookings.booking_created_datetime, - bookings.booking_approved_datetime, - bookings.booking_completed_datetime, - bookings.booking_suspended_datetime, + orders.service_type, + orders.booking_status, + orders.is_first_time_booking_company, + orders.is_first_time_booking_company_completed, + orders.is_first_time_booking_user, + orders.is_first_time_booking_user_completed, + orders.estimate_booking_base_to_quote_currency_exchange_rate, + orders.estimate_booking_quote_value, + orders.estimate_booking_base_value, + orders.estimate_booking_value_rm, + orders.booking_created_datetime, + orders.booking_approved_datetime, + orders.booking_completed_datetime, + orders.booking_suspended_datetime, - transaction_orders_get_next_order_created_datetime.transaction_order_id AS order_id, - transaction_orders_get_next_order_created_datetime.payment_method AS order_payment_method, - transaction_orders_get_next_order_created_datetime.order_status, - transaction_orders_get_next_order_created_datetime.payment_reference AS order_payment_reference, - transaction_orders_get_next_order_created_datetime.bill_number AS order_bill_number, - transaction_orders_get_next_order_created_datetime.is_first_time_company AS is_first_time_order_company, - transaction_orders_get_next_order_created_datetime.is_first_time_company_completed AS is_first_time_order_company_completed, - transaction_orders_get_next_order_created_datetime.is_first_time_user AS is_first_time_order_user, - transaction_orders_get_next_order_created_datetime.is_first_time_user_completed AS is_first_time_order_user_completed, - transaction_orders_get_next_order_created_datetime.base_to_quote_currency_exchange_rate AS order_base_to_quote_currency_exchange_rate , - transaction_orders_get_next_order_created_datetime.base_value AS order_base_value , - transaction_orders_get_next_order_created_datetime.base_service_charge AS order_base_service_charge , - transaction_orders_get_next_order_created_datetime.base_tax AS order_base_tax , - transaction_orders_get_next_order_created_datetime.quote_value AS order_quote_value , - transaction_orders_get_next_order_created_datetime.value_rm AS order_value_rm , - transaction_orders_get_next_order_created_datetime.service_charge_rm AS order_service_charge_rm , - transaction_orders_get_next_order_created_datetime.tax_rm AS order_tax_rm , - transaction_orders_get_next_order_created_datetime.total_value_rm AS total_order_value_rm, + orders.order_id, + orders.order_payment_method, + orders.order_status, + orders.order_payment_reference, + orders.order_bill_number, + orders.is_first_time_order_company, + orders.is_first_time_order_company_completed, + orders.is_first_time_order_user, + orders.is_first_time_order_user_completed, + orders.order_base_to_quote_currency_exchange_rate, + orders.order_base_value, + orders.order_base_service_charge, + orders.order_base_tax, + orders.order_quote_value, + orders.order_value_rm, + orders.order_service_charge_rm, + orders.order_tax_rm, + orders.total_order_value_rm, - transaction_orders_get_next_order_created_datetime.order_created_datetime, - order_created_dates.first_day_of_week AS order_created_week, + order_created_dates.first_day_of_week AS order_created_week, + orders.order_created_datetime, + orders.order_pending_submission_datetime, + orders.order_pending_verification_datetime, + + -- Estimated delivery datetime based on CIEF internal SLA (cutoff time 4pm) + CASE + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1 DAY TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) < 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_included_base_date || ' 23:59:59 +08:00') + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1 DAY TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) >= 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_excluded_base_date || ' 23:59:59 +08:00') - transaction_orders_get_next_order_created_datetime.order_pending_submission_datetime, - transaction_orders_get_next_order_created_datetime.order_pending_verification_datetime, - transaction_orders_get_next_order_created_datetime.order_approved_datetime, - transaction_orders_get_next_order_created_datetime.order_completed_datetime, - transaction_orders_get_next_order_created_datetime.order_rejected_datetime, - transaction_orders_get_next_order_created_datetime.order_suspended_datetime, - transaction_orders_get_next_order_created_datetime.next_order_created_datetime, + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '3 DAYS TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) < 16 + THEN TO_TIMESTAMP(order_created_dates.add_3_working_day_included_base_date || ' 23:59:59 +08:00') + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '3 DAYS TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) >= 16 + THEN TO_TIMESTAMP(order_created_dates.add_3_working_day_excluded_base_date || ' 23:59:59 +08:00') - transaction_costs.transaction_cost_id AS cost_id, - transaction_costs.bank_id AS currency_vendor_bank_id, - transaction_costs.transaction_type AS cost_transaction_type, - transaction_costs.payment_method AS cost_payment_method, - transaction_costs.status AS cost_status, - transaction_costs.payment_reference AS cost_payment_reference, - transaction_costs.bill_number AS cost_bill_number, - transaction_costs.base_value AS cost_base_value, - transaction_costs.quote_value AS cost_quote_value, - transaction_costs.base_to_quote_currency_exchange_rate AS cost_base_to_quote_currency_exchange_rate, - transaction_costs.base_tax AS cost_base_tax, - transaction_costs.base_service_charge AS cost_base_service_charge, - transaction_costs.value_rm AS cost_value_rm, - transaction_costs.tax_rm AS cost_tax_rm, - transaction_costs.service_charge_rm AS cost_service_charge_rm, - transaction_costs.total_value_rm AS total_cost_value_rm, - transaction_costs.cost_created_datetime, - transaction_costs.cost_pending_submission_datetime, - transaction_costs.cost_pending_verification_datetime, - transaction_costs.cost_approved_datetime, - transaction_costs.cost_completed_datetime, - transaction_costs.cost_rejected_datetime, + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1688 PAYMENT' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) < 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_included_base_date || ' 23:59:59 +08:00') + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1688 PAYMENT' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) >= 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_excluded_base_date || ' 23:59:59 +08:00') - '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime + ELSE null + END AS estimated_order_delivery_datetime_website_sla, + + --- Estimated delivery datetime based on customer expectation + CASE + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1 DAY TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) < 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_included_base_date) + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1 DAY TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) >= 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_excluded_base_date) + + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '3 DAYS TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) < 16 + THEN TO_TIMESTAMP(order_created_dates.add_3_working_day_included_base_date) + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '3 DAYS TRANSFER' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) >= 16 + THEN TO_TIMESTAMP(order_created_dates.add_3_working_day_excluded_base_date) + + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1688 PAYMENT' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) < 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_included_base_date) + WHEN orders.order_created_datetime >= '2023-01-01' AND orders.service_type = '1688 PAYMENT' AND DATE_PART(HOUR, orders.order_pending_verification_datetime) >= 16 + THEN TO_TIMESTAMP(order_created_dates.add_1_working_day_excluded_base_date) + + ELSE null + END AS estimated_order_delivery_datetime_customer_expectation, + + -- On time delivery boolean (CIEF internal SLA) + CASE + WHEN order_completed_datetime IS NULL THEN NULL + WHEN estimated_order_delivery_datetime_website_sla > order_completed_datetime THEN 1 + ELSE 0 + END AS is_on_time_delivery_website_sla, + + -- On time delivery boolean (Customer Expectation) + CASE + WHEN order_completed_datetime IS NULL THEN NULL + WHEN estimated_order_delivery_datetime_customer_expectation > order_completed_datetime THEN 1 + ELSE 0 + END AS is_on_time_delivery_customer_expectation, + + orders.order_approved_datetime, + orders.order_completed_datetime, + orders.order_rejected_datetime, + orders.order_suspended_datetime, + orders.next_order_created_datetime, + orders.order_expected_expired_datetime, + orders.order_expired_datetime, + + orders.cost_id, + orders.supplier_company_id, + supplier_companies.name AS supplier_company_name, + orders.currency_vendor_bank_id, + orders.cost_transaction_type, + orders.cost_payment_method, + orders.cost_status, + orders.cost_payment_reference, + orders.cost_bill_number, + orders.cost_base_value, + orders.cost_quote_value, + orders.cost_base_to_quote_currency_exchange_rate, + orders.cost_base_tax, + orders.cost_base_service_charge, + orders.cost_value_rm, + orders.cost_tax_rm, + orders.cost_service_charge_rm, + orders.total_cost_value_rm, + orders.cost_created_datetime, + orders.cost_pending_submission_datetime, + orders.cost_pending_verification_datetime, + orders.cost_approved_datetime, + orders.cost_completed_datetime, + orders.cost_rejected_datetime, + + '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime - FROM bookings - - RIGHT JOIN transaction_orders_get_next_order_created_datetime - ON (bookings.booking_id = transaction_orders_get_next_order_created_datetime.booking_id) - - LEFT JOIN transaction_costs - ON (transaction_orders_get_next_order_created_datetime.transaction_order_id = transaction_costs.transaction_order_id) + FROM orders LEFT JOIN companies - ON (bookings.company_id = companies.company_id) + ON (orders.company_id = companies.company_id) + + LEFT JOIN companies AS supplier_companies + ON (orders.supplier_company_id = supplier_companies.company_id) LEFT JOIN dates AS order_created_dates - ON (DATE(transaction_orders_get_next_order_created_datetime.order_created_datetime) = order_created_dates.date_day) + ON (DATE(orders.order_created_datetime) = order_created_dates.date_day) LEFT JOIN currencies AS fix_currencies - ON (bookings.fix_currency_id = fix_currencies.currency_id) + ON (orders.fix_currency_id = fix_currencies.currency_id) LEFT JOIN currencies AS quote_currencies - ON (bookings.quote_currency_id = quote_currencies.currency_id) + ON (orders.quote_currency_id = quote_currencies.currency_id) LEFT JOIN currencies AS base_currencies - ON (bookings.base_currency_id = base_currencies.currency_id) + ON (orders.base_currency_id = base_currencies.currency_id) ), --FINAL @@ -163,16 +205,19 @@ final__rep_exchange__daily_orders AS ( -- ids order_id, bank_id, - company_id, + company_id, company_marking_id, company_autocount_id, user_id, cost_id, + supplier_company_id, currency_vendor_bank_id, booking_id, booking_marking_id, -- dimensions + company_name, + supplier_company_name, fix_currency_name, quote_currency_name, base_currency_name, @@ -206,6 +251,8 @@ final__rep_exchange__daily_orders AS ( is_first_time_booking_company_completed, is_first_time_booking_user, is_first_time_booking_user_completed, + is_on_time_delivery_website_sla, + is_on_time_delivery_customer_expectation, -- measures order_base_to_quote_currency_exchange_rate, @@ -234,12 +281,14 @@ final__rep_exchange__daily_orders AS ( -- date/times order_created_datetime, order_created_week, + order_expected_expired_datetime, order_pending_submission_datetime, order_pending_verification_datetime, order_approved_datetime, order_completed_datetime, order_rejected_datetime, order_suspended_datetime, + order_expired_datetime, next_order_created_datetime, cost_created_datetime, cost_pending_submission_datetime, @@ -251,11 +300,14 @@ final__rep_exchange__daily_orders AS ( booking_approved_datetime, booking_completed_datetime, booking_suspended_datetime, + estimated_order_delivery_datetime_website_sla, + estimated_order_delivery_datetime_customer_expectation, -- metadata _dbt_ran_datetime FROM fct_and_dim_joins + ) -SELECT * FROM final__rep_exchange__daily_orders +SELECT * FROM final__rep_exchange__daily_orders \ No newline at end of file diff --git a/models/marts/reporting/rep_exchange__rfm.sql b/models/marts/reporting/rep_exchange__rfm.sql index b40cf87..893099d 100644 --- a/models/marts/reporting/rep_exchange__rfm.sql +++ b/models/marts/reporting/rep_exchange__rfm.sql @@ -1,4 +1,4 @@ --- AVAILALE FILTER VALUE +-- AVAILABLE FILTER VALUE {% set custom_one_year_from_date = modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")).date() - modules.datetime.timedelta(365) %} {% set custom_one_year_to_date = modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")).date() %} @@ -12,244 +12,240 @@ -- IMPORT WITH transaction_orders AS ( - SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} + SELECT * FROM {{ ref('fct_exchange__transaction_orders') }} ), - companies AS ( - SELECT * FROM {{ ref('dim_exchange__companies') }} + SELECT * FROM {{ ref('dim_exchange__companies') }} ), -- LOGIC transaction_order_one_years AS ( - SELECT - company_id, - MAX(transaction_orders.order_created_datetime) AS last_approved_or_completed_order_created_datetime_one_year, - DATEDIFF(day, last_approved_or_completed_order_created_datetime_one_year, CURRENT_DATE() ) AS day_after_approved_or_completed_order_one_year, - COUNT(transaction_orders.transaction_order_id) AS number_of_approved_or_completed_order_one_year, - ROUND(SUM(transaction_orders.value_rm + transaction_orders.tax_rm + transaction_orders.service_charge_rm),2) AS total_value_of_approved_or_completed_order_one_year - - FROM - transaction_orders - - WHERE - order_status IN ('APPROVED','COMPLETED') - AND - order_created_datetime >= '{{ custom_one_year_from_date }}' - AND - order_created_datetime < '{{ custom_one_year_to_date }}' - - GROUP BY - company_id + SELECT + company_id, + MAX(transaction_orders.order_created_datetime) AS last_approved_or_completed_order_created_datetime_one_year, + DATEDIFF(day, last_approved_or_completed_order_created_datetime_one_year, CURRENT_DATE() ) AS day_after_approved_or_completed_order_one_year, + COUNT(transaction_orders.order_id) AS number_of_approved_or_completed_order_one_year, + ROUND(SUM(transaction_orders.order_value_rm + transaction_orders.order_tax_rm + transaction_orders.order_service_charge_rm),2) AS total_value_of_approved_or_completed_order_one_year + + FROM + transaction_orders + + WHERE + order_status IN ('APPROVED','COMPLETED') + AND + order_created_datetime >= '{{ custom_one_year_from_date }}' + AND + order_created_datetime < '{{ custom_one_year_to_date }}' + + GROUP BY + company_id ), company_rfm AS ( - SELECT - transaction_orders.company_id, - companies.company_marking_id AS company_marking_id, - MAX(transaction_orders.order_created_datetime) AS last_approved_or_completed_order_created_datetime, + SELECT + transaction_orders.company_id, + companies.company_marking_id AS company_marking_id, + MAX(transaction_orders.order_created_datetime) AS last_approved_or_completed_order_created_datetime, - DATEDIFF(day, last_approved_or_completed_order_created_datetime, CURRENT_DATE() ) AS day_after_approved_or_completed_order_lifetime, - MAX(transaction_order_one_years.day_after_approved_or_completed_order_one_year) AS day_after_approved_or_completed_order_one_year, + DATEDIFF(day, last_approved_or_completed_order_created_datetime, CURRENT_DATE() ) AS day_after_approved_or_completed_order_lifetime, + MAX(transaction_order_one_years.day_after_approved_or_completed_order_one_year) AS day_after_approved_or_completed_order_one_year, - COUNT(transaction_orders.transaction_order_id) AS number_of_approved_or_completed_order_lifetime, - MAX(transaction_order_one_years.number_of_approved_or_completed_order_one_year) AS number_of_approved_or_completed_order_one_year, + COUNT(transaction_orders.order_id) AS number_of_approved_or_completed_order_lifetime, + MAX(transaction_order_one_years.number_of_approved_or_completed_order_one_year) AS number_of_approved_or_completed_order_one_year, - ROUND(SUM(transaction_orders.value_rm + transaction_orders.tax_rm + transaction_orders.service_charge_rm),2) AS total_value_of_approved_or_completed_order_lifetime, - MAX(transaction_order_one_years.total_value_of_approved_or_completed_order_one_year) AS total_value_of_approved_or_completed_order_one_year - - FROM transaction_orders - - LEFT JOIN transaction_order_one_years - ON (transaction_orders.company_id = transaction_order_one_years.company_id) - - LEFT JOIN companies - ON (transaction_orders.company_id = companies.company_id) - - - WHERE - transaction_orders.order_status IN ('APPROVED','COMPLETED') + ROUND(SUM(transaction_orders.order_value_rm + transaction_orders.order_tax_rm + transaction_orders.order_service_charge_rm),2) AS total_value_of_approved_or_completed_order_lifetime, + MAX(transaction_order_one_years.total_value_of_approved_or_completed_order_one_year) AS total_value_of_approved_or_completed_order_one_year - GROUP BY - transaction_orders.company_id, - companies.company_marking_id + FROM transaction_orders + + LEFT JOIN transaction_order_one_years + ON (transaction_orders.company_id = transaction_order_one_years.company_id) + + LEFT JOIN companies + ON (transaction_orders.company_id = companies.company_id) + + + WHERE + transaction_orders.order_status IN ('APPROVED','COMPLETED') + + GROUP BY + transaction_orders.company_id, + companies.company_marking_id ), calculate_rfm AS ( - SELECT - *, - - - CASE - WHEN day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[0]}} THEN 5 - WHEN (day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[0]}} AND day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[1]}}) THEN 4 - WHEN (day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[1]}} AND day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[2]}}) THEN 3 - WHEN (day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[2]}} AND day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[3]}}) THEN 2 - WHEN day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[3]}} THEN 1 - ELSE -999 - END AS r_score_lifetime, - CASE - WHEN number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[0]}} THEN 1 - WHEN (number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[0]}} AND number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[1]}}) THEN 2 - WHEN (number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[1]}} AND number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[2]}}) THEN 3 - WHEN (number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[2]}} AND number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[3]}}) THEN 4 - WHEN number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[3]}} THEN 5 - ELSE -999 - END AS f_score_lifetime, - CASE - WHEN total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[0]}} THEN 1 - WHEN (total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[0]}} AND total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[1]}}) THEN 2 - WHEN (total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[1]}} AND total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[2]}}) THEN 3 - WHEN (total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[2]}} AND total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[3]}}) THEN 4 - WHEN total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[3]}} THEN 5 - ELSE -999 - END AS m_score_lifetime, - - CASE - WHEN (r_score_lifetime = 5) AND (f_score_lifetime = 5) AND (m_score_lifetime = 5) - THEN '1_King' - - WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime = 1) AND (m_score_lifetime = 1) - THEN '10_At Cheap Risk' - - WHEN (r_score_lifetime = 1) AND (f_score_lifetime = 1) AND (m_score_lifetime = 1) - THEN '13_Cheap Lost' - - WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 1 AND 2) AND (m_score_lifetime BETWEEN 4 AND 5) - THEN '4_Whale' - - WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 1 AND 2) - THEN '3_Sardine' + SELECT + *, - WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 3 AND 5) AND (m_score_lifetime BETWEEN 3 AND 5) - THEN '2_Loyal Customer' - - WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 2 AND 5) AND (m_score_lifetime BETWEEN 2 AND 5) - THEN '5_Potention Loyal' + CASE + WHEN day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[0]}} THEN 5 + WHEN (day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[0]}} AND day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[1]}}) THEN 4 + WHEN (day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[1]}} AND day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[2]}}) THEN 3 + WHEN (day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[2]}} AND day_after_approved_or_completed_order_lifetime <= {{recency_list_lifetime[3]}}) THEN 2 + WHEN day_after_approved_or_completed_order_lifetime > {{recency_list_lifetime[3]}} THEN 1 + ELSE -999 + END AS r_score_lifetime, + CASE + WHEN number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[0]}} THEN 1 + WHEN (number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[0]}} AND number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[1]}}) THEN 2 + WHEN (number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[1]}} AND number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[2]}}) THEN 3 + WHEN (number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[2]}} AND number_of_approved_or_completed_order_lifetime <= {{frequency_list_lifetime[3]}}) THEN 4 + WHEN number_of_approved_or_completed_order_lifetime > {{frequency_list_lifetime[3]}} THEN 5 + ELSE -999 + END AS f_score_lifetime, + CASE + WHEN total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[0]}} THEN 1 + WHEN (total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[0]}} AND total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[1]}}) THEN 2 + WHEN (total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[1]}} AND total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[2]}}) THEN 3 + WHEN (total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[2]}} AND total_value_of_approved_or_completed_order_lifetime <= {{monetary_list_lifetime[3]}}) THEN 4 + WHEN total_value_of_approved_or_completed_order_lifetime > {{monetary_list_lifetime[3]}} THEN 5 + ELSE -999 + END AS m_score_lifetime, - WHEN (r_score_lifetime = 5) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 2) - THEN '7_New Customer' + CASE + WHEN (r_score_lifetime = 5) AND (f_score_lifetime = 5) AND (m_score_lifetime = 5) + THEN '1_King' - WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 4 AND 5) - THEN '8_At High Risk' + WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime = 1) AND (m_score_lifetime = 1) + THEN '10_At Cheap Risk' - WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 1 AND 5) AND (m_score_lifetime BETWEEN 1 AND 5) - THEN '9_At Risk' - WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 2) - THEN '9_At Risk' - WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 1 AND 2) AND (m_score_lifetime = 1) - THEN '9_At Risk' + WHEN (r_score_lifetime = 1) AND (f_score_lifetime = 1) AND (m_score_lifetime = 1) + THEN '13_Cheap Lost' - WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 1 AND 5) - THEN '11_Cant Lose Them' - WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 1 AND 5) AND (m_score_lifetime BETWEEN 4 AND 5) - THEN '11_Cant Lose Them' - WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 3 AND 5) AND (m_score_lifetime BETWEEN 3 AND 5) - THEN '11_Cant Lose Them' - - WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 1 AND 3) AND (m_score_lifetime BETWEEN 1 AND 3) - THEN '12_Lost' - - WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 3) - THEN '6_Normal Customer' - WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 1 AND 3) AND (m_score_lifetime = 1) - THEN '6_Normal Customer' - - ELSE 'ERROR Please Contact DATA Team' - END AS segment_lifetime, - - - CASE - WHEN day_after_approved_or_completed_order_one_year IS NULL THEN NULL - WHEN day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[0]}} THEN 5 - WHEN (day_after_approved_or_completed_order_one_year > {{recency_list_one_year[0]}} AND day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[1]}}) THEN 4 - WHEN (day_after_approved_or_completed_order_one_year > {{recency_list_one_year[1]}} AND day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[2]}}) THEN 3 - WHEN (day_after_approved_or_completed_order_one_year > {{recency_list_one_year[2]}} AND day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[3]}}) THEN 2 - WHEN day_after_approved_or_completed_order_one_year > {{recency_list_one_year[3]}} THEN 1 - ELSE -999 - END AS r_score_one_year, - CASE - WHEN number_of_approved_or_completed_order_one_year IS NULL THEN NULL - WHEN number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[0]}} THEN 1 - WHEN (number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[0]}} AND number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[1]}}) THEN 2 - WHEN (number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[1]}} AND number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[2]}}) THEN 3 - WHEN (number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[2]}} AND number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[3]}}) THEN 4 - WHEN number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[3]}} THEN 5 - ELSE -999 - END AS f_score_one_year, - CASE - WHEN total_value_of_approved_or_completed_order_one_year IS NULL THEN NULL - WHEN total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[0]}} THEN 1 - WHEN (total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[0]}} AND total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[1]}}) THEN 2 - WHEN (total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[1]}} AND total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[2]}}) THEN 3 - WHEN (total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[2]}} AND total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[3]}}) THEN 4 - WHEN total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[3]}} THEN 5 - ELSE -999 - END AS m_score_one_year, - - CASE - WHEN (r_score_one_year IS NULL) AND (f_score_one_year IS NULL) AND (m_score_one_year IS NULL) - THEN '14_Not Active Between 1 year' + WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 1 AND 2) AND (m_score_lifetime BETWEEN 4 AND 5) + THEN '4_Whale' - WHEN (r_score_one_year = 5) AND (f_score_one_year = 5) AND (m_score_one_year = 5) - THEN '1_King' - - WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year = 1) AND (m_score_one_year = 1) - THEN '10_At Cheap Risk' - - WHEN (r_score_one_year = 1) AND (f_score_one_year = 1) AND (m_score_one_year = 1) - THEN '13_Cheap Lost' - - WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 1 AND 2) AND (m_score_one_year BETWEEN 4 AND 5) - THEN '4_Whale' - - WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 1 AND 2) - THEN '3_Sardine' + WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 1 AND 2) + THEN '3_Sardine' - WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 3 AND 5) AND (m_score_one_year BETWEEN 3 AND 5) - THEN '2_Loyal Customer' - - WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 2 AND 5) AND (m_score_one_year BETWEEN 2 AND 5) - THEN '5_Potention Loyal' + WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 3 AND 5) AND (m_score_lifetime BETWEEN 3 AND 5) + THEN '2_Loyal Customer' - WHEN (r_score_one_year = 5) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 2) - THEN '7_New Customer' + WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 2 AND 5) AND (m_score_lifetime BETWEEN 2 AND 5) + THEN '5_Potention Loyal' - WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 4 AND 5) - THEN '8_At High Risk' + WHEN (r_score_lifetime = 5) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 2) + THEN '7_New Customer' - WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 1 AND 5) AND (m_score_one_year BETWEEN 1 AND 5) - THEN '9_At Risk' - WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 2) - THEN '9_At Risk' - WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 1 AND 2) AND (m_score_one_year = 1) - THEN '9_At Risk' + WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 4 AND 5) + THEN '8_At High Risk' - WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 1 AND 5) - THEN '11_Cant Lose Them' - WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 1 AND 5) AND (m_score_one_year BETWEEN 4 AND 5) - THEN '11_Cant Lose Them' - WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 3 AND 5) AND (m_score_one_year BETWEEN 3 AND 5) - THEN '11_Cant Lose Them' - - WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 1 AND 3) AND (m_score_one_year BETWEEN 1 AND 3) - THEN '12_Lost' - - WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 3) - THEN '6_Normal Customer' - WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 1 AND 3) AND (m_score_one_year = 1) - THEN '6_Normal Customer' - - ELSE 'ERROR Please Contact DATA Team' - END AS segment_one_year, + WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 1 AND 5) AND (m_score_lifetime BETWEEN 1 AND 5) + THEN '9_At Risk' + WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 2) + THEN '9_At Risk' + WHEN (r_score_lifetime BETWEEN 2 AND 3) AND (f_score_lifetime BETWEEN 1 AND 2) AND (m_score_lifetime = 1) + THEN '9_At Risk' - '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime - - - FROM + WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 4 AND 5) AND (m_score_lifetime BETWEEN 1 AND 5) + THEN '11_Cant Lose Them' + WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 1 AND 5) AND (m_score_lifetime BETWEEN 4 AND 5) + THEN '11_Cant Lose Them' + WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 3 AND 5) AND (m_score_lifetime BETWEEN 3 AND 5) + THEN '11_Cant Lose Them' + + WHEN (r_score_lifetime = 1) AND (f_score_lifetime BETWEEN 1 AND 3) AND (m_score_lifetime BETWEEN 1 AND 3) + THEN '12_Lost' + + WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime = 1) AND (m_score_lifetime BETWEEN 1 AND 3) + THEN '6_Normal Customer' + WHEN (r_score_lifetime BETWEEN 4 AND 5) AND (f_score_lifetime BETWEEN 1 AND 3) AND (m_score_lifetime = 1) + THEN '6_Normal Customer' + + ELSE 'ERROR Please Contact DATA Team' + END AS segment_lifetime, + + + CASE + WHEN day_after_approved_or_completed_order_one_year IS NULL THEN NULL + WHEN day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[0]}} THEN 5 + WHEN (day_after_approved_or_completed_order_one_year > {{recency_list_one_year[0]}} AND day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[1]}}) THEN 4 + WHEN (day_after_approved_or_completed_order_one_year > {{recency_list_one_year[1]}} AND day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[2]}}) THEN 3 + WHEN (day_after_approved_or_completed_order_one_year > {{recency_list_one_year[2]}} AND day_after_approved_or_completed_order_one_year <= {{recency_list_one_year[3]}}) THEN 2 + WHEN day_after_approved_or_completed_order_one_year > {{recency_list_one_year[3]}} THEN 1 + ELSE -999 + END AS r_score_one_year, + CASE + WHEN number_of_approved_or_completed_order_one_year IS NULL THEN NULL + WHEN number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[0]}} THEN 1 + WHEN (number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[0]}} AND number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[1]}}) THEN 2 + WHEN (number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[1]}} AND number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[2]}}) THEN 3 + WHEN (number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[2]}} AND number_of_approved_or_completed_order_one_year <= {{frequency_list_one_year[3]}}) THEN 4 + WHEN number_of_approved_or_completed_order_one_year > {{frequency_list_one_year[3]}} THEN 5 + ELSE -999 + END AS f_score_one_year, + CASE + WHEN total_value_of_approved_or_completed_order_one_year IS NULL THEN NULL + WHEN total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[0]}} THEN 1 + WHEN (total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[0]}} AND total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[1]}}) THEN 2 + WHEN (total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[1]}} AND total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[2]}}) THEN 3 + WHEN (total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[2]}} AND total_value_of_approved_or_completed_order_one_year <= {{monetary_list_one_year[3]}}) THEN 4 + WHEN total_value_of_approved_or_completed_order_one_year > {{monetary_list_one_year[3]}} THEN 5 + ELSE -999 + END AS m_score_one_year, + + CASE + WHEN (r_score_one_year IS NULL) AND (f_score_one_year IS NULL) AND (m_score_one_year IS NULL) + THEN '14_Not Active Between 1 year' + + WHEN (r_score_one_year = 5) AND (f_score_one_year = 5) AND (m_score_one_year = 5) + THEN '1_King' + + WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year = 1) AND (m_score_one_year = 1) + THEN '10_At Cheap Risk' + + WHEN (r_score_one_year = 1) AND (f_score_one_year = 1) AND (m_score_one_year = 1) + THEN '13_Cheap Lost' + + WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 1 AND 2) AND (m_score_one_year BETWEEN 4 AND 5) + THEN '4_Whale' + + WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 1 AND 2) + THEN '3_Sardine' + + WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 3 AND 5) AND (m_score_one_year BETWEEN 3 AND 5) + THEN '2_Loyal Customer' + + WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 2 AND 5) AND (m_score_one_year BETWEEN 2 AND 5) + THEN '5_Potention Loyal' + + WHEN (r_score_one_year = 5) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 2) + THEN '7_New Customer' + + WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 4 AND 5) + THEN '8_At High Risk' + + WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 1 AND 5) AND (m_score_one_year BETWEEN 1 AND 5) + THEN '9_At Risk' + WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 2) + THEN '9_At Risk' + WHEN (r_score_one_year BETWEEN 2 AND 3) AND (f_score_one_year BETWEEN 1 AND 2) AND (m_score_one_year = 1) + THEN '9_At Risk' + + WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 4 AND 5) AND (m_score_one_year BETWEEN 1 AND 5) + THEN '11_Cant Lose Them' + WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 1 AND 5) AND (m_score_one_year BETWEEN 4 AND 5) + THEN '11_Cant Lose Them' + WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 3 AND 5) AND (m_score_one_year BETWEEN 3 AND 5) + THEN '11_Cant Lose Them' + + WHEN (r_score_one_year = 1) AND (f_score_one_year BETWEEN 1 AND 3) AND (m_score_one_year BETWEEN 1 AND 3) + THEN '12_Lost' + + WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year = 1) AND (m_score_one_year BETWEEN 1 AND 3) + THEN '6_Normal Customer' + WHEN (r_score_one_year BETWEEN 4 AND 5) AND (f_score_one_year BETWEEN 1 AND 3) AND (m_score_one_year = 1) + THEN '6_Normal Customer' + + ELSE 'ERROR Please Contact DATA Team' + END AS segment_one_year, + + '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime + + FROM company_rfm - ), -- FINAL @@ -285,6 +281,5 @@ final__rep_exchange__rfm AS ( FROM calculate_rfm ) -SELECT * FROM final__rep_exchange__rfm - +SELECT * FROM final__rep_exchange__rfm \ No newline at end of file diff --git a/models/marts/reporting/rep_exchange__sales_lead_conversions.sql b/models/marts/reporting/rep_exchange__sales_lead_conversions.sql index b189f0a..e5bf4e5 100644 --- a/models/marts/reporting/rep_exchange__sales_lead_conversions.sql +++ b/models/marts/reporting/rep_exchange__sales_lead_conversions.sql @@ -46,10 +46,10 @@ join_booking_transaction AS ( bookings.booking_approved_datetime, bookings.booking_completed_datetime, - transactions.transaction_order_id, - transactions.transaction_type, - transactions.payment_method, - transactions.total_value_rm, + transactions.order_id AS transaction_order_id, + transactions.order_transaction_type, + transactions.order_payment_method, + transactions.total_order_value_rm AS total_value_rm, transactions.order_status AS transaction_order_status, transactions.order_created_datetime AS transaction_created_datetime, transactions.order_approved_datetime AS transaction_approved_datetime, diff --git a/models/marts/warehouse/_warehouse_models.yml b/models/marts/warehouse/_warehouse_models.yml index fdb915d..750d0d8 100644 --- a/models/marts/warehouse/_warehouse_models.yml +++ b/models/marts/warehouse/_warehouse_models.yml @@ -40,7 +40,7 @@ models: - name: fct_exchange__transaction_orders description: exchange transaction_orders columns: - - name: transaction_order_id + - name: order_id description: Primary key for 'fct_exchange__transaction_orders' tests: - unique diff --git a/models/marts/warehouse/fct_exchange__transaction_orders.sql b/models/marts/warehouse/fct_exchange__transaction_orders.sql index a330699..9fa1162 100644 --- a/models/marts/warehouse/fct_exchange__transaction_orders.sql +++ b/models/marts/warehouse/fct_exchange__transaction_orders.sql @@ -1,42 +1,225 @@ --- IMPORTS +-- VARIABLES {% set order_status = dbt_utils.get_column_values( table=ref('stg_exchange__transaction_order_logs'), - column='status') %} + column='status') +%} +{% set booking_status = dbt_utils.get_column_values( + table=ref('stg_exchange__booking_logs'), + column='status') +%} + +-- IMPORTS WITH transaction_orders AS ( - SELECT * FROM {{ ref('int_exchange__transaction_orders_get_user_ids') }} + SELECT * FROM {{ ref('int_exchange__transaction_orders_get_user_ids') }} ), -transaction_order_logs AS ( +transaction_order_logs AS ( SELECT * FROM {{ ref('stg_exchange__transaction_order_logs') }} ), --- LOGICS +transaction_costs AS ( + SELECT * FROM {{ ref('stg_exchange__transaction_costs') }} +), + +transaction_cost_logs AS ( + SELECT * FROM {{ ref('stg_exchange__transaction_cost_logs') }} +), + +bookings AS ( + SELECT * FROM {{ ref('int_exchange__bookings_get_estimate_booking_values') }} +), + +booking_logs AS ( + SELECT * FROM {{ ref('stg_exchange__booking_logs') }} +), + +-- LOGIC +order_logs_join_bookings AS ( + SELECT + transaction_order_logs.*, + bookings.service_type, + ROW_NUMBER() OVER (PARTITION BY transaction_order_id + ORDER BY transaction_order_logs.updated_datetime DESC, + transaction_order_logs.transaction_order_id DESC, + transaction_order_logs.transaction_order_log_id DESC) AS rank_index + + FROM transaction_order_logs + + LEFT JOIN bookings + ON (transaction_order_logs.booking_id = bookings.booking_id) +), + transaction_order_order_status_datetime AS ( SELECT transaction_order_id, - MIN(created_datetime) AS order_created_datetime, + payment_method, + service_type, + MAX(rank_index) AS status_count, + MAX(CASE WHEN rank_index = 1 THEN status END) AS final_order_status, + MIN(created_datetime) AS order_created_datetime, {%- for status in order_status %} - MAX(CASE WHEN status = '{{status}}' THEN updated_datetime END) AS order_{{status.lower()}}_datetime {%- if not loop.last %},{% endif -%} - {% endfor %} + {% if status != 'APPROVED' %} + MAX(CASE WHEN status = '{{status}}' THEN updated_datetime END) AS order_{{status.lower()}}_datetime + {% else %} + MIN(CASE WHEN status = '{{status}}' THEN updated_datetime END) AS order_{{status.lower()}}_datetime + {% endif %} + {%- if not loop.last %},{% endif -%} + {% endfor %} - FROM transaction_order_logs + FROM order_logs_join_bookings GROUP BY - transaction_order_id + transaction_order_id, + payment_method, + service_type ), +transaction_order_datetime_imputation AS ( + + SELECT + transaction_order_id, + payment_method, + service_type, + final_order_status, + + order_created_datetime AS new_order_created_datetime, + order_rejected_datetime AS new_order_rejected_datetime, + order_suspended_datetime AS new_order_suspended_datetime, + order_expired_datetime AS new_order_expired_datetime, + + -- imputation for ORDER_PENDING_SUBMISSION DATETIME + COALESCE(order_pending_submission_datetime, order_created_datetime) AS new_order_pending_submission_datetime, + + /* + Data manipulation for ORDER_PENDING_VERIFICATION_DATETIME + - To improve data consistency + */ + CASE + -- When final order status is not pending verification, return null + WHEN final_order_status NOT IN ('PENDING_VERIFICATION', 'APPROVED', 'COMPLETED') THEN null + ELSE COALESCE(order_pending_verification_datetime, new_order_pending_submission_datetime) + END AS new_order_pending_verification_datetime, + + + /* + Data manipulation for ORDER_APPROVED_DATETIME + - To improve data consistency + - All orders from year 2023 has order_approved datetime + */ + CASE + -- When final order status is not approved, return null + WHEN order_created_datetime >= '2023-01-01'AND final_order_status NOT IN ('APPROVED', 'COMPLETED') THEN null + ELSE COALESCE(order_approved_datetime, new_order_pending_verification_datetime) + END AS new_order_approved_datetime, + + + /* + Missing value imputation for order_completed_datetime + - Missing value caused by inconsistency and backlog from exchange system + - Imputed dataset used for estimation of on-time delivery + */ + CASE + -- When final order status is not completed, return null, imputation will be done in next code block + WHEN order_created_datetime >= '2023-01-01'AND final_order_status NOT IN ('COMPLETED') THEN null + WHEN order_created_datetime < '2023-01-01' THEN order_completed_datetime + + /* + Imputation for order_approved_datetime for 1688 payment + - If payment_method is 'cash', add median of 53 minute to order_approved datetime + - If payment_method is 'wallet', add median of 569 minute to order_approved datetime + - If payment_method is 'cheque', reuse order_completed datetime, no orders using cheque in 1688 payment + - If payment_method is 'payment_gateway', add median of 433 minute to order_approved datetime + */ + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1688 PAYMENT' AND payment_method = 'CASH' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 53, new_order_approved_datetime)) + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1688 PAYMENT' AND payment_method = 'WALLET' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 569, new_order_approved_datetime)) + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1688 PAYMENT' AND payment_method = 'CHEQUE' + THEN order_completed_datetime + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1688 PAYMENT' AND payment_method = 'PAYMENT_GATEWAY' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 433, new_order_approved_datetime)) + + /* + Imputation for order_approved_datetime for 1 day transfer + - If payment_method is 'cash', add median of 59 minute to order_approved datetime + - If payment_method is 'wallet', add median of 206 minute to order_approved datetime + - If payment_method is 'cheque', reuse order_completed datetime, all orders have completed datetime + - If payment_method is 'payment_gateway', add median of 214.5 minute to order_approved datetime + */ + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1 DAY TRANSFER' AND payment_method = 'CASH' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 59, new_order_approved_datetime)) + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1 DAY TRANSFER' AND payment_method = 'WALLET' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 206, new_order_approved_datetime)) + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1 DAY TRANSFER' AND payment_method = 'CHEQUE' + THEN order_completed_datetime + WHEN order_created_datetime >= '2023-01-01' AND service_type = '1 DAY TRANSFER' AND payment_method = 'PAYMENT_GATEWAY' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 214.5, new_order_approved_datetime)) + + /* + Imputation for order_approved_datetime for 3 days transfer + - If payment_method is 'cash', add median of 2702 minute to order_approved datetime + - If payment_method is 'wallet', add median of 4502.92 minute to order_approved datetime + - If payment_method is 'cheque', reuse order_completed datetime, all orders have completed datetime + - If payment_method is 'payment_gateway', add median of 5253 minute to order_approved datetime + */ + WHEN order_created_datetime >= '2023-01-01' AND service_type = '3 DAYS TRANSFER' AND payment_method = 'CASH' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 2702, new_order_approved_datetime)) + WHEN order_created_datetime >= '2023-01-01' AND service_type = '3 DAYS TRANSFER' AND payment_method = 'WALLET' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 4502.92, new_order_approved_datetime)) + WHEN order_created_datetime >= '2023-01-01' AND service_type = '3 DAYS TRANSFER' AND payment_method = 'CHEQUE' + THEN order_completed_datetime + WHEN order_created_datetime >= '2023-01-01' AND service_type = '3 DAYS TRANSFER' AND payment_method = 'PAYMENT_GATEWAY' + THEN COALESCE(order_completed_datetime, DATEADD(minute, 5253, new_order_approved_datetime)) + + END AS new_order_completed_datetime + + FROM transaction_order_order_status_datetime +), + +transaction_cost_status_datetime AS ( + + SELECT + transaction_cost_id, + MIN(created_datetime) AS cost_created_datetime, + + {%- for status in order_status %} + MAX(CASE WHEN status = '{{status}}' THEN updated_datetime END) AS cost_{{status.lower()}}_datetime {%- if not loop.last %},{% endif -%} + {% endfor %} + + FROM transaction_cost_logs + + GROUP BY + transaction_cost_id +), + +booking_status_datetime AS ( + + SELECT + booking_id, + MIN(created_datetime) AS booking_created_datetime, + + {%- for status in booking_status %} + MAX(CASE WHEN status = '{{status}}' THEN updated_datetime END) AS booking_{{status.lower()}}_datetime {%- if not loop.last %},{% endif -%} + {% endfor %} + + FROM booking_logs + + GROUP BY + booking_id +), transaction_orders_lists AS ( + SELECT transaction_orders.transaction_order_id, transaction_orders.booking_id, transaction_orders.bank_id, transaction_orders.company_id, transaction_orders.user_id, - transaction_orders.status AS order_status, + transaction_orders.status, transaction_orders.transaction_type, transaction_orders.payment_method, transaction_orders.base_currency_id, @@ -44,37 +227,36 @@ transaction_orders_lists AS ( transaction_orders.base_to_quote_currency_exchange_rate, transaction_orders.payment_reference, transaction_orders.bill_number, - transaction_orders.expired_datetime AS order_expected_expired_datetime, - transaction_orders.base_value, transaction_orders.quote_value, -- use for future if base currency id other from '1' IFF(transaction_orders.base_currency_id = '1', transaction_orders.base_value, - -9999999999) AS value_rm, + -9999999999) AS value_rm, - transaction_orders.base_tax AS base_tax, + transaction_orders.base_tax AS base_tax, -- use for future if base currency id other from '1' IFF(transaction_orders.base_currency_id = '1', transaction_orders.base_tax, - -9999999999) AS tax_rm, + -9999999999) AS tax_rm, transaction_orders.base_service_charge, -- use for future if base currency id other from '1' IFF(transaction_orders.base_currency_id = '1', transaction_orders.base_service_charge, - -9999999999) AS service_charge_rm, + -9999999999) AS service_charge_rm, - (value_rm + service_charge_rm + tax_rm) AS total_value_rm, + (value_rm + service_charge_rm + tax_rm) AS total_value_rm, - transaction_orders.deleted_datetime AS order_deleted_datetime, - transaction_orders.updated_datetime AS order_updated_datetime, + transaction_orders.expired_datetime AS order_expected_expired_datetime, + transaction_orders.deleted_datetime AS order_deleted_datetime, + transaction_orders.updated_datetime AS order_updated_datetime, {% for column_name in ["company", "user"] %} CASE - WHEN ROW_NUMBER() OVER (PARTITION BY transaction_orders.{{column_name}}_id ORDER BY transaction_orders.created_datetime) = 1 THEN 1 + WHEN ROW_NUMBER() OVER (PARTITION BY transaction_orders.{{column_name}}_id ORDER BY transaction_orders.created_datetime, transaction_orders.transaction_order_id) = 1 THEN 1 ELSE 0 - END AS is_first_time_{{column_name}}, + END AS is_first_time_{{column_name}}, CASE WHEN transaction_orders.status = 'COMPLETED' @@ -84,64 +266,280 @@ transaction_orders_lists AS ( = transaction_orders.created_datetime THEN 1 ELSE 0 - END AS is_first_time_{{column_name}}_completed, + END AS is_first_time_{{column_name}}_completed, {% endfor %} - transaction_order_order_status_datetime.order_created_datetime, + transaction_order_datetime_imputation.new_order_created_datetime AS order_created_datetime, + -- transaction_order_datetime_imputation.order_expired_datetime, {%- for status in order_status %} - transaction_order_order_status_datetime.order_{{status.lower()}}_datetime, + transaction_order_datetime_imputation.new_order_{{status.lower()}}_datetime AS order_{{status.lower()}}_datetime, {% endfor %} - - '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime + + LEAD(transaction_order_datetime_imputation.new_order_created_datetime) OVER + (PARTITION BY company_id ORDER BY transaction_order_datetime_imputation.new_order_created_datetime, + transaction_order_datetime_imputation.transaction_order_id) AS next_order_created_datetime FROM transaction_orders - LEFT JOIN transaction_order_order_status_datetime - ON (transaction_orders.transaction_order_id = transaction_order_order_status_datetime.transaction_order_id) + LEFT JOIN transaction_order_datetime_imputation + ON (transaction_orders.transaction_order_id = transaction_order_datetime_imputation.transaction_order_id) +), + +transaction_costs_lists AS ( + + SELECT + transaction_costs.transaction_cost_id, + transaction_costs.transaction_order_id, + transaction_costs.supplier_company_id, + transaction_costs.bank_id, + transaction_costs.base_currency_id, + transaction_costs.quote_currency_id, + transaction_costs.transaction_type, + transaction_costs.payment_method, + transaction_costs.status, + transaction_costs.payment_reference, + transaction_costs.bill_number, + transaction_costs.base_value, + transaction_costs.quote_value, + transaction_costs.base_to_quote_currency_exchange_rate, + transaction_costs.base_tax, + transaction_costs.base_service_charge, + + -- use for future if base currency id other from '1' + IFF(transaction_costs.base_currency_id = '1', + transaction_costs.base_value, + -9999999999) AS value_rm, + + -- use for future if base currency id other from '1' + IFF(transaction_costs.base_currency_id = '1', + transaction_costs.base_tax, + -9999999999) AS tax_rm, + + -- use for future if base currency id other from '1' + IFF(transaction_costs.base_currency_id = '1', + transaction_costs.base_service_charge, + -9999999999) AS service_charge_rm, + + (value_rm + service_charge_rm + tax_rm) AS total_value_rm, + + transaction_costs.expired_datetime, + transaction_costs.deleted_datetime, + transaction_costs.created_datetime, + transaction_costs.updated_datetime, + + {%- for status in order_status %} + transaction_cost_status_datetime.cost_{{status.lower()}}_datetime, + {% endfor %} + transaction_cost_status_datetime.cost_created_datetime + + FROM transaction_costs + + LEFT JOIN transaction_cost_status_datetime + ON (transaction_costs.transaction_cost_id = transaction_cost_status_datetime.transaction_cost_id) + +), + +bookings_lists AS ( + SELECT + bookings.*, + + {% for column_name in ["company", "user"] %} + CASE + WHEN ROW_NUMBER() OVER (PARTITION BY bookings.{{column_name}}_id ORDER BY bookings.created_datetime, bookings.booking_id) = 1 THEN 1 + ELSE 0 + END AS is_first_time_{{column_name}}, + + CASE + WHEN bookings.status = 'COMPLETED' + AND + MIN(IFF(bookings.status = 'COMPLETED', bookings.created_datetime, NULL)) + OVER (PARTITION BY bookings.{{column_name}}_id) + = bookings.created_datetime + THEN 1 + ELSE 0 + END AS is_first_time_{{column_name}}_completed, + {% endfor %} + + booking_status_datetime.booking_created_datetime, + {%- for status in booking_status %} + booking_status_datetime.booking_{{status.lower()}}_datetime {%- if not loop.last %},{% endif -%} + {% endfor %} + + FROM bookings + + LEFT JOIN booking_status_datetime + ON (bookings.booking_id = booking_status_datetime.booking_id) +), + +bookings_orders_costs_join AS ( + + SELECT + bookings_lists.booking_id, + bookings_lists.booking_marking_id, + bookings_lists.user_id, + bookings_lists.fix_currency_id, + bookings_lists.quote_currency_id, + bookings_lists.base_currency_id, + bookings_lists.service_type, + bookings_lists.status AS booking_status, + bookings_lists.is_first_time_company AS is_first_time_booking_company, + bookings_lists.is_first_time_company_completed AS is_first_time_booking_company_completed, + bookings_lists.is_first_time_user AS is_first_time_booking_user, + bookings_lists.is_first_time_user_completed AS is_first_time_booking_user_completed, + bookings_lists.estimate_base_to_quote_currency_exchange_rate AS estimate_booking_base_to_quote_currency_exchange_rate, + bookings_lists.estimate_quote_value AS estimate_booking_quote_value, + bookings_lists.estimate_base_value AS estimate_booking_base_value, + bookings_lists.estimate_value_rm AS estimate_booking_value_rm, + bookings_lists.booking_created_datetime, + bookings_lists.booking_approved_datetime, + bookings_lists.booking_completed_datetime, + bookings_lists.booking_suspended_datetime, + + transaction_orders_lists.transaction_order_id AS order_id, + transaction_orders_lists.company_id, + transaction_orders_lists.bank_id, + transaction_orders_lists.transaction_type AS order_transaction_type, + transaction_orders_lists.payment_method AS order_payment_method, + transaction_orders_lists.status AS order_status, + transaction_orders_lists.payment_reference AS order_payment_reference, + transaction_orders_lists.bill_number AS order_bill_number, + transaction_orders_lists.is_first_time_company AS is_first_time_order_company, + transaction_orders_lists.is_first_time_company_completed AS is_first_time_order_company_completed, + transaction_orders_lists.is_first_time_user AS is_first_time_order_user, + transaction_orders_lists.is_first_time_user_completed AS is_first_time_order_user_completed, + transaction_orders_lists.base_to_quote_currency_exchange_rate AS order_base_to_quote_currency_exchange_rate , + transaction_orders_lists.base_value AS order_base_value , + transaction_orders_lists.base_service_charge AS order_base_service_charge , + transaction_orders_lists.base_tax AS order_base_tax , + transaction_orders_lists.quote_value AS order_quote_value , + transaction_orders_lists.value_rm AS order_value_rm , + transaction_orders_lists.service_charge_rm AS order_service_charge_rm , + transaction_orders_lists.tax_rm AS order_tax_rm , + transaction_orders_lists.total_value_rm AS total_order_value_rm, + transaction_orders_lists.order_created_datetime, + transaction_orders_lists.order_deleted_datetime, + transaction_orders_lists.order_pending_submission_datetime, + transaction_orders_lists.order_pending_verification_datetime, + transaction_orders_lists.order_approved_datetime, + transaction_orders_lists.order_completed_datetime, + transaction_orders_lists.order_updated_datetime, + transaction_orders_lists.order_rejected_datetime, + transaction_orders_lists.order_suspended_datetime, + transaction_orders_lists.order_expired_datetime, + transaction_orders_lists.next_order_created_datetime, + transaction_orders_lists.order_expected_expired_datetime, + + transaction_costs_lists.transaction_cost_id AS cost_id, + transaction_costs_lists.bank_id AS currency_vendor_bank_id, + transaction_costs_lists.supplier_company_id AS supplier_company_id, + transaction_costs_lists.transaction_type AS cost_transaction_type, + transaction_costs_lists.payment_method AS cost_payment_method, + transaction_costs_lists.status AS cost_status, + transaction_costs_lists.payment_reference AS cost_payment_reference, + transaction_costs_lists.bill_number AS cost_bill_number, + transaction_costs_lists.base_value AS cost_base_value, + transaction_costs_lists.quote_value AS cost_quote_value, + transaction_costs_lists.base_to_quote_currency_exchange_rate AS cost_base_to_quote_currency_exchange_rate, + transaction_costs_lists.base_tax AS cost_base_tax, + transaction_costs_lists.base_service_charge AS cost_base_service_charge, + transaction_costs_lists.value_rm AS cost_value_rm, + transaction_costs_lists.tax_rm AS cost_tax_rm, + transaction_costs_lists.service_charge_rm AS cost_service_charge_rm, + transaction_costs_lists.total_value_rm AS total_cost_value_rm, + transaction_costs_lists.cost_created_datetime, + transaction_costs_lists.cost_pending_submission_datetime, + transaction_costs_lists.cost_pending_verification_datetime, + transaction_costs_lists.cost_approved_datetime, + transaction_costs_lists.cost_completed_datetime, + transaction_costs_lists.cost_rejected_datetime, + + '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime + + FROM transaction_orders_lists + + LEFT JOIN transaction_costs_lists + ON transaction_orders_lists.transaction_order_id = transaction_costs_lists.transaction_order_id + + LEFT JOIN bookings_lists + ON transaction_orders_lists.booking_id = bookings_lists.booking_id + ), -- FINAL -final__fct_exchange__transaction_orders AS ( - SELECT +final_fct_exchange__new_orders AS ( + + SELECT -- ids - transaction_order_id, + order_id, booking_id, + booking_marking_id, company_id, user_id, bank_id, - base_currency_id, + cost_id, + supplier_company_id, + currency_vendor_bank_id, + fix_currency_id, quote_currency_id, + base_currency_id, -- dimensions - transaction_type, - payment_method, + service_type, + booking_status, + is_first_time_booking_company, + is_first_time_booking_company_completed, + is_first_time_booking_user, + is_first_time_booking_user_completed, + is_first_time_order_company, + is_first_time_order_company_completed, + is_first_time_order_user, + is_first_time_order_user_completed, + order_transaction_type, + order_payment_method, order_status, - payment_reference, - bill_number, - is_first_time_company, - is_first_time_company_completed, - is_first_time_user, - is_first_time_user_completed, - + order_payment_reference, + order_bill_number, + cost_transaction_type, + cost_payment_method, + cost_status, + cost_payment_reference, + cost_bill_number, + -- measures - base_to_quote_currency_exchange_rate, - base_value, - base_service_charge, - base_tax, - - quote_value, - - value_rm, - service_charge_rm, - tax_rm, - total_value_rm, + estimate_booking_base_to_quote_currency_exchange_rate, + estimate_booking_quote_value, + estimate_booking_base_value, + estimate_booking_value_rm, + order_base_to_quote_currency_exchange_rate, + order_base_value, + order_base_service_charge, + order_base_tax, + order_quote_value, + order_value_rm, + order_service_charge_rm, + order_tax_rm, + total_order_value_rm, + cost_base_value, + cost_quote_value, + cost_base_to_quote_currency_exchange_rate, + cost_base_tax, + cost_base_service_charge, + cost_value_rm, + cost_tax_rm, + cost_service_charge_rm, + total_cost_value_rm, -- date/times - order_expected_expired_datetime, + booking_created_datetime, + booking_approved_datetime, + booking_completed_datetime, + booking_suspended_datetime, + order_deleted_datetime, order_updated_datetime, order_created_datetime, + order_expected_expired_datetime, order_pending_submission_datetime, order_pending_verification_datetime, order_approved_datetime, @@ -149,11 +547,19 @@ final__fct_exchange__transaction_orders AS ( order_rejected_datetime, order_suspended_datetime, order_expired_datetime, + + next_order_created_datetime, + cost_created_datetime, + cost_pending_submission_datetime, + cost_pending_verification_datetime, + cost_approved_datetime, + cost_completed_datetime, + cost_rejected_datetime, -- metadata - _dbt_ran_datetime - - FROM transaction_orders_lists + _dbt_ran_datetime + + FROM bookings_orders_costs_join ) -SELECT * FROM final__fct_exchange__transaction_orders \ No newline at end of file +SELECT * FROM final_fct_exchange__new_orders \ No newline at end of file