admin override

This commit is contained in:
Seth Call 2020-12-05 12:16:38 -06:00
parent 14a3851458
commit 01bf30b4ce
13 changed files with 135 additions and 39 deletions

View File

@ -71,7 +71,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
end
member_action :end_trial, :method => :get do
if DateTime.now - 2.days < resource.subscription_trial_ends_at
if Time.now - 2.days < resource.subscription_trial_ends_at
resource.subscription_trial_ends_at = 3.days.ago
resource.save!
redirect_to :back, {notice: "User's trial ended"}
@ -156,9 +156,10 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
row "Subscription" do |user|
div do
attributes_table do
row :desired_plan_code, 'hi'
row :subscription_plan_code
row :desired_plan_code
row :admin_override_plan_code
row :admin_override_ends_at
row :recurly_subscription_state
row :recurly_subscription_id
row :desired_plan_code_set_at
@ -175,7 +176,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
'DESIRED PLAN CODE = What plan the user has selected in the UI'
end
div do
'SUBSCIRPTION PLAN CODE = What plan the user actually has'
'SUBSCRIPTION PLAN CODE = What plan the user actually has'
end
div do
div do
@ -190,28 +191,19 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do
'Give Free Plan Actions'
end
h4 do
'sets secret override to give user a free plan'
'sets secret override to give user a free plan (link goes to another page)'
end
div do
link_to("Give No-Payment Plan", edit_admin_subscription_path(user.id))
end
link_to("give free silver plan", give_free_plan_admin_user_path(user.id, plan_code: 'jamsubsilver'), :data => {:confirm => 'Are you sure?'})
end
div do
link_to("give free gold plan", give_free_plan_admin_user_path(user.id, plan_code: 'jamsubgold'), :data => {:confirm => 'Are you sure?'})
end
div do
link_to("give free platinum plan", give_free_plan_admin_user_path(user.id, plan_code: 'jamsubplatinum'), :data => {:confirm => 'Are you sure?'})
end
div do
link_to("revoke free plan", revoke_free_plan_admin_user_path(user.id), :data => {:confirm => 'Are you sure?'})
end
end
div do
h3 do
'Change Plan Actions'
end
h4 do
'exactly as if the user did it in the UI'
'Change desired plan xactly as if the user did it on /client#/accounts/subscription'
end
div do
link_to("change plan to silver", change_to_plan_admin_user_path(user.id, 'jamsubsilver'), :data => {:confirm => 'Are you sure?'})

View File

@ -0,0 +1,26 @@
ActiveAdmin.register User, :as => 'Subscription' do
menu :label => 'Subscription', :parent => 'Users'
form title: 'Use This To Give a No-Payment Subscription' do |f|
inputs 'Details' do
input :admin_override_touch, :as => :hidden, value: 'true'
input :admin_override_reason, :as => :text
input :admin_override_plan_code, :as => :select, :collection => SubscriptionDefinitions::MONTHLY_PLANS + ['Remove Override']
input :admin_override_ends_at, as: :datepicker,
datepicker_options: {
min_date: Date.today,
max_date: "+10Y"
}
li "User has admin override set to #{f.object.admin_override_plan_code}. Lasts until #{f.object.admin_override_ends_at}" if !f.object.admin_override_plan_code.nil?
li "User does not have admin override. They are currently on the #{f.object.subscription_plan_code ? f.object.subscription_plan_code : 'Free'} plan" if f.object.admin_override_plan_code.nil?
end
panel 'Instructions' do
"If you select a plan, the user will have their current subscription (if any) cancelled and set to the new plan for free. If you instead select Remove Override, you can cancel the gifted plan and the user will be o normal free-tier user again."
end
para "Press cancel to return to the list without saving."
actions
end
end

View File

