Remove trial support
This commit is contained in:
parent
6667eb6fac
commit
51ef25b3af
30 changed files with 3 additions and 241 deletions
|
@ -10,7 +10,6 @@ class ApplicationController < ActionController::Base
|
|||
:current_role?,
|
||||
:current_nonprofit_user?,
|
||||
:administered_nonprofit,
|
||||
:nonprofit_in_trial?,
|
||||
:current_plan_tier # int
|
||||
|
||||
def set_locale
|
||||
|
@ -125,14 +124,6 @@ class ApplicationController < ActionController::Base
|
|||
QueryRoles.user_has_role?(current_user.id, role_names, host_id)
|
||||
end
|
||||
|
||||
def nonprofit_in_trial?(npo_id = nil)
|
||||
return false if !npo_id && !administered_nonprofit
|
||||
|
||||
npo_id ||= administered_nonprofit.id
|
||||
key = "in_trial_user_#{current_user_id}_nonprofit_#{npo_id}"
|
||||
QueryBillingSubscriptions.currently_in_trial?(npo_id)
|
||||
end
|
||||
|
||||
def current_plan_tier(npo_id = nil)
|
||||
return 0 if !npo_id && !administered_nonprofit
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ module Nonprofits
|
|||
requires(:holder_type).one_of('Supporter', 'Nonprofit')
|
||||
end
|
||||
end.when_valid do |d|
|
||||
UpdateBillingSubscriptions.activate_from_trial(d[:nonprofit_id])
|
||||
InsertCard.with_stripe(d[:card])
|
||||
end
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@ class BillingSubscription < ApplicationRecord
|
|||
# :nonprofit_id, :nonprofit,
|
||||
# :billing_plan_id, :billing_plan,
|
||||
# :stripe_subscription_id,
|
||||
# :status # trialing, active, past_due, canceled, or unpaid
|
||||
# :status # active, past_due, canceled, or unpaid
|
||||
|
||||
attr_accessor :stripe_plan_id, :manual
|
||||
belongs_to :nonprofit
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
<%= IncludeAsset.js '/client/js/campaigns/index/page.js' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'components/header',
|
||||
icon_class: 'icon-thermometer-medium',
|
||||
title: 'Campaigns',
|
||||
|
|
|
@ -59,8 +59,6 @@
|
|||
<%= render 'admin_top_nav' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'components/fundraising_pages/header',
|
||||
image_url: @campaign_background_image,
|
||||
is_editor: current_campaign_editor?,
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
<%= stylesheet_link_tag 'campaigns/supporters/index/page' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<header class='header'>
|
||||
<div class='container'>
|
||||
<i class='icon-check-list header-icon'></i>
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<%- # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later -%>
|
||||
<!-- partial start: componenets/trial_bar -->
|
||||
<div class='is-showing announcementBar--grey'>
|
||||
<div class='container transparent centered'>
|
||||
You have <%= QueryBillingSubscriptions.days_left_in_trial(@nonprofit.id) %> days left in your free trial. You can
|
||||
<a href="/nonprofits/<%= @nonprofit.id%>/card/edit" class='u-underline'>activate your account at anytime.
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- partial end: componenets/trial_bar -->
|
|
@ -43,8 +43,6 @@
|
|||
<%= render 'admin_top_nav' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'components/fundraising_pages/header',
|
||||
image_url: @event_background_image,
|
||||
is_editor: current_event_editor?,
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
<%- # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later -%>
|
||||
<div class='modal skinny' id='newNonprofitModal'>
|
||||
<%= render 'common/modal_header', title: 'Register Your Organization' %>
|
||||
|
||||
<div class='modal-body'>
|
||||
|
||||
<form parsley-validate>
|
||||
<!--= on 'submit' (create_admin_and_nonprofit form_object) -->
|
||||
<input type='text' name='name' placeholder='Organization name' required parsley-trigger='change'>
|
||||
<select>
|
||||
<!--= show_if is_onboarding_with_trial -->
|
||||
<!--= set_attr_if is_onboarding_with_trial 'name' 'tier' -->
|
||||
<!--= set_attr_if is_onboarding_with_trial 'required' '' -->
|
||||
<option value='' selected>Organization Budget</option>
|
||||
<option value='1'>less than $250K</option>
|
||||
<option value='2'>$250K ~ $5M</option>
|
||||
<option value='3'>$5M+</option>
|
||||
</select>
|
||||
|
||||
<input type='text' name='city' placeholder='City' required parsley-trigger='change' class='input--half'>
|
||||
<input type='hidden' name='referrer' value="<%= params[:referrer] %>">
|
||||
|
||||
<select name='state_code' class='input--half u-floatR' required>
|
||||
<option value='' selected>State</option>
|
||||
<% us_states.each do |state| %>
|
||||
<option value='<%= state[1] %>'><%= state[1] %></option>
|
||||
<% end %>
|
||||
</select>
|
||||
|
||||
<input type='text' name='website' parsley-trigger='change' placeholder='Nonprofit website'>
|
||||
|
||||
<%= render 'components/forms/submit_button', button_text: 'Create', scope: 'new_nonprofit' %>
|
||||
</form>
|
||||
|
||||
<p class='finePrint u-marginTop--20 u-marginBottom--0 u-centered'>By clicking Create, you agree to our <%= link_to "terms of service & privacy policy", (root_url + "help/terms-of-service-and-privacy-policy"), target: :blank %></p>
|
||||
</div>
|
||||
</div>
|
|
@ -8,8 +8,6 @@
|
|||
<%= IncludeAsset.js '/client/js/nonprofits/button/page.js' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<header class='header'>
|
||||
<div class='container--mid'>
|
||||
<i class='header-icon icon-credit-card'></i>
|
||||
|
|
|
@ -22,8 +22,6 @@ document.addEventListener("DOMContentLoaded", function(event) {
|
|||
})
|
||||
</script>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<header class='header'>
|
||||
<div class='container--mid'>
|
||||
<i class='header-icon icon-credit-card'></i>
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
<%= IncludeAsset.js '/client/js/nonprofits/button/page.js' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<header class='header'>
|
||||
<div class='container--mid'>
|
||||
<i class='header-icon icon-credit-card'></i>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
card: <%= @nonprofit.active_card ? raw(@nonprofit.active_card.to_json) : '{}' %>
|
||||
, plan: <%= raw(@nonprofit.billing_plan.to_json) %>
|
||||
, subscription: <%= raw(@nonprofit.billing_subscription.to_json) %>
|
||||
, daysLeft : <%= QueryBillingSubscriptions.days_left_in_trial(@nonprofit.id) %>
|
||||
}
|
||||
</script>
|
||||
<%= IncludeAsset.js '/client/js/nonprofits/cards/edit/page.js' %>
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
<%= IncludeAsset.js '/client/js/nonprofits/dashboard/page.js' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial? %>
|
||||
|
||||
<%= render 'components/header',
|
||||
icon_class: 'icon-camera-graph-2',
|
||||
title: 'Dashboard',
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
</script>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'nonprofits/transaction_title',
|
||||
active: :payments,
|
||||
icon_class: 'icon-piggy-bank',
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
</script>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'nonprofits/transaction_title',
|
||||
active: :payouts,
|
||||
icon_class: 'icon-bank-1',
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
<%= IncludeAsset.js '/client/js/nonprofits/recurring_donations/index/page.js' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'nonprofits/transaction_title',
|
||||
active: :recurring,
|
||||
icon_class: 'icon-return',
|
||||
|
|
|
@ -59,8 +59,6 @@
|
|||
<%= render 'admin_top_nav' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'components/fundraising_pages/header',
|
||||
image_url: @nonprofit_background_image,
|
||||
is_editor: current_nonprofit_user?,
|
||||
|
|
|
@ -40,8 +40,6 @@
|
|||
</script>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<%= render 'header'%>
|
||||
<%= render 'table_meta' %>
|
||||
|
||||
|
|
|
@ -15,14 +15,8 @@
|
|||
</strong><br>
|
||||
<em><small>Our processor (Stripe) assesses an additional 2.2% + $0.30 for each online payment.</small></em></p>
|
||||
|
||||
<% if @nonprofit.billing_subscription.status == 'trialing' %>
|
||||
<p>
|
||||
To ensure that your account stays active after your trial,
|
||||
<a href='/nonprofits/<%=@nonprofit.id%>/card/edit'><strong> add a payment method.</strong></a>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if @nonprofit.billing_plan.amount > 0 && @nonprofit.billing_subscription.status != 'trialing' %>
|
||||
<% if @nonprofit.billing_plan.amount > 0 %>
|
||||
<p><a class='u-color--red u-small' href='/nonprofits/<%=@nonprofit.id%>/billing_subscription/cancellation'>Unsubscribe from plan</a></p>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
<%= IncludeAsset.js '/client/js/settings/index/page.js' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if @nonprofit && nonprofit_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<header class='header stripe--mosaic'>
|
||||
<div class='container--mid'>
|
||||
<i class='header-icon icon-setting-gear'></i>
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
<%= stylesheet_link_tag 'tickets/index/page' %>
|
||||
<% end %>
|
||||
|
||||
<%= render '/components/trial_bar' if QueryBillingSubscriptions.currently_in_trial?(@nonprofit.id) %>
|
||||
|
||||
<header class='header'>
|
||||
<div class='container'>
|
||||
<i class='icon-check-list header-icon'></i>
|
||||
|
|
|
@ -38,9 +38,6 @@ const view = state =>
|
|||
h('div.u-centered.u-maxWidth--600.u-margin--auto.u-marginTop--50.u-padding--15.js-view-confirm', [
|
||||
h('h4', `Payment Method for ${app.nonprofit.name}`)
|
||||
, state.card.name ? h('p', `Current card: ${state.card.name}`) : ''
|
||||
, h('p', [
|
||||
state.subscription.status === 'trialing' ? `You have ${state.daysLeft} days left in your free trial. If you add a payment method now, your account will stay active after your trial, and you will get your remaining trial days for free.` : ''
|
||||
])
|
||||
, h('p.u-strong', `Tier: ${state.plan.name} ($${format.centsToDollars(state.plan.amount)} ${state.plan.interval})`)
|
||||
, h('hr')
|
||||
, h('h5', 'Update Your Card:')
|
||||
|
|
|
@ -8,11 +8,9 @@ module ConstructBillingSubscription
|
|||
def self.with_stripe(np, billing_plan)
|
||||
raise ArgumentError, 'Billing plan not found' if billing_plan.nil?
|
||||
|
||||
trial_end = QueryBillingSubscriptions.currently_in_trial?(np.id) ? (np.created_at + 15.days).to_i : nil
|
||||
customer = Stripe::Customer.retrieve np.active_card.stripe_customer_id
|
||||
stripe_subscription = customer.subscriptions.create(
|
||||
plan: billing_plan.stripe_plan_id,
|
||||
trial_end: trial_end
|
||||
plan: billing_plan.stripe_plan_id
|
||||
)
|
||||
{
|
||||
billing_plan_id: billing_plan.id,
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||
require 'qx'
|
||||
require 'delayed_job_helper'
|
||||
require 'active_support/core_ext'
|
||||
|
||||
module InsertBillingSubscriptions
|
||||
def self.trial(np_id, stripe_plan_id)
|
||||
nonprofit = Nonprofit.includes(:billing_subscription).find(np_id)
|
||||
billing_plan = BillingPlan.where('stripe_plan_id = ?', stripe_plan_id).last
|
||||
sub = nonprofit.create_billing_subscription(billing_plan: billing_plan, status: 'trialing')
|
||||
n = 10
|
||||
DelayedJobHelper.enqueue_job(self, :check_trial, [sub['id']], run_at: n.days.from_now)
|
||||
{ json: sub }
|
||||
rescue ActiveRecord::RecordNotFound => e
|
||||
{ json: { error: e }, status: :unprocessable_entity }
|
||||
end
|
||||
|
||||
def self.check_trial(bs_id)
|
||||
sub = Qx.fetch(:billing_subscriptions, bs_id).last
|
||||
if sub['status'] == 'trialing'
|
||||
Qx.update(:billing_subscriptions)
|
||||
.set(status: 'inactive')
|
||||
.timestamps
|
||||
.where('id = $id', id: bs_id)
|
||||
.execute
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,22 +5,10 @@ require 'qx'
|
|||
require 'active_support/core_ext'
|
||||
|
||||
module QueryBillingSubscriptions
|
||||
def self.days_left_in_trial(np_id)
|
||||
sub = Qx.fetch(:billing_subscriptions, nonprofit_id: np_id).last
|
||||
return 0 if sub.nil?
|
||||
|
||||
sub['status'] == 'trialing' ? (((sub['created_at'] + 10.days) - Time.current) / 86_400).floor : 0
|
||||
end
|
||||
|
||||
def self.plan_tier(np_id)
|
||||
sub = Qx.fetch(:billing_subscriptions, nonprofit_id: np_id).last
|
||||
return 2 if sub && sub['status'] != 'inactive'
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
def self.currently_in_trial?(np_id)
|
||||
sub = Qx.fetch(:billing_subscriptions, nonprofit_id: np_id).last
|
||||
sub && sub['status'] == 'trialing'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||
|
||||
module UpdateBillingSubscriptions
|
||||
def self.activate_from_trial(np_id)
|
||||
Qx.update(:billing_subscriptions)
|
||||
.set(status: 'active')
|
||||
.timestamps
|
||||
.where('nonprofit_id=$id', id: np_id)
|
||||
.execute
|
||||
end
|
||||
end
|
|
@ -7,9 +7,6 @@ require 'controllers/support/shared_user_context'
|
|||
describe BillingSubscriptionsController, type: :controller do
|
||||
describe 'authorization' do
|
||||
include_context :shared_user_context
|
||||
describe 'create_trial' do
|
||||
include_context :open_to_np_admin, :post, :create_trial, nonprofit_id: :__our_np
|
||||
end
|
||||
|
||||
describe 'create' do
|
||||
include_context :open_to_np_admin, :post, :create, nonprofit_id: :__our_np
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||
require 'rails_helper'
|
||||
|
||||
describe InsertBillingSubscriptions, skip: true do
|
||||
let(:sub) do
|
||||
# billing_plan = Qx.insert_into(:billing_plans).values({name: 'test_bp', amount: 0, stripe_plan_id: 'stripe_bp', created_at: Time.current, updated_at: Time.current}).returning('*').execute.last
|
||||
# InsertBillingSubscriptions.trial(3624, billing_plan['stripe_plan_id'])[:json]
|
||||
end
|
||||
|
||||
describe '.trial' do
|
||||
it 'creates the record' do
|
||||
sub
|
||||
expect(sub['id']).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
describe '.check_trial' do
|
||||
it 'marks as inactive after 10 days' do
|
||||
sub
|
||||
Timecop.freeze(10.days.from_now) { InsertBillingSubscriptions.check_trial(sub['id']) }
|
||||
updated = Qx.fetch(:billing_subscriptions, sub['id']).last
|
||||
expect(updated['status']).to eq('inactive')
|
||||
end
|
||||
|
||||
it 'does not change the status if not still trialing after 10 days' do
|
||||
sub
|
||||
Qx.update(:billing_subscriptions).set(status: 'active').where('id = $id', id: sub['id']).execute
|
||||
Timecop.freeze(10.days.from_now) { InsertBillingSubscriptions.check_trial(sub['id']) }
|
||||
updated = Qx.fetch(:billing_subscriptions, sub['id']).last
|
||||
expect(updated['status']).to eq('active')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,36 +7,9 @@ require 'query/query_billing_subscriptions'
|
|||
|
||||
describe QueryBillingSubscriptions, pending: true do
|
||||
before(:each) do
|
||||
# Qx.delete_from(:billing_plans).where("stripe_plan_id = $id", id: 'stripe_bp').execute
|
||||
# Qx.delete_from(:billing_subscriptions).where("nonprofit_id = $id", id: 3624).execute
|
||||
# @billing_plan = Qx.insert_into(:billing_plans).values({name: 'test_bp', amount: 0, stripe_plan_id: 'stripe_bp', created_at: Time.current, updated_at: Time.current}).returning('*').execute.last
|
||||
# @sub = InsertBillingSubscriptions.trial(3624, @billing_plan['stripe_plan_id'])[:json]
|
||||
end
|
||||
|
||||
describe '.days_left_in_trial' do
|
||||
it 'gives days left in trial, rounded down' do
|
||||
expect(QueryBillingSubscriptions.days_left_in_trial(3624)).to eq(9)
|
||||
raise
|
||||
end
|
||||
|
||||
it 'gives 0 if not trialing' do
|
||||
Qx.update(:billing_subscriptions).set(status: 'active').where('id = $id', id: @sub['id']).execute
|
||||
expect(QueryBillingSubscriptions.days_left_in_trial(3624)).to eq(0)
|
||||
raise
|
||||
end
|
||||
|
||||
it 'gives negative if past expiration' do
|
||||
Qx.update(:billing_subscriptions).set(status: 'trialing', created_at: 20.days.ago).where('id = $id', id: @sub['id']).execute
|
||||
expect(QueryBillingSubscriptions.days_left_in_trial(3624)).to eq(-11)
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
describe '.plan_tier' do
|
||||
it 'gives tier 2 if status=trialing' do
|
||||
Qx.update(:billing_subscriptions).set(status: 'trialing').where('id = $id', id: @sub['id']).execute
|
||||
expect(QueryBillingSubscriptions.plan_tier(3624)).to eq(2)
|
||||
end
|
||||
it 'gives tier 0 if status=inactive' do
|
||||
Qx.update(:billing_subscriptions).set(status: 'inactive').where('id = $id', id: @sub['id']).execute
|
||||
expect(QueryBillingSubscriptions.plan_tier(3624)).to eq(0)
|
||||
|
@ -52,23 +25,4 @@ describe QueryBillingSubscriptions, pending: true do
|
|||
raise
|
||||
end
|
||||
end
|
||||
|
||||
describe '.currently_in_trial?' do
|
||||
it 'gives true if status=trialing' do
|
||||
Qx.update(:billing_subscriptions).set(status: 'trialing').where('id = $id', id: @sub['id']).execute
|
||||
expect(QueryBillingSubscriptions.currently_in_trial?(3624)).to eq(true)
|
||||
raise
|
||||
end
|
||||
|
||||
it 'gives false if status!=trialing' do
|
||||
Qx.update(:billing_subscriptions).set(status: 'active').where('id = $id', id: @sub['id']).execute
|
||||
expect(QueryBillingSubscriptions.currently_in_trial?(3624)).to eq(false)
|
||||
raise
|
||||
end
|
||||
|
||||
it 'gives false if no subscription' do
|
||||
expect(QueryBillingSubscriptions.currently_in_trial?(666)).to be_falsey
|
||||
raise
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue