diff --git a/admin/app/admin/jam_ruby_users.rb b/admin/app/admin/jam_ruby_users.rb index fff7b460d..58dbe92f1 100644 --- a/admin/app/admin/jam_ruby_users.rb +++ b/admin/app/admin/jam_ruby_users.rb @@ -74,6 +74,12 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do redirect_to :back, {notice: "Check the Subscription Plan Code, Subscription Sync Code, Subscription Sync Msg"} end + member_action :reset_monthly_play, :method => :get do + resource.used_month_play_time = 0 + resource.save! + redirect_to :back, {notice: "Reset user's monthly play time to 0"} + end + member_action :change_to_plan, :method => :get do @client = RecurlyClient.new plan_code = params[:plan_code] @@ -128,6 +134,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do row :gender row :email_confirmed row :remember_token +=begin row "Session Ready" do |user| div do if user.ready_for_session_at @@ -154,6 +161,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do end end end +=end row "Delete Forever" do |user| span do link_to("delete forever", delete_forever_admin_user_path(user.id), :data => {:confirm => 'Are you sure?'}) @@ -201,6 +209,24 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do row :subscription_sync_msg row :is_past_due row :stored_credit_card + row "Monthly Time Used" do |user| + div do + remaining_month_play_time = user.subscription_rules[:remaining_month_play_time] + if remaining_month_play_time.nil? + span do + "No limit" + end + elsif user.played_this_month? + span do + "Used: #{user.used_month_play_time / 60} min | Remaining #{remaining_month_play_time / 60} min" + end + else + span do + "Did not play this month. Last played #{user.used_current_month}" + end + end + end + end end end div do @@ -225,9 +251,19 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do '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_user_override_path(user.id)) + link_to("give no-payment plan", edit_admin_user_override_path(user.id)) + end + end + div do + h3 do + 'Reset Monthly Play Time' + end + h4 do + 'sets the user\'s monthly play time to 0' + end + div do + link_to("reset monthly play time", reset_monthly_play_admin_user_path(user.id), :data => {:confirm => 'Are you sure?'}) end - end div do h3 do @@ -331,6 +367,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do end end +=begin panel "Teacher Setting" do attributes_table do @@ -396,6 +433,8 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do end +=end + panel "JamTracks" do div do link_to "Give JamTrack", "../jam_track_rights/new" diff --git a/ruby/lib/jam_ruby/connection_manager.rb b/ruby/lib/jam_ruby/connection_manager.rb index 183f4a5ff..4ae6e9311 100644 --- a/ruby/lib/jam_ruby/connection_manager.rb +++ b/ruby/lib/jam_ruby/connection_manager.rb @@ -181,6 +181,16 @@ SQL clients end + # deletes any connections in active music sessions older than 2 days. + def cleanup_dangling + + ConnectionManager.active_record_transaction do |connection_manager, conn| + sql = "update connections set music_session_id = null where id in (select id from connections where music_session_id in (select id from active_music_sessions where updated_at::date < (current_date - 2)))" + conn.exec(sql) do |result| + end + end + + end # returns the number of connections that this user currently has across all clients # this number is used by notification logic elsewhere to know diff --git a/ruby/lib/jam_ruby/models/music_session_user_history.rb b/ruby/lib/jam_ruby/models/music_session_user_history.rb index 7e35f39d5..3836b4231 100644 --- a/ruby/lib/jam_ruby/models/music_session_user_history.rb +++ b/ruby/lib/jam_ruby/models/music_session_user_history.rb @@ -98,7 +98,7 @@ module JamRuby # update the users monthly play time def update_remaining_play_time now = Time.now - current_month = (now.year * 100 + now.month) + current_month = User.current_month remaining_time_so_far = self.user.used_month_play_time.to_i if current_month != self.user.used_current_month @@ -117,7 +117,7 @@ module JamRuby # we use the database to get all other connections that occurred while their this user was connected, # and then sort through them using custom logic to increase/decrease the count as people come and go def determine_max_concurrent - overlapping_connections = MusicSessionUserHistory.where("music_session_id = ? AND + overlapping_connections = MusicSessionUserHistory.where("music_session_id = ? AND ((created_at >= ? AND (session_removed_at is NULL OR session_removed_at <= ?)) OR (created_at <= ? AND (session_removed_at is NULL OR session_removed_at >= ?)))", self.music_session_id, self.created_at, self.session_removed_at, self.created_at, self.created_at).select('id, created_at, session_removed_at').order(:created_at) diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index ee73d9bbe..5cf5b4f4b 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -2879,12 +2879,11 @@ module JamRuby if play_time_per_month.nil? rules[:remaining_month_play_time] = nil else - now = Time.now - if used_current_month != (now.year * 100 + now.month) + if played_this_month? + rules[:remaining_month_play_time] = (play_time_per_month * 3600) - self.used_month_play_time.to_i + else # if this is a new month, then they get full play time rules[:remaining_month_play_time] = (play_time_per_month * 3600) - else - rules[:remaining_month_play_time] = (play_time_per_month * 3600) - self.used_month_play_time.to_i end end end @@ -2892,6 +2891,15 @@ module JamRuby rules end + def self.current_month + now = Time.now + (now.year * 100 + now.month) + end + + def played_this_month? + used_current_month == User.current_month + end + def update_admin_override_plan_code(plan_code) self.admin_override_plan_code = plan_code self.subscription_plan_code = plan_code diff --git a/ruby/lib/jam_ruby/recurly_client.rb b/ruby/lib/jam_ruby/recurly_client.rb index c37cf21cd..507c127e9 100644 --- a/ruby/lib/jam_ruby/recurly_client.rb +++ b/ruby/lib/jam_ruby/recurly_client.rb @@ -64,6 +64,11 @@ module JamRuby if subscription puts "Canceling user's #{current_user.email} subscription" subscription.cancel + # upon cancelation, take the user's current monthly payment plan + subscription = Recurly::Subscription.find(subscription.uuid) + current_user.subscription_plan_code = get_highest_plan(subscription) + current_user.subscription_plan_code_set_at = DateTime.now + current_user.save(validate: false) # do not delete the recurly_subscription_id ; we'll use that to try and reactivate later if they user re-activates their account else # if no subscription and past trial, you goin down -- because there must have never been payment?? @@ -323,12 +328,24 @@ module JamRuby raise RecurlyClientError.new(plan.errors) if plan.errors.any? end + def get_pending_plan_code(subscription) + if subscription && subscription.pending_subscription + return subscription.pending_subscription.plan.plan_code + else + return nil + end + end + + def get_highest_plan(subscription) + SubscriptionDefinitions.higher_plan(subscription.plan.plan_code, get_pending_plan_code(subscription)) + end + def handle_create_subscription(current_user, plan_code, account) begin subscription = create_subscription(current_user, plan_code, account, current_user.subscription_trial_ended? ? nil : current_user.subscription_trial_ends_at) current_user.recurly_subscription_id = subscription.uuid if current_user.subscription_trial_ended? - current_user.subscription_plan_code = plan_code + current_user.subscription_plan_code = get_highest_plan(subscription) current_user.subscription_plan_code_set_at = DateTime.now else # we could force a platinum plan since the user has put forward payment already, even in trial @@ -364,13 +381,14 @@ module JamRuby begin old_subscription.reactivate puts "reactivated plan! Let's check if it needs changing" - if plan_code != old_subscription.plan.plan_code + #if plan_code != old_subscription.plan.plan_code result = old_subscription.update_attributes( :plan_code => plan_code, :timeframe => starts_at.nil? ? 'bill_date' : 'now' ) - end - return old_subscription + # end + # fetch it again. because it's got staleness after update_attributes operation + return Recurly::Subscription.find(old_subscription_id) rescue => e puts "Unable to reactivate/update old plan #{e}" user.update_attribute(:recurly_subscription_id, nil) diff --git a/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb b/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb index 6efbe7d50..94a42af21 100644 --- a/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb +++ b/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb @@ -12,6 +12,7 @@ module JamRuby #LessonSession.hourly_check #TeacherPayment.hourly_check User.hourly_check + ConnectionManager.new.cleanup_dangling @@log.info("done") end diff --git a/ruby/lib/jam_ruby/subscription_definitions.rb b/ruby/lib/jam_ruby/subscription_definitions.rb index 500b4ee39..00be941e2 100644 --- a/ruby/lib/jam_ruby/subscription_definitions.rb +++ b/ruby/lib/jam_ruby/subscription_definitions.rb @@ -117,5 +117,22 @@ module JamRuby next_plan_rank < current_plan_rank end + + def self.higher_plan(plan_a, plan_b) + if plan_a.nil? + plan_b + elsif plan_b.nil? + plan_a + else + plan_a_rank = rules(plan_a)[:rank] + plan_b_rank = rules(plan_b)[:rank] + # if plan a is higher, take plan_a + if plan_a_rank > plan_b_rank + plan_a + else + plan_b + end + end + end end end diff --git a/ruby/spec/jam_ruby/connection_manager_spec.rb b/ruby/spec/jam_ruby/connection_manager_spec.rb index 117995963..0fe4584db 100644 --- a/ruby/spec/jam_ruby/connection_manager_spec.rb +++ b/ruby/spec/jam_ruby/connection_manager_spec.rb @@ -11,7 +11,7 @@ describe ConnectionManager, no_transaction: true do GATEWAY = 'gateway1' REACHABLE = true - let(:channel_id) {'1'} + let(:channel_id) { '1' } before do @conn = PG::Connection.new(:dbname => SpecDb::TEST_DB_NAME, :user => "postgres", :password => "postgres", :host => "localhost") @@ -42,6 +42,32 @@ describe ConnectionManager, no_transaction: true do end end + + describe "cleanup_dangling" do + + it "success" do + @connman.cleanup_dangling + + client_id = "client_id9" + user_id = create_user("test", "user9", "user9@jamkazam.com") + music_session = FactoryGirl.create(:active_music_session, user_id: user_id) + music_session_id = music_session.id + user = User.find(user_id) + + @connman.create_connection(user_id, client_id, channel_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME, REACHABLE, GATEWAY, false) + connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS, 10) + + Connection.where('music_session_id is not null').count.should == 1 + @connman.cleanup_dangling + Connection.where('music_session_id is not null').count.should == 1 + # well in the past + music_session.update_attribute("updated_at", '2020-01-01 00:00:00') + @connman.cleanup_dangling + Connection.where('music_session_id is not null').count.should == 0 + end + + end + it "can't create two client_ids of same value" do client_id = "client_id1" user_id = create_user("test", "user1", "user1@jamkazam.com") @@ -263,7 +289,7 @@ describe ConnectionManager, no_transaction: true do user_id = create_user("test", "user8", "user8@jamkazam.com") @connman.create_connection(user_id, client_id, channel_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME, REACHABLE, GATEWAY, false) - num = JamRuby::Connection.where('aasm_state = ?','connected').count + num = JamRuby::Connection.where('aasm_state = ?', 'connected').count num.should == 1 assert_num_connections(client_id, num) @connman.flag_stale_connections(GATEWAY) @@ -346,7 +372,6 @@ describe ConnectionManager, no_transaction: true do end - it "join_music_session fails if no connection" do client_id = "client_id10" @@ -429,7 +454,7 @@ describe ConnectionManager, no_transaction: true do @connman.create_connection(user_id, client_id, channel_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME, REACHABLE, GATEWAY, false) # specify real user id, but not associated with this session - expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS, 10) } .to raise_error(JamRuby::JamPermissionError) + expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS, 10) }.to raise_error(JamRuby::JamPermissionError) end it "join_music_session fails if no music_session" do @@ -455,7 +480,7 @@ describe ConnectionManager, no_transaction: true do @connman.create_connection(user_id, client_id, channel_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME, REACHABLE, GATEWAY, false) # specify real user id, but not associated with this session - expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS, 10) } .to raise_error(JamRuby::JamPermissionError) + expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS, 10) }.to raise_error(JamRuby::JamPermissionError) end diff --git a/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee b/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee index ff8fe5184..c6ca70a68 100644 --- a/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/CurrentSubscription.js.jsx.coffee @@ -205,6 +205,9 @@ AppStore = context.AppStore displayTime: (until_time) -> + if until_time < 0 + return 'no time' + untilTime = @getTimeRemaining(until_time * 1000) timeString = '' @@ -213,9 +216,9 @@ AppStore = context.AppStore if untilTime.hours != 0 || timeString.length > 0 timeString += "#{untilTime.hours} hours, " if untilTime.minutes != 0 || timeString.length > 0 - timeString += "#{untilTime.minutes} minutes, " - if untilTime.seconds != 0 || timeString.length > 0 - timeString += "#{untilTime.seconds} seconds" + timeString += "#{untilTime.minutes} minutes " + #if untilTime.seconds != 0 || timeString.length > 0 + # timeString += "#{untilTime.seconds} seconds" if timeString == '' 'now!' @@ -295,15 +298,18 @@ AppStore = context.AppStore explanation = `You have successfully upgraded your plan to the {desired_plan_name} level, thank you` warning = `
However, you must provide a payment method (e.g. a credit card), for the monthly subscription charge. Please click the Update Payment Method button to do this now.
` else - explanation = `You have successfully upgraded your plan to the {desired_plan_name} level, thank you!` + explanation = `You are currently on the {effective_plan_name} level, thank you!` else # free plan situation - not much to go on about - explanation = `You are currently on the {desired_plan_name} plan.` + explanation = `You are currently on the {effective_plan_name} plan.` if show_payment_info update_payment_btn = `UPDATE PAYMENT METHOD` if has_pending_subscription - billingAddendum = null #`You have {this.displayTime(remaining_month_play_time)} time remaining this month. Only the time you spend in a session with 2 or more people uses your session play time.
+You have {this.displayTime(remaining_month_play_time)} remaining this month. Only the time you spend in a session with 2 or more people uses your session play time.