@ -1,7 +1,8 @@
class JamRuby::User
attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :teacher_attributes, :email_template, :is_platform_instructor # :invite_email
attr_accessible :admin, :raw_password, :musician, :can_invite, :photo_url, :session_settings, :confirm_url, :teacher_attributes, :email_template, :is_platform_instructor, :admin_override_plan_code, :admin_override_ends_at, :admin_override_touch, :admin_override_reason, as: :admin # :invite_email
attr_accessor :admin_override_touch
accepts_nested_attributes_for :teacher, allow_destroy: true
ransacker :jamuser_full_name, formatter: proc { |v| v.mb_chars.downcase.to_s } do |parent|
@ -10,6 +11,27 @@
[Arel::Nodes::SqlLiteral.new("' '"), User.arel_table[:first_name], User.arel_table[:last_name]])])
end
after_save :admin_override_handler_sync
before_validation do
if self.admin_override_plan_code == 'Remove Override'
puts "Remove override just means set it to free again. so set to nil"
self.admin_override_plan_code = nil
end
end
def admin_override_handler_sync
if admin_override_touch
self.admin_override_touch = false
@client = RecurlyClient.new
# first, when ever we admin code it, set them to free. This would cancel any existing plan. We don't want them geting charged in any scenario where we are doing this acitvity
puts "Setting desired plan to free. Potentially cancelling existing."
result, subscription, account = @client.update_desired_subscription(self, nil)
self.update_admin_override_plan_code(self.admin_override_plan_code)
end
end
def raw_password
''
end

View File

@ -99,6 +99,8 @@ ALTER TABLE users ADD COLUMN recurly_subscription_state VARCHAR(20) DEFAULT NULL
ALTER TABLE users ADD COLUMN subscription_plan_code VARCHAR(100) DEFAULT NULL;
ALTER TABLE users ADD COLUMN desired_plan_code VARCHAR(100) DEFAULT NULL;
ALTER TABLE users ADD COLUMN admin_override_plan_code VARCHAR(100) DEFAULT NULL;
ALTER TABLE users ADD COLUMN admin_override_ends_at DATE;
ALTER TABLE users ADD COLUMN admin_override_reason VARCHAR;
ALTER TABLE users ADD COLUMN desired_plan_code_set_at TIMESTAMP;
ALTER TABLE users ADD COLUMN subscription_plan_code_set_at TIMESTAMP;
ALTER TABLE users ADD COLUMN subscription_last_checked_at TIMESTAMP;
@ -111,8 +113,7 @@ ALTER TABLE users ADD COLUMN subscription_trial_ends_at TIMESTAMP NOT NULL DEFAU
ALTER TABLE users ADD COLUMN subscription_plan_reason varchar(20);
--UPDATE users set subscription_trial_ends_at = (CURRENT_TIMESTAMP + '30 days'::interval), subscription_plan_code = 'jamsubgold';
UPDATE users set subscription_trial_ends_at = '2021-01-01', subscription_plan_code = 'jamsubgold';
UPDATE users set subscription_plan_code = 'jamsubplatinum';
UPDATE users set subscription_trial_ends_at = '2021-01-01', subscription_plan_code = 'jamsubplatinum';
UPDATE users set stored_credit_card = true where recurly_code is not null;

View File

@ -398,7 +398,7 @@ module JamRuby
any = false
User
.where('subscription_last_checked_at is NULL OR users.subscription_last_checked_at < ?', 1.days.ago)
.where("recurly_subscription_id IS NOT NULL OR subscription_sync_code IS NULL or (subscription_sync_code not in ('trial_ended', 'no_recurly_account', 'admin_control', 'school_license', 'no_subscription_or_expired'))")
.where("recurly_subscription_id IS NOT NULL OR subscription_sync_code IS NULL or (subscription_sync_code not in ('trial_ended', 'no_recurly_account', 'school_license', 'no_subscription_or_expired'))")
.order('subscription_last_checked_at ASC NULLS FIRST, recurly_code ASC NULLS LAST')
.limit(1000)
.each do |user|
@ -411,7 +411,7 @@ module JamRuby
# for testing when no results
#any = true
sleep(20)
#sleep(20)
# eat up work to do for up to 30 minutes
break if !any || Time.now - 30.minutes > start
@ -2881,12 +2881,15 @@ module JamRuby
self.admin_override_plan_code = plan_code
self.subscription_plan_code = plan_code
self.subscription_plan_code_set_at = DateTime.now
if plan_code.nil?
self.admin_override_ends_at = nil
end
self.save(validate: false)
end
def subscription_trial_ended?
subscription_trial_ends_at.nil? || DateTime.now > subscription_trial_ends_at
subscription_trial_ends_at.nil? || Time.now > subscription_trial_ends_at
end
def recurly_link_to_account

