diff --git a/src/app/(main)/reports/revenue/RevenueParameters.tsx b/src/app/(main)/reports/revenue/RevenueParameters.tsx index f231ce06..8e344e4d 100644 --- a/src/app/(main)/reports/revenue/RevenueParameters.tsx +++ b/src/app/(main)/reports/revenue/RevenueParameters.tsx @@ -11,7 +11,11 @@ export function RevenueParameters() { const { id, parameters } = report || {}; const { websiteId, dateRange } = parameters || {}; const queryEnabled = websiteId && dateRange; - const { data: values = [] } = useRevenueValues(websiteId, dateRange.startDate, dateRange.endDate); + const { data: values = [] } = useRevenueValues( + websiteId, + dateRange?.startDate, + dateRange?.endDate, + ); const handleSubmit = (data: any, e: any) => { e.stopPropagation(); diff --git a/src/app/(main)/reports/revenue/RevenueTable.tsx b/src/app/(main)/reports/revenue/RevenueTable.tsx index f038aed9..bf7114e8 100644 --- a/src/app/(main)/reports/revenue/RevenueTable.tsx +++ b/src/app/(main)/reports/revenue/RevenueTable.tsx @@ -29,7 +29,7 @@ export function RevenueTable() { {row => row.count} - {row => row.uniqueCount} + {row => row.unique_count} ); diff --git a/src/app/(main)/reports/revenue/RevenueView.tsx b/src/app/(main)/reports/revenue/RevenueView.tsx index 89247b6a..cd53129a 100644 --- a/src/app/(main)/reports/revenue/RevenueView.tsx +++ b/src/app/(main)/reports/revenue/RevenueView.tsx @@ -87,7 +87,7 @@ export function RevenueView({ isLoading }: RevenueViewProps) { const metricData = useMemo(() => { if (!data) return []; - const { sum, avg, count, uniqueCount } = data.total; + const { sum, avg, count, unique_count } = data.total; return [ { @@ -106,7 +106,7 @@ export function RevenueView({ isLoading }: RevenueViewProps) { formatValue: formatLongNumber, }, { - value: uniqueCount, + value: unique_count, label: formatMessage(labels.uniqueCustomers), formatValue: formatLongNumber, }, @@ -121,29 +121,31 @@ export function RevenueView({ isLoading }: RevenueViewProps) { return ; })} - {data && ( - - ({ - x: name, - y: value, - z: (value / data?.total.sum) * 100, - }))} - renderLabel={renderCountryName} + <> + - - + + ({ + x: name, + y: Number(value), + z: (value / data?.total.sum) * 100, + }))} + renderLabel={renderCountryName} + /> + + + )} {showTable && } diff --git a/src/queries/analytics/reports/getRevenue.ts b/src/queries/analytics/reports/getRevenue.ts index 9d9a4a14..5fb419c0 100644 --- a/src/queries/analytics/reports/getRevenue.ts +++ b/src/queries/analytics/reports/getRevenue.ts @@ -1,5 +1,5 @@ import clickhouse from 'lib/clickhouse'; -import { CLICKHOUSE, PRISMA, runQuery } from 'lib/db'; +import { CLICKHOUSE, getDatabaseType, POSTGRESQL, PRISMA, runQuery } from 'lib/db'; import prisma from 'lib/prisma'; export async function getRevenue( @@ -27,50 +27,118 @@ async function relationalQuery( endDate: Date; unit: string; timezone: string; + currency: string; }, ): Promise<{ - chart: { time: string; sum: number; avg: number; count: number; uniqueCount: number }[]; - total: { sum: number; avg: number; count: number; uniqueCount: number }; + chart: { x: string; t: string; y: number }[]; + country: { name: string; value: number }[]; + total: { sum: number; avg: number; count: number; unique_count: number }; + table: { + currency: string; + sum: number; + avg: number; + count: number; + unique_count: number; + }[]; }> { - const { startDate, endDate, timezone = 'UTC', unit = 'day' } = criteria; + const { startDate, endDate, timezone = 'UTC', unit = 'day', currency } = criteria; const { getDateSQL, rawQuery } = prisma; + const db = getDatabaseType(); + const like = db === POSTGRESQL ? 'ilike' : 'like'; const chartRes = await rawQuery( ` select - ${getDateSQL('website_event.created_at', unit, timezone)} time, - sum(case when data_key = {{revenueProperty}} then number_value else 0 end) sum, - avg(case when data_key = {{revenueProperty}} then number_value else 0 end) avg, - count(case when data_key = {{revenueProperty}} then 1 else 0 end) count, - count(distinct {{userProperty}}) uniqueCount - from event_data - where website_event.website_id = {{websiteId::uuid}} - and website_event.created_at between {{startDate}} and {{endDate}} - and event_name = {{eventType}} - and data_key in ({{revenueProperty}} , {{userProperty}}) - group by 1 + we.event_name x, + ${getDateSQL('ed.created_at', unit, timezone)} t, + sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) y + from event_data ed + join website_event we + on we.event_id = ed.website_event_id + join (select website_event_id + from event_data + where data_key ${like} '%currency%' + and string_value = {{currency}}) currency + on currency.website_event_id = ed.website_event_id + where ed.website_id = {{websiteId::uuid}} + and ed.created_at between {{startDate}} and {{endDate}} + and ed.data_key ${like} '%revenue%' + group by x, t + order by t `, - { websiteId, startDate, endDate }, + { websiteId, startDate, endDate, unit, timezone, currency }, + ); + + const countryRes = await rawQuery( + ` + select + s.country as name, + sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) value + from event_data ed + join website_event we + on we.event_id = ed.website_event_id + join session s + on s.session_id = we.session_id + join (select website_event_id + from event_data + where data_key ${like} '%currency%' + and string_value = 'USD') currency + on currency.website_event_id = ed.website_event_id + where ed.website_id = {{websiteId::uuid}} + and ed.created_at between {{startDate}} and {{endDate}} + and ed.data_key ${like} '%revenue%' + group by s.country + `, + { websiteId, startDate, endDate, currency }, ); const totalRes = await rawQuery( ` select - sum(case when data_key = {{revenueProperty}} then number_value else 0 end) sum, - avg(case when data_key = {{revenueProperty}} then number_value else 0 end) avg, - count(case when data_key = {{revenueProperty}} then 1 else 0 end) count, - count(distinct {{userProperty}}) uniqueCount - from event_data - where website_event.website_id = {{websiteId::uuid}} - and website_event.created_at between {{startDate}} and {{endDate}} - and event_name = {{eventType}} - and data_key in ({{revenueProperty}} , {{userProperty}}) - group by 1 + sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as sum, + avg(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as avg, + count(distinct event_id) as count, + count(distinct session_id) as unique_count + from event_data ed + join website_event we + on we.event_id = ed.website_event_id + join (select website_event_id + from event_data + where data_key ${like} '%currency%' + and string_value = 'USD') currency + on currency.website_event_id = ed.website_event_id + where ed.website_id = {{websiteId::uuid}} + and ed.created_at between {{startDate}} and {{endDate}} + and ed.data_key ${like} '%revenue%' + `, + { websiteId, startDate, endDate, currency }, + ).then(result => result?.[0]); + + const tableRes = await rawQuery( + ` + select + c.currency, + sum(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as sum, + avg(coalesce(cast(number_value as decimal(10,2)), cast(string_value as decimal(10,2)))) as avg, + count(distinct ed.website_event_id) as count, + count(distinct we.session_id) as unique_count + from event_data ed + join website_event we + on we.event_id = ed.website_event_id + join (select website_event_id, string_value as currency + from event_data + where data_key ${like} '%currency%') c + on c.website_event_id = ed.website_event_id + where ed.website_id = {{websiteId::uuid}} + and ed.created_at between {{startDate}} and {{endDate}} + and ed.data_key ${like} '%revenue%' + group by c.currency + order by sum desc; `, - { websiteId, startDate, endDate }, + { websiteId, startDate, endDate, unit, timezone, currency }, ); - return { chart: chartRes, total: totalRes }; + return { chart: chartRes, country: countryRes, total: totalRes, table: tableRes }; } async function clickhouseQuery( @@ -85,13 +153,13 @@ async function clickhouseQuery( ): Promise<{ chart: { x: string; t: string; y: number }[]; country: { name: string; value: number }[]; - total: { sum: number; avg: number; count: number; uniqueCount: number }; + total: { sum: number; avg: number; count: number; unique_count: number }; table: { currency: string; sum: number; avg: number; count: number; - uniqueCount: number; + unique_count: number; }[]; }> { const { startDate, endDate, timezone = 'UTC', unit = 'day', currency } = criteria; @@ -114,7 +182,7 @@ async function clickhouseQuery( from event_data where positionCaseInsensitive(data_key, 'currency') > 0 and string_value = {currency:String}) currency - on currency.event_id = event_data.event_id + on currency.event_id = event_data.event_id where website_id = {websiteId:UUID} and created_at between {startDate:DateTime64} and {endDate:DateTime64} and positionCaseInsensitive(data_key, 'revenue') > 0 @@ -139,17 +207,16 @@ async function clickhouseQuery( from event_data where positionCaseInsensitive(data_key, 'currency') > 0 and string_value = {currency:String}) c - on c.event_id = ed.event_id + on c.event_id = ed.event_id join (select distinct website_id, session_id, country from website_event_stats_hourly where website_id = {websiteId:UUID}) s - on ed.website_id = s.website_id + on ed.website_id = s.website_id and ed.session_id = s.session_id where ed.website_id = {websiteId:UUID} and ed.created_at between {startDate:DateTime64} and {endDate:DateTime64} and positionCaseInsensitive(ed.data_key, 'revenue') > 0 group by s.country - `, { websiteId, startDate, endDate, currency }, ); @@ -158,23 +225,23 @@ async function clickhouseQuery( sum: number; avg: number; count: number; - uniqueCount: number; + unique_count: number; }>( ` select sum(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as sum, avg(coalesce(toDecimal64(number_value, 2), toDecimal64(string_value, 2))) as avg, uniqExact(event_id) as count, - uniqExact(session_id) as uniqueCount + uniqExact(session_id) as unique_count from event_data join (select event_id from event_data where positionCaseInsensitive(data_key, 'currency') > 0 and string_value = {currency:String}) currency - on currency.event_id = event_data.event_id - where website_id = {websiteId:UUID} - and created_at between {startDate:DateTime64} and {endDate:DateTime64} - and positionCaseInsensitive(data_key, 'revenue') > 0 + on currency.event_id = event_data.event_id + where website_id = {websiteId:UUID} + and created_at between {startDate:DateTime64} and {endDate:DateTime64} + and positionCaseInsensitive(data_key, 'revenue') > 0 `, { websiteId, startDate, endDate, currency }, ).then(result => result?.[0]); @@ -185,7 +252,7 @@ async function clickhouseQuery( sum: number; avg: number; count: number; - uniqueCount: number; + unique_count: number; }[] >( ` @@ -194,12 +261,12 @@ async function clickhouseQuery( sum(coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2))) as sum, avg(coalesce(toDecimal64(ed.number_value, 2), toDecimal64(ed.string_value, 2))) as avg, uniqExact(ed.event_id) as count, - uniqExact(ed.session_id) as uniqueCount + uniqExact(ed.session_id) as unique_count from event_data ed join (select event_id, string_value as currency from event_data where positionCaseInsensitive(data_key, 'currency') > 0) c - ON c.event_id = ed.event_id + on c.event_id = ed.event_id where website_id = {websiteId:UUID} and created_at between {startDate:DateTime64} and {endDate:DateTime64} and positionCaseInsensitive(data_key, 'revenue') > 0 diff --git a/src/queries/analytics/reports/getRevenueValues.ts b/src/queries/analytics/reports/getRevenueValues.ts index e20672b4..4dcc4a22 100644 --- a/src/queries/analytics/reports/getRevenueValues.ts +++ b/src/queries/analytics/reports/getRevenueValues.ts @@ -34,8 +34,8 @@ async function relationalQuery( ` select distinct string_value as currency from event_data - where website_id = {websiteId:UUID} - and created_at between {startDate:DateTime64} and {endDate:DateTime64} + where website_id = {{websiteId::uuid}} + and created_at between {{startDate}} and {{endDate}} and data_key ${like} '%currency%' order by currency `,