Add revenue metrics in StatsController instead of Stats.Breakdown (#3028)

This commit makes total_revenue and average_revenue first-class metrics
instead of adding them magically in `Plausible.Stats.Breakdown`. To
keep the same behavior, revenue metrics are added in StatsController.

Related: https://github.com/plausible/analytics/pull/2957#pullrequestreview-1475017620
This commit is contained in:
Vini Brasil 2023-06-14 09:32:08 +01:00 committed by GitHub
parent a356009af8
commit 2c4cea6dce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 22 deletions

View File

@ -34,6 +34,7 @@ defmodule Plausible.Site do
many_to_many :members, User, join_through: Plausible.Site.Membership
has_many :memberships, Plausible.Site.Membership
has_many :invitations, Plausible.Auth.Invitation
has_many :goals, Plausible.Goal, preload_order: [desc: :id]
has_many :revenue_goals, Plausible.Goal, where: [currency: {:not, nil}]
has_one :google_auth, GoogleAuth
has_one :weekly_report, Plausible.Site.WeeklyReport

View File

@ -3,7 +3,7 @@ defmodule Plausible.Stats.Breakdown do
import Plausible.Stats.{Base, Imported, Util}
require OpenTelemetry.Tracer, as: Tracer
alias Plausible.Stats.Query
alias Plausible.Goals
@no_ref "Direct / None"
@not_set "(not set)"
@ -12,25 +12,15 @@ defmodule Plausible.Stats.Breakdown do
@event_props Plausible.Stats.Props.event_props()
def breakdown(site, query, "event:goal" = property, metrics, pagination) do
{event_goals, pageview_goals} =
site
|> Goals.for_site()
|> Enum.split_with(fn goal -> goal.event_name end)
site = Plausible.Repo.preload(site, :goals)
{event_goals, pageview_goals} = Enum.split_with(site.goals, & &1.event_name)
revenue_goals = Enum.filter(event_goals, &Plausible.Goal.revenue?/1)
events = Enum.map(event_goals, & &1.event_name)
event_query = %Query{query | filters: Map.put(query.filters, "event:name", {:member, events})}
trace(query, property, metrics)
metrics =
if Enum.empty?(revenue_goals) do
metrics
else
metrics ++ [:average_revenue, :total_revenue]
end
event_results =
if Enum.any?(event_goals) do
breakdown(site, event_query, "event:name", metrics, pagination)
@ -170,7 +160,7 @@ defmodule Plausible.Stats.Breakdown do
for result <- event_results do
matching_goal = Enum.find(revenue_goals, &(&1.event_name == result.goal))
if matching_goal && result.total_revenue && result.average_revenue do
if matching_goal && result[:total_revenue] && result[:average_revenue] do
result
|> Map.put(:total_revenue, Money.new!(matching_goal.currency, result.total_revenue))
|> Map.put(:average_revenue, Money.new!(matching_goal.currency, result.average_revenue))

View File

@ -1033,7 +1033,7 @@ defmodule PlausibleWeb.Api.StatsController do
end
def conversions(conn, params) do
site = conn.assigns[:site]
site = Plausible.Repo.preload(conn.assigns.site, :goals)
query = Query.from(site, params) |> Filters.add_prefix()
query =
@ -1047,13 +1047,17 @@ defmodule PlausibleWeb.Api.StatsController do
%{visitors: %{value: total_visitors}} = Stats.aggregate(site, total_q, [:visitors])
metrics =
if Enum.any?(site.goals, &Plausible.Goal.revenue?/1) do
[:visitors, :events, :average_revenue, :total_revenue]
else
[:visitors, :events]
end
conversions =
Stats.breakdown(site, query, "event:goal", [:visitors, :events], {100, 1})
|> transform_keys(%{
goal: :name,
visitors: :unique_conversions,
events: :total_conversions
})
site
|> Stats.breakdown(query, "event:goal", metrics, {100, 1})
|> transform_keys(%{goal: :name, visitors: :unique_conversions, events: :total_conversions})
|> Enum.map(fn goal ->
goal
|> Map.put(:prop_names, CustomProps.props_for_goal(site, query))
@ -1062,7 +1066,7 @@ defmodule PlausibleWeb.Api.StatsController do
end)
if params["csv"] do
conversions |> to_csv([:name, :unique_conversions, :total_conversions])
to_csv(conversions, [:name, :unique_conversions, :total_conversions])
else
json(conn, conversions)
end