mirror of
https://github.com/plausible/analytics.git
synced 2024-12-22 17:11:36 +03:00
Remove grace period if user upgrades
This commit is contained in:
parent
ec2a4a1a65
commit
e9cb8eb4e2
@ -4,6 +4,15 @@ defimpl Bamboo.Formatter, for: Plausible.Auth.User do
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Plausible.Auth.GracePeriod do
|
||||
use Ecto.Schema
|
||||
|
||||
embedded_schema do
|
||||
field :end_date, :date
|
||||
field :allowance_required, :integer
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Plausible.Auth.User do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
@ -17,9 +26,9 @@ defmodule Plausible.Auth.User do
|
||||
field :name, :string
|
||||
field :last_seen, :naive_datetime
|
||||
field :trial_expiry_date, :date
|
||||
field :grace_period_end, :date
|
||||
field :theme, :string
|
||||
field :email_verified, :boolean
|
||||
embeds_one :grace_period, Plausible.Auth.GracePeriod, on_replace: :update
|
||||
|
||||
has_many :site_memberships, Plausible.Site.Membership
|
||||
has_many :sites, through: [:site_memberships, :site]
|
||||
@ -80,8 +89,17 @@ defmodule Plausible.Auth.User do
|
||||
change(user, trial_expiry_date: Timex.today() |> Timex.shift(days: -1))
|
||||
end
|
||||
|
||||
def start_grace_period(user) do
|
||||
change(user, grace_period_end: Timex.today() |> Timex.shift(days: 7))
|
||||
def start_grace_period(user, allowance_required) do
|
||||
grace_period = %Plausible.Auth.GracePeriod{
|
||||
end_date: Timex.today() |> Timex.shift(days: 7),
|
||||
allowance_required: allowance_required
|
||||
}
|
||||
|
||||
change(user, grace_period: grace_period)
|
||||
end
|
||||
|
||||
def remove_grace_period(user) do
|
||||
change(user, grace_period: nil)
|
||||
end
|
||||
|
||||
defp trial_expiry() do
|
||||
|
@ -17,20 +17,29 @@ defmodule Plausible.Billing do
|
||||
|
||||
changeset = Subscription.changeset(%Subscription{}, format_subscription(params))
|
||||
|
||||
Repo.insert(changeset)
|
||||
|> check_lock_status
|
||||
|> maybe_adjust_api_key_limits
|
||||
Repo.insert(changeset) |> after_subscription_update
|
||||
end
|
||||
|
||||
def subscription_updated(params) do
|
||||
subscription = Repo.get_by!(Subscription, paddle_subscription_id: params["subscription_id"])
|
||||
changeset = Subscription.changeset(subscription, format_subscription(params))
|
||||
|
||||
Repo.update(changeset)
|
||||
Repo.update(changeset) |> after_subscription_update
|
||||
end
|
||||
|
||||
defp after_subscription_update({:ok, subscription}) do
|
||||
user =
|
||||
Repo.get(Plausible.Auth.User, subscription.user_id)
|
||||
|> Map.put(:subscription, subscription)
|
||||
|
||||
{:ok, user}
|
||||
|> maybe_remove_grace_period
|
||||
|> check_lock_status
|
||||
|> maybe_adjust_api_key_limits
|
||||
end
|
||||
|
||||
defp after_subscription_update(err), do: err
|
||||
|
||||
def subscription_cancelled(params) do
|
||||
subscription =
|
||||
Repo.get_by(Subscription, paddle_subscription_id: params["subscription_id"])
|
||||
@ -114,7 +123,7 @@ defmodule Plausible.Billing do
|
||||
subscription_active = subscription_is_active?(user.subscription)
|
||||
|
||||
grace_period_ended =
|
||||
user.grace_period_end && Timex.before?(user.grace_period_end, Timex.today())
|
||||
user.grace_period && Timex.before?(user.grace_period.end_date, Timex.today())
|
||||
|
||||
cond do
|
||||
trial_is_over && !subscription_active -> {true, :no_active_subscription}
|
||||
@ -225,31 +234,48 @@ defmodule Plausible.Billing do
|
||||
defp present?(nil), do: false
|
||||
defp present?(_), do: true
|
||||
|
||||
defp check_lock_status({:ok, subscription}) do
|
||||
user =
|
||||
Repo.get(Plausible.Auth.User, subscription.user_id)
|
||||
|> Map.put(:subscription, subscription)
|
||||
defp maybe_remove_grace_period({:ok, user}) do
|
||||
alias Plausible.Auth.GracePeriod
|
||||
|
||||
case user.grace_period do
|
||||
%GracePeriod{allowance_required: allowance_required} ->
|
||||
new_allowance = Plausible.Billing.Plans.allowance(user.subscription)
|
||||
|
||||
if new_allowance > allowance_required do
|
||||
Plausible.Auth.User.remove_grace_period(user)
|
||||
|> Repo.update()
|
||||
else
|
||||
{:ok, user}
|
||||
end
|
||||
|
||||
_ ->
|
||||
{:ok, user}
|
||||
end
|
||||
end
|
||||
|
||||
defp maybe_remove_grace_period(err), do: err
|
||||
|
||||
defp check_lock_status({:ok, user}) do
|
||||
Plausible.Billing.SiteLocker.check_sites_for(user)
|
||||
{:ok, subscription}
|
||||
{:ok, user}
|
||||
end
|
||||
|
||||
defp check_lock_status(err), do: err
|
||||
|
||||
defp maybe_adjust_api_key_limits({:ok, subscription}) do
|
||||
defp maybe_adjust_api_key_limits({:ok, user}) do
|
||||
plan =
|
||||
Repo.get_by(Plausible.Billing.EnterprisePlan,
|
||||
user_id: subscription.user_id,
|
||||
paddle_plan_id: subscription.paddle_plan_id
|
||||
user_id: user.id,
|
||||
paddle_plan_id: user.subscription.paddle_plan_id
|
||||
)
|
||||
|
||||
if plan do
|
||||
user_id = subscription.user_id
|
||||
user_id = user.id
|
||||
api_keys = from(key in Plausible.Auth.ApiKey, where: key.user_id == ^user_id)
|
||||
Repo.update_all(api_keys, set: [hourly_request_limit: plan.hourly_api_request_limit])
|
||||
end
|
||||
|
||||
{:ok, subscription}
|
||||
{:ok, user}
|
||||
end
|
||||
|
||||
defp maybe_adjust_api_key_limits(err), do: err
|
||||
|
@ -96,7 +96,7 @@ defmodule Plausible.Workers.CheckUsage do
|
||||
)
|
||||
|
||||
Plausible.Mailer.send_email_safe(template)
|
||||
Plausible.Auth.User.start_grace_period(subscriber) |> Repo.update()
|
||||
Plausible.Auth.User.start_grace_period(subscriber, last_cycle_usage) |> Repo.update()
|
||||
|
||||
_ ->
|
||||
nil
|
||||
|
@ -3,7 +3,7 @@ defmodule Plausible.Repo.Migrations.GracePeriodEnd do
|
||||
|
||||
def change do
|
||||
alter table(:users) do
|
||||
add :grace_period_end, :date
|
||||
add :grace_period, :map
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -229,7 +229,8 @@ defmodule Plausible.BillingTest do
|
||||
end
|
||||
|
||||
@subscription_id "subscription-123"
|
||||
@plan_id "plan-123"
|
||||
@plan_id_10k "654177"
|
||||
@plan_id_100k "654178"
|
||||
|
||||
describe "subscription_created" do
|
||||
test "creates a subscription" do
|
||||
@ -238,7 +239,7 @@ defmodule Plausible.BillingTest do
|
||||
Billing.subscription_created(%{
|
||||
"alert_name" => "subscription_created",
|
||||
"subscription_id" => @subscription_id,
|
||||
"subscription_plan_id" => @plan_id,
|
||||
"subscription_plan_id" => @plan_id_10k,
|
||||
"update_url" => "update_url.com",
|
||||
"cancel_url" => "cancel_url.com",
|
||||
"passthrough" => user.id,
|
||||
@ -263,7 +264,7 @@ defmodule Plausible.BillingTest do
|
||||
"email" => user.email,
|
||||
"alert_name" => "subscription_created",
|
||||
"subscription_id" => @subscription_id,
|
||||
"subscription_plan_id" => @plan_id,
|
||||
"subscription_plan_id" => @plan_id_10k,
|
||||
"update_url" => "update_url.com",
|
||||
"cancel_url" => "cancel_url.com",
|
||||
"status" => "active",
|
||||
@ -285,7 +286,7 @@ defmodule Plausible.BillingTest do
|
||||
Billing.subscription_created(%{
|
||||
"alert_name" => "subscription_created",
|
||||
"subscription_id" => @subscription_id,
|
||||
"subscription_plan_id" => @plan_id,
|
||||
"subscription_plan_id" => @plan_id_10k,
|
||||
"update_url" => "update_url.com",
|
||||
"cancel_url" => "cancel_url.com",
|
||||
"passthrough" => user.id,
|
||||
@ -304,7 +305,7 @@ defmodule Plausible.BillingTest do
|
||||
plan =
|
||||
insert(:enterprise_plan,
|
||||
user: user,
|
||||
paddle_plan_id: @plan_id,
|
||||
paddle_plan_id: @plan_id_10k,
|
||||
hourly_api_request_limit: 10_000
|
||||
)
|
||||
|
||||
@ -313,7 +314,7 @@ defmodule Plausible.BillingTest do
|
||||
Billing.subscription_created(%{
|
||||
"alert_name" => "subscription_created",
|
||||
"subscription_id" => @subscription_id,
|
||||
"subscription_plan_id" => @plan_id,
|
||||
"subscription_plan_id" => @plan_id_10k,
|
||||
"update_url" => "update_url.com",
|
||||
"cancel_url" => "cancel_url.com",
|
||||
"passthrough" => user.id,
|
||||
@ -401,6 +402,66 @@ defmodule Plausible.BillingTest do
|
||||
|
||||
assert Repo.reload!(api_key).hourly_request_limit == plan.hourly_api_request_limit
|
||||
end
|
||||
|
||||
test "if user's grace period has ended, upgrading to the proper plan will unlock sites and remove grace period" do
|
||||
user =
|
||||
insert(:user,
|
||||
grace_period: %Plausible.Auth.GracePeriod{
|
||||
end_date: Timex.shift(Timex.today(), days: -1),
|
||||
allowance_required: 11_000
|
||||
}
|
||||
)
|
||||
|
||||
subscription = insert(:subscription, user: user)
|
||||
site = insert(:site, locked: true, members: [user])
|
||||
|
||||
Billing.subscription_updated(%{
|
||||
"alert_name" => "subscription_updated",
|
||||
"subscription_id" => subscription.paddle_subscription_id,
|
||||
"subscription_plan_id" => @plan_id_100k,
|
||||
"update_url" => "update_url.com",
|
||||
"cancel_url" => "cancel_url.com",
|
||||
"passthrough" => user.id,
|
||||
"old_status" => "past_due",
|
||||
"status" => "active",
|
||||
"next_bill_date" => "2019-06-01",
|
||||
"new_unit_price" => "12.00",
|
||||
"currency" => "EUR"
|
||||
})
|
||||
|
||||
assert Repo.reload!(site).locked == false
|
||||
assert Repo.reload!(user).grace_period == nil
|
||||
end
|
||||
|
||||
test "does not remove grace period if upgraded plan allowance is too low" do
|
||||
user =
|
||||
insert(:user,
|
||||
grace_period: %Plausible.Auth.GracePeriod{
|
||||
end_date: Timex.shift(Timex.today(), days: -1),
|
||||
allowance_required: 11_000
|
||||
}
|
||||
)
|
||||
|
||||
subscription = insert(:subscription, user: user)
|
||||
site = insert(:site, locked: true, members: [user])
|
||||
|
||||
Billing.subscription_updated(%{
|
||||
"alert_name" => "subscription_updated",
|
||||
"subscription_id" => subscription.paddle_subscription_id,
|
||||
"subscription_plan_id" => @plan_id_10k,
|
||||
"update_url" => "update_url.com",
|
||||
"cancel_url" => "cancel_url.com",
|
||||
"passthrough" => user.id,
|
||||
"old_status" => "past_due",
|
||||
"status" => "active",
|
||||
"next_bill_date" => "2019-06-01",
|
||||
"new_unit_price" => "12.00",
|
||||
"currency" => "EUR"
|
||||
})
|
||||
|
||||
assert Repo.reload!(site).locked == true
|
||||
assert Repo.reload!(user).grace_period.allowance_required == 11_000
|
||||
end
|
||||
end
|
||||
|
||||
describe "subscription_cancelled" do
|
||||
|
@ -50,7 +50,14 @@ defmodule Plausible.Billing.SiteLockerTest do
|
||||
end
|
||||
|
||||
test "does not lock user who has an active subscription and is on grace period" do
|
||||
user = insert(:user, grace_period_end: Timex.shift(Timex.today(), days: 1))
|
||||
user =
|
||||
insert(:user,
|
||||
grace_period: %Plausible.Auth.GracePeriod{
|
||||
end_date: Timex.shift(Timex.today(), days: 1),
|
||||
allowance_required: 10_000
|
||||
}
|
||||
)
|
||||
|
||||
insert(:subscription, status: "active", user: user)
|
||||
user = Repo.preload(user, :subscription)
|
||||
site = insert(:site, members: [user])
|
||||
@ -79,7 +86,14 @@ defmodule Plausible.Billing.SiteLockerTest do
|
||||
end
|
||||
|
||||
test "locks all sites if user has active subscription but grace period has ended" do
|
||||
user = insert(:user, grace_period_end: Timex.shift(Timex.today(), days: -1))
|
||||
user =
|
||||
insert(:user,
|
||||
grace_period: %Plausible.Auth.GracePeriod{
|
||||
end_date: Timex.shift(Timex.today(), days: -1),
|
||||
allowance_required: 10_000
|
||||
}
|
||||
)
|
||||
|
||||
insert(:subscription, status: "active", user: user)
|
||||
user = Repo.preload(user, :subscription)
|
||||
site = insert(:site, members: [user])
|
||||
@ -90,7 +104,14 @@ defmodule Plausible.Billing.SiteLockerTest do
|
||||
end
|
||||
|
||||
test "sends email if grace period has ended" do
|
||||
user = insert(:user, grace_period_end: Timex.shift(Timex.today(), days: -1))
|
||||
user =
|
||||
insert(:user,
|
||||
grace_period: %Plausible.Auth.GracePeriod{
|
||||
end_date: Timex.shift(Timex.today(), days: -1),
|
||||
allowance_required: 10_000
|
||||
}
|
||||
)
|
||||
|
||||
insert(:subscription, status: "active", user: user)
|
||||
user = Repo.preload(user, :subscription)
|
||||
insert(:site, members: [user])
|
||||
|
@ -24,7 +24,7 @@ defmodule Plausible.Workers.CheckUsageTest do
|
||||
CheckUsage.perform(nil)
|
||||
|
||||
assert_no_emails_delivered()
|
||||
assert Repo.reload(user).grace_period_end == nil
|
||||
assert Repo.reload(user).grace_period == nil
|
||||
end
|
||||
|
||||
test "does not send an email if account has been over the limit for one billing month", %{
|
||||
@ -46,7 +46,7 @@ defmodule Plausible.Workers.CheckUsageTest do
|
||||
CheckUsage.perform(nil, billing_stub)
|
||||
|
||||
assert_no_emails_delivered()
|
||||
assert Repo.reload(user).grace_period_end == nil
|
||||
assert Repo.reload(user).grace_period == nil
|
||||
end
|
||||
|
||||
test "sends an email when an account is over their limit for two consecutive billing months", %{
|
||||
@ -72,7 +72,7 @@ defmodule Plausible.Workers.CheckUsageTest do
|
||||
subject: "[Action required] You have outgrown your Plausible subscription tier"
|
||||
)
|
||||
|
||||
assert Repo.reload(user).grace_period_end == Timex.shift(Timex.today(), days: 7)
|
||||
assert Repo.reload(user).grace_period.end_date == Timex.shift(Timex.today(), days: 7)
|
||||
end
|
||||
|
||||
describe "enterprise customers" do
|
||||
|
Loading…
Reference in New Issue
Block a user