View File

@ -463,14 +463,29 @@ module JamRuby
begin
# edge case: admin controlled
if user.admin_override_plan_code
puts "admin controlled plan #{user.email}"
user.subscription_plan_code = user.admin_override_plan_code
user.subscription_plan_code_set_at = DateTime.now
user.subscription_last_checked_at = DateTime.now
user.subscription_sync_code = 'admin_control'
user.subscription_sync_msg = "admin override - plan_code set to #{user.admin_override_plan_code}"
user.save(validate: false)
return
# check if it's expired first...
if Time.now > user.admin_override_ends_at.to_time
puts "admin control expired. clear override and set Free plan"
user.admin_override_plan_code = nil
# logic below will catch this
#user.subscription_plan_code = nil
user.admin_override_ends_at = nil
user.subscription_sync_code = 'undo_admin_control'
user.subscription_sync_msg = "admin control expired. clear override and set Free plan"
user.subscription_last_checked_at = Time.now
user.save(validate: false)
# don't return; let this fall through to next states
else
puts "admin controlled plan #{user.email}"
user.subscription_plan_code = user.admin_override_plan_code
user.subscription_plan_code_set_at = Time.now
user.subscription_last_checked_at = Time.now
user.subscription_sync_code = 'admin_control'
user.subscription_sync_msg = "admin override - plan_code set to #{user.admin_override_plan_code}"
user.save(validate: false)
return
end
end
# edge case: user is in a licensed school
@ -497,7 +512,7 @@ module JamRuby
end
# if the trial has ended, but it was within 2 days of ending the trial date, give the user some leeway
if user.subscription_trial_ended? && (user.subscription_trial_ends_at.nil? || (DateTime.now < ( user.subscription_trial_ends_at + 2.days )))
if user.subscription_trial_ended? && (!user.subscription_trial_ends_at.nil? && (Time.now < ( user.subscription_trial_ends_at + 2.days )))
puts "user recently ended trial; ignore them #{user.email}"
user.subscription_last_checked_at = DateTime.now
user.subscription_sync_code = 'trial_recently_ended'
@ -522,11 +537,12 @@ module JamRuby
account = get_account(user)
if account.nil?
puts "Account is nil? #{user.email}. Strange"
puts "Account is nil? #{user.email}. Strange. Could happen in some weird admin messing around scenarios"
user.subscription_last_checked_at = DateTime.now
user.save(validate: false)
user.subscription_sync_code = 'no_recurly_account'
user.subscription_sync_msg = "user has no recurly account - plan_code not altered"
user.save(validate: false)
return
end

View File

