Skip to content

Commit

Permalink
Move pricing logic into plan model
Browse files Browse the repository at this point in the history
Old `Plan` model become obsolete with tiered plans.
`Pricing` was an odd-name because `Plan` was taken.
We can now move new logic into the `Plan` model, and refactor
surrounding tier logic.
  • Loading branch information
Greg Lazarev committed May 26, 2017
1 parent d57b4cc commit 17f1aa9
Show file tree
Hide file tree
Showing 57 changed files with 686 additions and 892 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ exports[`NotifyTierChange snapshots renders plans appropriately (Chihuahua -> La
<div
className="tier-change-content">
<h1>
Pricing: Change of Plans
Change of Plans
</h1>
<section
className="tier-change-description">
Expand Down Expand Up @@ -133,7 +133,7 @@ exports[`NotifyTierChange snapshots renders plans appropriately (Labrador -> Gre
<div
className="tier-change-content">
<h1>
Pricing: Change of Plans
Change of Plans
</h1>
<section
className="tier-change-description">
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/components/notify_tier_change.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class NotifyTierChange extends React.Component {
{this.renderTierPlans()}
</aside>
<div className="tier-change-content">
<h1>Pricing: Change of Plans</h1>
<h1>Change of Plans</h1>
<section className="tier-change-description">
<div className="allowance large">
Private Repos
Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/components/repos_container.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class ReposContainer extends React.Component {
updateSubscribedRepoCount() {
this.getUser().then(user => {
const subscribedRepoCount = user.subscribed_repo_count;
const tierAllowance = user.tier_allowance;
const tierAllowance = user.plan_max;

if (subscribedRepoCount === 0) {
$("[data-role='allowance-container']").remove();
Expand Down Expand Up @@ -123,7 +123,7 @@ class ReposContainer extends React.Component {

onSubscriptionError(repo, error) {
if (error.status === 402) {
document.location.href = `/pricings?repo_id=${repo.id}`;
document.location.href = `/plans?repo_id=${repo.id}`;
} else {
alert("Your subscription could not be activated.");
}
Expand Down
16 changes: 16 additions & 0 deletions app/controllers/plans_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class PlansController < ApplicationController
def index
@plans = ActiveModel::ArraySerializer.new(
Plan.all,
each_serializer: PlanSerializer,
scope: current_user,
)
@repo = Repo.find(plan_params[:repo_id])
end

private

def plan_params
params.permit(:repo_id)
end
end
16 changes: 0 additions & 16 deletions app/controllers/pricings_controller.rb

This file was deleted.

2 changes: 1 addition & 1 deletion app/controllers/subscriptions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class FailedToActivate < StandardError; end
before_action :update_email

def create
if Tier.new(current_user).full?
if current_user.plan_upgrade?
render json: {}, status: :payment_required
elsif activator.activate && create_subscription
render json: repo, status: :created
Expand Down
12 changes: 10 additions & 2 deletions app/models/analytics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def track_repo_deactivated(repo)
properties: {
name: repo.name,
private: repo.private,
revenue: -repo.plan_price,
revenue: lost_revenue,
}
)
end
Expand All @@ -53,12 +53,20 @@ def track_build_completed(repo)

private

attr_reader :user

def track(options)
backend.track({
active_repos_count: user.repos.active.count,
user_id: user.id,
}.merge(options))
end

attr_reader :user
def lost_revenue
if user.current_plan == user.next_plan
0
else
user.current_plan_price - user.next_plan_price
end
end
end
20 changes: 10 additions & 10 deletions app/models/home.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ def initialize(user)
@user = user
end

def open_source_pricings
open_source_repos.map { |pricing| present(pricing) }
def open_source_plans
open_source_repos.map { |plan| present(plan) }
end

def private_pricings
private_repos.map { |pricing| present(pricing) }
def private_plans
private_repos.map { |plan| present(plan) }
end

private

def present(pricing)
PricingPresenter.new(pricing: pricing, user: user)
def present(plan)
PlanPresenter.new(plan: plan, user: user)
end

def pricings
Pricing.all
def plans
Plan.all
end

def private_repos
pricings.reject(&:open_source?)
plans.reject(&:open_source?)
end

def open_source_repos
pricings.select(&:open_source?)
plans.select(&:open_source?)
end
end
10 changes: 3 additions & 7 deletions app/models/payment_gateway_customer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def subscription
def retrieve_subscription(subscription_id)
PaymentGatewaySubscription.new(
stripe_subscription: customer.subscriptions.retrieve(subscription_id),
tier: tier,
user: user,
)
end

Expand All @@ -54,7 +54,7 @@ def update_email(email)
def create_subscription(options)
PaymentGatewaySubscription.new(
stripe_subscription: customer.subscriptions.create(options),
tier: tier,
user: user,
)
end

Expand All @@ -67,15 +67,11 @@ def subscriptions
customer.subscriptions.map do |subscription|
PaymentGatewaySubscription.new(
stripe_subscription: subscription,
tier: tier,
user: user,
)
end
end

def tier
Tier.new(user)
end

class NoRecord
def email
""
Expand Down
14 changes: 5 additions & 9 deletions app/models/payment_gateway_subscription.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class PaymentGatewaySubscription
attr_reader :stripe_subscription, :tier
attr_reader :stripe_subscription, :user

delegate(
:id,
Expand All @@ -11,14 +11,14 @@ class PaymentGatewaySubscription
to: :stripe_subscription,
)

def initialize(stripe_subscription:, tier:)
def initialize(stripe_subscription:, user:)
@stripe_subscription = stripe_subscription
@tier = tier
@user = user
end

def subscribe(repo_id)
append_repo_id_to_metadata(repo_id)
self.plan = tier.next.id
self.plan = user.next_plan.id
save
end

Expand Down Expand Up @@ -51,11 +51,7 @@ def current_repo_ids
end

def downgraded_plan
previous_tier.id
end

def previous_tier
tier.previous
user.previous_plan.id
end

def stripe_plan
Expand Down
67 changes: 37 additions & 30 deletions app/models/plan.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
class Plan
PRICES = {
bulk: 0,
public: 0,
private: 12
}

TYPES = {
bulk: "bulk",
public: "public",
private: "private"
}

def initialize(repo)
@repo = repo
include ActiveModel::Serialization

PLANS = [
{ id: "basic", price: 0, range: 0..0, title: "Hound" },
{ id: "tier1", price: 49, range: 1..4, title: "Chihuahua" },
{ id: "tier2", price: 99, range: 5..10, title: "Labrador" },
{ id: "tier3", price: 249, range: 11..30, title: "Great Dane" },
].freeze

attr_reader :id, :price, :title

def initialize(id:, range:, price:, title:)
@id = id
@range = range
@price = price
@title = title
end

def type
if @repo.bulk?
TYPES[:bulk]
elsif @repo.private?
TYPES[:private]
else
TYPES[:public]
end
def self.all
PLANS.map { |plan| new(plan) }
end

def price
if @repo.bulk?
PRICES[:bulk]
elsif @repo.private?
PRICES[:private]
else
PRICES[:public]
end
def self.find_by(count:)
found = PLANS.detect { |plan| plan.fetch(:range).include?(count) }
new(found)
end

def ==(other)
id == other.id
end

def allowance
range.max
end

def open_source?
price.zero?
end

private

attr_reader :range
end
39 changes: 39 additions & 0 deletions app/models/plan_selector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class PlanSelector
BULK_ID = "bulk".freeze

def initialize(user)
@user = user
end

def current_plan
find_plan(repo_count)
end

def next_plan
find_plan(repo_count.succ)
end

def previous_plan
find_plan(repo_count.pred)
end

def upgrade?
current_plan != next_plan
end

private

attr_reader :user

def repo_count
@_repo_count ||= repos.size
end

def find_plan(count)
Plan.find_by(count: count)
end

def repos
user.subscribed_repos
end
end
44 changes: 0 additions & 44 deletions app/models/pricing.rb

This file was deleted.

Loading

0 comments on commit 17f1aa9

Please sign in to comment.