analytics/lib/mix/tasks/analyze_plans.ex

61 lines
1.5 KiB
Elixir
Raw Normal View History

2022-01-15 18:07:59 +03:00
defmodule Mix.Tasks.AnalyzePlans do
use Mix.Task
use Plausible.Repo
# coveralls-ignore-start
def run(_) do
Mix.Task.run("app.start")
res =
Repo.all(
from s in Plausible.Billing.Subscription,
where: s.status == "active",
group_by: s.paddle_plan_id,
select: {s.paddle_plan_id, count(s)}
)
res =
Enum.map(res, fn {plan_id, count} ->
plan = Plausible.Billing.Plans.for_product_id(plan_id)
if plan do
is_monthly = plan_id == plan[:monthly_product_id]
monthly_revenue =
if is_monthly do
price(plan[:monthly_cost])
else
price(plan[:yearly_cost]) / 12
end
{PlausibleWeb.StatsView.large_number_format(plan[:limit]), monthly_revenue, count}
end
end)
|> Enum.filter(& &1)
res =
Enum.reduce(res, %{}, fn {limit, revenue, count}, acc ->
total_revenue = revenue * count
Map.update(acc, limit, {total_revenue, count}, fn {ex_rev, ex_count} ->
{ex_rev + total_revenue, ex_count + count}
end)
end)
total_revenue = round(Enum.reduce(res, 0, fn {_, {revenue, _}}, sum -> sum + revenue end))
for {limit, {rev, _}} <- res do
percentage = round(rev / total_revenue * 100)
IO.puts(
"The #{limit} plan makes up #{percentage}% of total revenue ($#{round(rev)} / $#{total_revenue})"
)
end
end
defp price("$" <> nr) do
String.to_integer(nr)
end
end