@ -17,6 +17,12 @@ module JamRuby
PLATINUM_PLAY_TIME_PER_SESSION = nil # unlimited
PLATINUM_PLAY_TIME_PER_MONTH = nil # unlimited
MONTHLY_PLANS = [
nil,
JAM_SILVER,
JAM_GOLD,
JAM_PLATINUM
]
FREE_PLAN = {
play_time_per_month: FREE_PLAY_TIME_PER_MONTH,

View File

@ -16,8 +16,8 @@ describe "User Subscriptions" do
user1.reload
user1.subscription_sync_code.should be_nil
user1.subscription_last_checked_at.should be_nil
user1.subscription_sync_code.should == 'trial_recently_ended'
user1.subscription_last_checked_at.should_not be_nil
end
it "user not in trial" do
@ -43,4 +43,34 @@ describe "User Subscriptions" do
user1.subscription_plan_code.should be_nil
end
it "revert admin user down" do
user1.subscription_plan_code = SubscriptionDefinitions::JAM_PLATINUM
user1.subscription_trial_ends_at = 1.days.ago
user1.admin_override_plan_code = SubscriptionDefinitions::JAM_PLATINUM
user1.admin_override_ends_at = 10.days.from_now
user1.save!
User.subscription_sync
user1.reload
user1.subscription_sync_code.should == "admin_control"
user1.subscription_last_checked_at.should_not be_nil
user1.subscription_plan_code.should == SubscriptionDefinitions::JAM_PLATINUM
user1.subscription_trial_ends_at = 3.days.ago
user1.admin_override_ends_at = 10.days.ago
user1.subscription_last_checked_at = 2.days.ago
user1.save!
User.subscription_sync
user1.reload
user1.subscription_sync_code.should == "trial_ended"
user1.subscription_last_checked_at.should_not be_nil
user1.subscription_plan_code.should be_nil
end
end

View File

@ -877,7 +877,7 @@
}
context.JK.alertSupportedNeeded = function(additionalContext) {
var $item = context.JK.Banner.showAlert(additionalContext + '<br/><br/>Please <a href="http://jamkazam.desk.com" rel="external">contact support</a>.');
var $item = context.JK.Banner.showAlert(additionalContext + '<br/><br/>Please <a href="https://jamkazam.freshdesk.com" rel="external">contact support</a>.');
context.JK.popExternalLinks($item);
return $item;
}

View File

@ -4,7 +4,7 @@
<p>Thank you for your interest in JamKazam. Depending on your specific interest, please use one of the following avenues to reach out to us. We look forward to hearing from you!</p>
<h2>Support</h2>
<p>For technical support and help using our products and services, please visit the <a rel="external" href="http://jamkazam.desk.com">JamKazam Support Center</a>.</p>
<p>For technical support and help using our products and services, please visit the <a rel="external" href="https://jamkazam.freshdesk.com">JamKazam Support Center</a>.</p>
<h2>Partnerships</h2>
<p>For partnering inquiries, please contact us at: <a rel="external" href="mailto:partners@jamkazam.com">partners@jamkazam.com</a>.</p>
<h2>Media</h2>

View File

@ -23,7 +23,7 @@
%textarea.txtComment{id: 'txtComment', rows: '2', placeholder: 'Enter a comment...'}
.buttons
.left
%a.button-orange{:href => 'http://jamkazam.desk.com', :rel => 'external', :target => '_blank'} HELP
%a.button-orange{:href => 'https://jamkazam.freshdesk.com', :rel => 'external', :target => '_blank'} HELP
.right
%a.button-grey{:id => 'btnCancel', 'layout-action' => 'close'} CANCEL
%a.button-orange{:id => 'btnCancelRsvp'} CANCEL RSVP

View File

@ -27,7 +27,7 @@
.buttons
.left
%a#btnHelp.button-grey{:href => 'http://jamkazam.desk.com', :rel => 'external', :target => '_blank'} HELP
%a#btnHelp.button-grey{:href => 'https://jamkazam.freshdesk.com', :rel => 'external', :target => '_blank'} HELP
.right
%a#btnCancel.button-grey{'layout-action' => 'close'} CANCEL
%a#btnSubmitRsvp.button-orange SUBMIT RSVP

View File

@ -16,7 +16,7 @@
%br/
%br/
.left
%a.button-orange{:href => 'http://jamkazam.desk.com/', :rel => 'external', :target => '_blank'} HELP
%a.button-orange{:href => 'https://jamkazam.freshdesk.com', :rel => 'external', :target => '_blank'} HELP
.right
%a.button-grey{:id => 'btnCancel', 'layout-action' => 'close'} CANCEL
%a.button-orange{:id => 'btnCancelSession'} CANCEL SESSION