mirror of
https://github.com/plausible/analytics.git
synced 2024-11-28 21:47:25 +03:00
Switch billing controller action to teams schema behind FF (#4843)
* Switch upgrade to enterprise plan view to teams schema behind FF * Switch change plan preview action to teams schema behind FF * Switch remaining billing controller actions to teams schema behind FF
This commit is contained in:
parent
380dc00d1a
commit
a29eb3d3ca
@ -55,7 +55,8 @@ defmodule Plausible.Billing do
|
|||||||
do: do_change_plan(subscription, new_plan_id)
|
do: do_change_plan(subscription, new_plan_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_change_plan(subscription, new_plan_id) do
|
@doc false
|
||||||
|
def do_change_plan(subscription, new_plan_id) do
|
||||||
res =
|
res =
|
||||||
paddle_api().update_subscription(subscription.paddle_subscription_id, %{
|
paddle_api().update_subscription(subscription.paddle_subscription_id, %{
|
||||||
plan_id: new_plan_id
|
plan_id: new_plan_id
|
||||||
|
@ -4,6 +4,13 @@ defmodule Plausible.Teams.Adapter.Read.Billing do
|
|||||||
"""
|
"""
|
||||||
use Plausible.Teams.Adapter
|
use Plausible.Teams.Adapter
|
||||||
|
|
||||||
|
def change_plan(user, new_plan_id) do
|
||||||
|
switch(user,
|
||||||
|
team_fn: &Plausible.Teams.Billing.change_plan(&1, new_plan_id),
|
||||||
|
user_fn: &Plausible.Billing.change_plan(&1, new_plan_id)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def enterprise_configured?(nil), do: false
|
def enterprise_configured?(nil), do: false
|
||||||
|
|
||||||
def enterprise_configured?(user) do
|
def enterprise_configured?(user) do
|
||||||
@ -13,6 +20,13 @@ defmodule Plausible.Teams.Adapter.Read.Billing do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def latest_enterprise_plan_with_prices(user, customer_ip) do
|
||||||
|
switch(user,
|
||||||
|
team_fn: &Plausible.Teams.Billing.latest_enterprise_plan_with_price(&1, customer_ip),
|
||||||
|
user_fn: &Plausible.Billing.Plans.latest_enterprise_plan_with_price(&1, customer_ip)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def has_active_subscription?(user) do
|
def has_active_subscription?(user) do
|
||||||
switch(user,
|
switch(user,
|
||||||
team_fn: &Plausible.Teams.Billing.has_active_subscription?/1,
|
team_fn: &Plausible.Teams.Billing.has_active_subscription?/1,
|
||||||
@ -20,6 +34,13 @@ defmodule Plausible.Teams.Adapter.Read.Billing do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_subscription_for(user) do
|
||||||
|
switch(user,
|
||||||
|
team_fn: &Plausible.Teams.Billing.active_subscription_for/1,
|
||||||
|
user_fn: &Plausible.Billing.active_subscription_for/1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def get_subscription(user) do
|
def get_subscription(user) do
|
||||||
case user_or_team(user) do
|
case user_or_team(user) do
|
||||||
%{subscription: subscription} -> subscription
|
%{subscription: subscription} -> subscription
|
||||||
|
@ -18,6 +18,24 @@ defmodule Plausible.Teams.Billing do
|
|||||||
@limit_sites_since ~D[2021-05-05]
|
@limit_sites_since ~D[2021-05-05]
|
||||||
@site_limit_for_trials 10
|
@site_limit_for_trials 10
|
||||||
|
|
||||||
|
def change_plan(team, new_plan_id) do
|
||||||
|
subscription = active_subscription_for(team)
|
||||||
|
plan = Plausible.Billing.Plans.find(new_plan_id)
|
||||||
|
|
||||||
|
limit_checking_opts =
|
||||||
|
if team.allow_next_upgrade_override do
|
||||||
|
[ignore_pageview_limit: true]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
usage = quota_usage(team)
|
||||||
|
|
||||||
|
with :ok <-
|
||||||
|
Plausible.Billing.Quota.ensure_within_plan_limits(usage, plan, limit_checking_opts),
|
||||||
|
do: Plausible.Billing.do_change_plan(subscription, new_plan_id)
|
||||||
|
end
|
||||||
|
|
||||||
def enterprise_configured?(nil), do: false
|
def enterprise_configured?(nil), do: false
|
||||||
|
|
||||||
def enterprise_configured?(%Teams.Team{} = team) do
|
def enterprise_configured?(%Teams.Team{} = team) do
|
||||||
@ -26,6 +44,19 @@ defmodule Plausible.Teams.Billing do
|
|||||||
|> Repo.exists?()
|
|> Repo.exists?()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def latest_enterprise_plan_with_price(team, customer_ip) do
|
||||||
|
enterprise_plan =
|
||||||
|
Repo.one!(
|
||||||
|
from(e in EnterprisePlan,
|
||||||
|
where: e.team_id == ^team.id,
|
||||||
|
order_by: [desc: e.inserted_at],
|
||||||
|
limit: 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
{enterprise_plan, Plausible.Billing.Plans.get_price_for(enterprise_plan, customer_ip)}
|
||||||
|
end
|
||||||
|
|
||||||
def has_active_subscription?(nil), do: false
|
def has_active_subscription?(nil), do: false
|
||||||
|
|
||||||
def has_active_subscription?(team) do
|
def has_active_subscription?(team) do
|
||||||
@ -34,6 +65,12 @@ defmodule Plausible.Teams.Billing do
|
|||||||
|> Repo.exists?()
|
|> Repo.exists?()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_subscription_for(team) do
|
||||||
|
team
|
||||||
|
|> active_subscription_query()
|
||||||
|
|> Repo.one()
|
||||||
|
end
|
||||||
|
|
||||||
def check_needs_to_upgrade(nil), do: {:needs_to_upgrade, :no_trial}
|
def check_needs_to_upgrade(nil), do: {:needs_to_upgrade, :no_trial}
|
||||||
|
|
||||||
def check_needs_to_upgrade(team) do
|
def check_needs_to_upgrade(team) do
|
||||||
@ -132,7 +169,7 @@ defmodule Plausible.Teams.Billing do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def quota_usage(team, opts) do
|
def quota_usage(team, opts \\ []) do
|
||||||
team = Teams.with_subscription(team)
|
team = Teams.with_subscription(team)
|
||||||
with_features? = Keyword.get(opts, :with_features, false)
|
with_features? = Keyword.get(opts, :with_features, false)
|
||||||
pending_site_ids = Keyword.get(opts, :pending_ownership_site_ids, [])
|
pending_site_ids = Keyword.get(opts, :pending_ownership_site_ids, [])
|
||||||
|
@ -30,19 +30,20 @@ defmodule PlausibleWeb.BillingController do
|
|||||||
|
|
||||||
def upgrade_to_enterprise_plan(conn, _params) do
|
def upgrade_to_enterprise_plan(conn, _params) do
|
||||||
current_user = conn.assigns.current_user
|
current_user = conn.assigns.current_user
|
||||||
|
subscription = Plausible.Teams.Adapter.Read.Billing.get_subscription(current_user)
|
||||||
|
|
||||||
{latest_enterprise_plan, price} =
|
{latest_enterprise_plan, price} =
|
||||||
Plans.latest_enterprise_plan_with_price(current_user, PlausibleWeb.RemoteIP.get(conn))
|
Plans.latest_enterprise_plan_with_price(current_user, PlausibleWeb.RemoteIP.get(conn))
|
||||||
|
|
||||||
subscription_resumable? =
|
subscription_resumable? =
|
||||||
Plausible.Billing.Subscriptions.resumable?(current_user.subscription)
|
Plausible.Billing.Subscriptions.resumable?(subscription)
|
||||||
|
|
||||||
subscribed_to_latest? =
|
subscribed_to_latest? =
|
||||||
subscription_resumable? &&
|
subscription_resumable? &&
|
||||||
current_user.subscription.paddle_plan_id == latest_enterprise_plan.paddle_plan_id
|
subscription.paddle_plan_id == latest_enterprise_plan.paddle_plan_id
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
Subscription.Status.in?(current_user.subscription, [
|
Subscription.Status.in?(subscription, [
|
||||||
Subscription.Status.past_due(),
|
Subscription.Status.past_due(),
|
||||||
Subscription.Status.paused()
|
Subscription.Status.paused()
|
||||||
]) ->
|
]) ->
|
||||||
@ -68,8 +69,9 @@ defmodule PlausibleWeb.BillingController do
|
|||||||
|
|
||||||
def change_plan_preview(conn, %{"plan_id" => new_plan_id}) do
|
def change_plan_preview(conn, %{"plan_id" => new_plan_id}) do
|
||||||
current_user = conn.assigns.current_user
|
current_user = conn.assigns.current_user
|
||||||
|
subscription = Plausible.Teams.Adapter.Read.Billing.active_subscription_for(current_user)
|
||||||
|
|
||||||
case preview_subscription(current_user, new_plan_id) do
|
case preview_subscription(subscription, new_plan_id) do
|
||||||
{:ok, {subscription, preview_info}} ->
|
{:ok, {subscription, preview_info}} ->
|
||||||
render(conn, "change_plan_preview.html",
|
render(conn, "change_plan_preview.html",
|
||||||
back_link: Routes.billing_path(conn, :choose_plan),
|
back_link: Routes.billing_path(conn, :choose_plan),
|
||||||
@ -99,7 +101,7 @@ defmodule PlausibleWeb.BillingController do
|
|||||||
def change_plan(conn, %{"new_plan_id" => new_plan_id}) do
|
def change_plan(conn, %{"new_plan_id" => new_plan_id}) do
|
||||||
current_user = conn.assigns.current_user
|
current_user = conn.assigns.current_user
|
||||||
|
|
||||||
case Billing.change_plan(current_user, new_plan_id) do
|
case Plausible.Teams.Adapter.Read.Billing.change_plan(current_user, new_plan_id) do
|
||||||
{:ok, _subscription} ->
|
{:ok, _subscription} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:success, "Plan changed successfully")
|
|> put_flash(:success, "Plan changed successfully")
|
||||||
@ -137,15 +139,11 @@ defmodule PlausibleWeb.BillingController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp preview_subscription(user, new_plan_id) do
|
defp preview_subscription(nil, _new_plan_id), do: {:error, :no_subscription}
|
||||||
subscription = Billing.active_subscription_for(user)
|
|
||||||
|
|
||||||
if subscription do
|
defp preview_subscription(subscription, new_plan_id) do
|
||||||
with {:ok, preview_info} <- Billing.change_plan_preview(subscription, new_plan_id) do
|
with {:ok, preview_info} <- Billing.change_plan_preview(subscription, new_plan_id) do
|
||||||
{:ok, {subscription, preview_info}}
|
{:ok, {subscription, preview_info}}
|
||||||
end
|
|
||||||
else
|
|
||||||
{:error, :no_subscription}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -24,17 +24,13 @@ defmodule PlausibleWeb.BillingControllerTest do
|
|||||||
setup [:create_user, :log_in]
|
setup [:create_user, :log_in]
|
||||||
|
|
||||||
test "errors if usage exceeds team member limit on the new plan", %{conn: conn, user: user} do
|
test "errors if usage exceeds team member limit on the new plan", %{conn: conn, user: user} do
|
||||||
insert(:subscription, user: user, paddle_plan_id: "123123")
|
subscribe_to_plan(user, "123123")
|
||||||
|
|
||||||
insert(:site,
|
site = new_site(owner: user)
|
||||||
memberships: [
|
|
||||||
build(:site_membership, user: user, role: :owner),
|
for _ <- 1..4 do
|
||||||
build(:site_membership, user: build(:user)),
|
add_guest(site, role: :viewer)
|
||||||
build(:site_membership, user: build(:user)),
|
end
|
||||||
build(:site_membership, user: build(:user)),
|
|
||||||
build(:site_membership, user: build(:user))
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
conn = post(conn, Routes.billing_path(conn, :change_plan, @v4_growth_plan))
|
conn = post(conn, Routes.billing_path(conn, :change_plan, @v4_growth_plan))
|
||||||
|
|
||||||
@ -46,9 +42,9 @@ defmodule PlausibleWeb.BillingControllerTest do
|
|||||||
conn: conn,
|
conn: conn,
|
||||||
user: user
|
user: user
|
||||||
} do
|
} do
|
||||||
insert(:subscription, user: user, paddle_plan_id: "123123")
|
subscribe_to_plan(user, "123123")
|
||||||
|
|
||||||
for _ <- 1..11, do: insert(:site, members: [user])
|
for _ <- 1..11, do: new_site(owner: user)
|
||||||
|
|
||||||
Plausible.Users.allow_next_upgrade_override(user)
|
Plausible.Users.allow_next_upgrade_override(user)
|
||||||
|
|
||||||
@ -64,8 +60,8 @@ defmodule PlausibleWeb.BillingControllerTest do
|
|||||||
conn: conn,
|
conn: conn,
|
||||||
user: user
|
user: user
|
||||||
} do
|
} do
|
||||||
insert(:subscription, user: user, paddle_plan_id: "123123")
|
subscribe_to_plan(user, "123123")
|
||||||
site = insert(:site, members: [user])
|
site = new_site(owner: user)
|
||||||
now = NaiveDateTime.utc_now()
|
now = NaiveDateTime.utc_now()
|
||||||
|
|
||||||
generate_usage_for(site, 11_000, Timex.shift(now, days: -5))
|
generate_usage_for(site, 11_000, Timex.shift(now, days: -5))
|
||||||
@ -91,7 +87,7 @@ defmodule PlausibleWeb.BillingControllerTest do
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "calls Paddle API to update subscription", %{conn: conn, user: user} do
|
test "calls Paddle API to update subscription", %{conn: conn, user: user} do
|
||||||
insert(:subscription, user: user)
|
subscribe_to_plan(user, "321321")
|
||||||
|
|
||||||
post(conn, Routes.billing_path(conn, :change_plan, "123123"))
|
post(conn, Routes.billing_path(conn, :change_plan, "123123"))
|
||||||
|
|
||||||
@ -218,7 +214,7 @@ defmodule PlausibleWeb.BillingControllerTest do
|
|||||||
setup [:create_user, :log_in]
|
setup [:create_user, :log_in]
|
||||||
|
|
||||||
test "renders preview information about the plan change", %{conn: conn, user: user} do
|
test "renders preview information about the plan change", %{conn: conn, user: user} do
|
||||||
insert(:subscription, user: user, paddle_plan_id: @v4_growth_plan)
|
subscribe_to_plan(user, @v4_growth_plan)
|
||||||
|
|
||||||
html_response =
|
html_response =
|
||||||
conn
|
conn
|
||||||
@ -339,29 +335,30 @@ defmodule PlausibleWeb.BillingControllerTest do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp configure_enterprise_plan(%{user: user}) do
|
defp configure_enterprise_plan(%{user: user}) do
|
||||||
insert(:enterprise_plan,
|
subscribe_to_enterprise_plan(user,
|
||||||
user_id: user.id,
|
|
||||||
paddle_plan_id: "123",
|
paddle_plan_id: "123",
|
||||||
billing_interval: :yearly,
|
billing_interval: :yearly,
|
||||||
monthly_pageview_limit: 50_000_000,
|
monthly_pageview_limit: 50_000_000,
|
||||||
site_limit: 20_000,
|
site_limit: 20_000,
|
||||||
hourly_api_request_limit: 5000,
|
hourly_api_request_limit: 5000,
|
||||||
inserted_at: Timex.now() |> Timex.shift(hours: 1)
|
inserted_at: NaiveDateTime.utc_now() |> NaiveDateTime.shift(hour: 1),
|
||||||
|
subscription?: false
|
||||||
)
|
)
|
||||||
|
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
|
|
||||||
defp subscribe_enterprise(%{user: user}, opts \\ []) do
|
defp subscribe_enterprise(%{user: user}, opts \\ []) do
|
||||||
|
{paddle_plan_id, opts} = Keyword.pop(opts, :paddle_plan_id, "321")
|
||||||
|
|
||||||
opts =
|
opts =
|
||||||
opts
|
opts
|
||||||
|> Keyword.put(:user, user)
|
|> Keyword.put(:user, user)
|
||||||
|> Keyword.put_new(:paddle_plan_id, "321")
|
|
||||||
|> Keyword.put_new(:status, Subscription.Status.active())
|
|> Keyword.put_new(:status, Subscription.Status.active())
|
||||||
|
|
||||||
insert(:subscription, opts)
|
user = subscribe_to_plan(user, paddle_plan_id, opts)
|
||||||
|
|
||||||
{:ok, user: Plausible.Users.with_subscription(user)}
|
{:ok, user: user}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_paddle_checkout_params(element) do
|
defp get_paddle_checkout_params(element) do
|
||||||
|
Loading…
Reference in New Issue
Block a user