diff --git a/admin/app/admin/jam_class_knobs.rb b/admin/app/admin/jam_class_knobs.rb
new file mode 100644
index 000000000..f27e3f0e0
--- /dev/null
+++ b/admin/app/admin/jam_class_knobs.rb
@@ -0,0 +1,14 @@
+ActiveAdmin.register_page "Jam Class Knobs" do
+ menu :parent => 'JamClass'
+
+ page_action :force_hourly, :method => :post do
+
+ Resque.enqueue(HourlyJob)
+ redirect_to admin_jam_class_knobs_path, :notice => "Re-running the Hourly Job. Lessons will be analysed; any payments will be attempted that should be, etc"
+ end
+
+
+ action_item do
+ link_to "Force Hourly Background Job", admin_jam_class_knobs_force_hourly_path, :method => :post
+ end
+end
\ No newline at end of file
diff --git a/admin/app/admin/lesson_session.rb b/admin/app/admin/lesson_session.rb
index 914174408..58ebe2d68 100644
--- a/admin/app/admin/lesson_session.rb
+++ b/admin/app/admin/lesson_session.rb
@@ -28,7 +28,11 @@ ActiveAdmin.register JamRuby::LessonSession, :as => 'LessonSessions' do
end
column "Start Time" do |lesson_session|
span do
- lesson_session.music_session.pretty_scheduled_start(true)
+ if lesson_session.music_session.nil?
+ raise "Lessonsesison with no id #{lesson_session.id}"
+ else
+ lesson_session.music_session.pretty_scheduled_start(true)
+ end
end
br
span do
@@ -92,6 +96,11 @@ ActiveAdmin.register JamRuby::LessonSession, :as => 'LessonSessions' do
lesson_session.sent_notices
end
end
+ row "Success" do |lesson_session|
+ span do
+ lesson_session.success
+ end
+ end
row "Billed" do |lesson_session|
span do
lesson_session.billed
diff --git a/ruby/lib/jam_ruby/models/chat_message.rb b/ruby/lib/jam_ruby/models/chat_message.rb
index 60ef217c7..bcd75fb5a 100644
--- a/ruby/lib/jam_ruby/models/chat_message.rb
+++ b/ruby/lib/jam_ruby/models/chat_message.rb
@@ -105,7 +105,6 @@ module JamRuby
lesson_session_id = lesson_session.id if lesson_session
if music_notation
- puts "IS MUSIC NOTATION"
attachment_id = music_notation.id
attachment_type = music_notation.attachment_type
attachment_name = music_notation.file_name
@@ -115,8 +114,6 @@ module JamRuby
attachment_name = claimed_recording.name
end
- puts "ATTACMENT #{}"
-
msg = @@message_factory.chat_message(
music_session_id,
diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb
index 8e70af29e..a41f248bc 100644
--- a/ruby/lib/jam_ruby/models/lesson_session.rb
+++ b/ruby/lib/jam_ruby/models/lesson_session.rb
@@ -116,16 +116,15 @@ module JamRuby
end
def self.analyse_sessions
- MusicSession.joins(lesson_session: :lesson_booking).where('lesson_sessions.status = ?', LessonSession::STATUS_APPROVED).where("session_removed_at IS NOT NULL OR NOW() > scheduled_start + (INTERVAL '1 minutes' * duration)").where('analysed = false').each do |music_session|
+ MusicSession.joins(lesson_session: :lesson_booking).where('lesson_sessions.status = ?', LessonSession::STATUS_APPROVED).where("NOW() > scheduled_start + (INTERVAL '1 minutes' * (3 + duration))").where('analysed = false').each do |music_session|
lession_session = music_session.lesson_session
- @@log.debug("analysis lesson session #{lession_session.id}")
lession_session.analyse
end
end
def self.complete_sessions
# this will find any paid session (recurring monthly paid, recurring single paid, single paid)
- MusicSession.joins(lesson_session: [:lesson_booking, :lesson_payment_charge]).where('lesson_sessions.status = ?', LessonSession::STATUS_COMPLETED).where("session_removed_at IS NOT NULL OR NOW() > scheduled_start + (INTERVAL '1 minutes' * duration)").where('analysed = true').where('lesson_sessions.post_processed = false').where('billing_should_retry = true').each do |music_session|
+ MusicSession.joins(lesson_session: [:lesson_booking, :lesson_payment_charge]).where('lesson_sessions.status = ?', LessonSession::STATUS_COMPLETED).where("NOW() > scheduled_start + (INTERVAL '1 minutes' * (3 + duration))").where('analysed = true').where('lesson_sessions.post_processed = false').where('billing_should_retry = true').each do |music_session|
lession_session = music_session.lesson_session
lession_session.session_completed
end
diff --git a/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee b/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee
index cccbe2b29..379cb69a1 100644
--- a/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee
@@ -43,6 +43,14 @@ context = window
timeString
render: () ->
+ if @props.lessonSession.isStudent
+ role = 'student'
+ otherRole = 'teacher'
+ billingStatement = 'charged for the lesson'
+ else
+ role = 'teacher'
+ otherRole = 'student'
+ billingStatement = 'not receive payment for the lesson'
if @props.lessonSession.completed
if @props.lessonSession.success
content = `
@@ -61,18 +69,19 @@ context = window
content = `
You need to wait in this session for
{this.displayTime()}
-
to allow time for your teacher to join you. If you leave before this timer reaches zero, and your teacher joins this session, you will be marked absent and charged for the lesson.
+
to allow time for your {otherRole} to join you. If you leave before this timer reaches zero, and your {otherRole} joins this session, you will be marked absent and {billingStatement}.
`
else if @props.lessonSession.teacherFault
- if @props.lessonSession.teacherPresent?
+ if @props.lessonSession.isStudent
content = `
-
Because your teacher was late, you may now leave the session. However, if you choose to stay in the session with the teacher, after 5 minutes together the session will be considered a success, and you will be billed.
-
If the two of you do not spend at least 5 minutes together in the session, your teacher will be marked absent and penalized for missing the lesson, and you will not be charged for this lesson.
+
You may now leave the session.
+
Your teacher will be marked absent and penalized for missing the lesson. You will not be charged for this lesson.
+
We apologize for your inconvenience, and we will work to remedy this situation.
`
else
content = `
You may now leave the session.
-
Your teacher will be marked absent and penalized for missing the lesson. You will not be charged for this lesson.
+
Your student will be marked absent and penalized for missing the lesson. You will still received payment for this lesson.
We apologize for your inconvenience, and we will work to remedy this situation.
`
diff --git a/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
index 99f1ac078..8e733943d 100644
--- a/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
@@ -105,13 +105,13 @@ LessonTimerActions = context.LessonTimerActions
title: 'Start Time Set',
text: "Start time for session set to 5 mins from now"
})))
- else if data.lessonAction == 'start-35-ago'
+ else if data.lessonAction == 'start-65-ago'
rest.lessonStartTime({
id: lessonId,
- minutes: -35
+ minutes: -65
}).done((response) => (@app.layout.notify({
title: 'Start Time Set',
- text: "Start time for session set to 35 mins ago"
+ text: "Start time for session set to 65 mins ago"
})))
else if data.lessonAction == 'enter-payment'
window.location.href = "/client#/jamclass/lesson-payment/lesson-booking_#{lessonId}"
diff --git a/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee b/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee
index 49fcfab49..a744c9cea 100644
--- a/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee
@@ -177,7 +177,7 @@
:
- * Time will be local to {context.JK.currentTimezone()}
+ * Time will be local to {window.JK.currentTimezone()}
{errorText}
@@ -199,7 +199,7 @@
:
- *Time will be local to {context.JK.currentTimezone()}
+ *Time will be local to {window.JK.currentTimezone()}
{errorText}
`
diff --git a/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee
index 904b517c0..5e336f9be 100644
--- a/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee
@@ -38,7 +38,7 @@ ProfileActions = @ProfileActions
afterShow: (e) ->
UserActions.refresh()
-
+
#@setState(TeacherSearchStore.getState())
#if @state.results.length == 0
# don't issue a new search every time someone comes to the screen, to preserve location from previous browsing
diff --git a/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee b/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee
index 53dacfdf9..1d5968687 100644
--- a/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee
+++ b/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee
@@ -93,7 +93,7 @@ BroadcastStore = Reflux.createStore(
@session = session
currentSession = session.session
- if currentSession? && currentSession.lesson_session? && session.inSession() && currentSession.lesson_session.student_id == context.JK.currentUserId
+ if currentSession? && currentSession.lesson_session? && session.inSession()
@currentSession = currentSession
@@ -137,9 +137,13 @@ BroadcastStore = Reflux.createStore(
changed: () ->
if @currentLesson?
+ @currentLesson.isStudent == @currentLesson.student_id == context.JK.currentUserId
+ @currentLesson.isTeacher = !@currentLesson.isStudent
@currentLesson.teacherFault = @teacherFault
@currentLesson.teacherPresent = @session.findParticipantByUserId(@currentLesson.teacher_id)
- if @currentLesson.teacherPresent?
+ @currentLesson.studentPresent = @session.findParticipantByUserId(@currentLesson.student_id)
+ if (@currentLesson.teacherPresent? && @currentLesson.isStudent) || (@currentLesson.studentPresent? && @currentLesson.isTeacher)
+ # don't show anything if the other person is there
this.trigger(null)
else
this.trigger(@currentLesson)
diff --git a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee
index bd2447424..95ffeb0b5 100644
--- a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee
+++ b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee
@@ -774,7 +774,6 @@ ConfigureTracksActions = @ConfigureTracksActions
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.TRACKS_CHANGED, @trackChanges);
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.HEARTBEAT_ACK, @trackChanges);
- console.log("SESSION STARTED EVENT")
$(document).trigger(EVENTS.SESSION_STARTED, {session: {id: @currentSessionId, lesson_session: response.lesson_session}}) if document
@handleAutoOpenJamTrack()
diff --git a/web/app/views/clients/_lessonSessionActions.html.slim b/web/app/views/clients/_lessonSessionActions.html.slim
index c42b76c35..9e0a4fc18 100644
--- a/web/app/views/clients/_lessonSessionActions.html.slim
+++ b/web/app/views/clients/_lessonSessionActions.html.slim
@@ -64,8 +64,8 @@ script type='text/template' id='template-lesson-session-actions'
= '{% if (data.isAdmin) { %}'
li data-lesson-option="start-5-min"
a href='#' Set Start In 5 Min
- li data-lesson-option="start-35-ago"
- a href='#' Set Start 35 Min Ago
+ li data-lesson-option="start-65-ago"
+ a href='#' Set Start 65 Min Ago
= '{% } %}'
= '{% } else { %}'
diff --git a/web/lib/tasks/lesson.rake b/web/lib/tasks/lesson.rake
index a2963c3ab..99fdd999f 100644
--- a/web/lib/tasks/lesson.rake
+++ b/web/lib/tasks/lesson.rake
@@ -1,10 +1,39 @@
require 'factory_girl'
+require 'timecop'
+require 'rspec-rails'
+require Rails.root.join('spec', 'support', 'lessons.rb')
namespace :lessons do
+ task book_completed: :environment do |task, args|
+
+ user = User.find_by_email(ENV['STUDENT'])
+ teacher = User.find_by_email(ENV['TEACHER'])
+ recurring = ENV['RECURRING'] == '1'
+ slots = []
+ Timecop.travel(Date.today - 5)
+ slots << FactoryGirl.build(:lesson_booking_slot_single, preferred_day: Date.today - 3, timezone: 'America/Chicago')
+ slots << FactoryGirl.build(:lesson_booking_slot_single, preferred_day: Date.today - 4, timezone: 'America/Chicago')
+ if recurring
+ payment_style = LessonBooking::PAYMENT_STYLE_MONTHLY
+ else
+ payment_style = LessonBooking::PAYMENT_STYLE_SINGLE
+ end
+
+ lesson = normal_lesson(user, teacher, {accept: true, finish: true, student_show:true, no_validate: true})
+
+
+ if lesson.errors.any?
+ puts lesson.errors.inspect
+ raise "lesson failed"
+ end
+ lesson = booking.lesson_sessions[0]
+
+ puts "http://localhost:3000/client#/jamclass/lesson-booking/#{lesson.id}"
+ end
task book_normal: :environment do |task, args|
- user = User.find_by_email(ENV['STUDENT_EMAIL'])
- teacher = User.find_by_email(ENV['TEACHER_EMAIL'])
+ user = User.find_by_email(ENV['STUDENT'])
+ teacher = User.find_by_email(ENV['TEACHER'])
recurring = ENV['RECURRING'] == '1'
slots = []
@@ -71,7 +100,7 @@ namespace :lessons do
lesson = booking.lesson_sessions[0]
if user.most_recent_test_drive_purchase.nil?
- LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
+ LessonPackagePurchase.create(user, lesson.booking, LessonPackageType.test_drive_4)
end
#lesson.accept({message: 'Yeah I got this', slot: slots[0]})
@@ -80,6 +109,6 @@ namespace :lessons do
#lesson.slot.should eql slots[0]
#lesson.status.should eql LessonSession::STATUS_APPROVED
- puts "http://localhost:3000/client#/jamclass/lesson-booking/#{booking.id}"
+ puts "http://localhost:3000/client#/jamclass/lesson-booking/#{lesson.booking.id}"
end
end
diff --git a/web/spec/support/lessons.rb b/web/spec/support/lessons.rb
index 3fed2208e..533ee3055 100644
--- a/web/spec/support/lessons.rb
+++ b/web/spec/support/lessons.rb
@@ -89,157 +89,122 @@ end
-def testdrive_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil, package_count: 4})
+def book_lesson(user, teacher, options)
if options[:package_count].nil?
options[:package_count] = 4
end
+
if options[:slots].nil?
- slots = []
- slots << FactoryGirl.build(:lesson_booking_slot_single)
- slots << FactoryGirl.build(:lesson_booking_slot_single)
+ slots = []
+ if options[:monthly]
+ slots << FactoryGirl.build(:lesson_booking_slot_recurring)
+ slots << FactoryGirl.build(:lesson_booking_slot_recurring)
+ else
+ slots << FactoryGirl.build(:lesson_booking_slot_single)
+ slots << FactoryGirl.build(:lesson_booking_slot_single)
+ end
+
else
slots = options[:slots]
end
-
if user.stored_credit_card == false
- user.stored_credit_card = true
- user.save!
+ token = create_stripe_token
+ result = user.payment_update({token: token, zip: '78759', normal: true})
+ #user.stored_credit_card = true
+ #user.save!
end
- booking = LessonBooking.book_test_drive(user, teacher, slots, "Hey I've heard of you before.")
+ if options[:test_drive]
+ booking = LessonBooking.book_test_drive(user, teacher, slots, "Hey I've heard of you before.")
+ elsif options[:normal]
+ booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
+ elsif options[:monthly]
+ booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
+ end
if booking.errors.any?
puts "BOOKING #{booking.errors.inspect}"
+
+ if booking.lesson_booking_slots[0].errors.any?
+ puts "SLOT0 #{booking.lesson_booking_slots[0].errors.inspect}"
+ end
end
- booking.errors.any?.should be_false
+
+ booking.errors.any?.should be_false unless options[:no_validate]
+
lesson = booking.lesson_sessions[0]
start = lesson.scheduled_start
end_time = lesson.scheduled_start + (60 * lesson.duration)
- booking.card_presumed_ok.should be_true
+ booking.card_presumed_ok.should be_true unless options[:no_validate]
- if user.most_recent_test_drive_purchase.nil?
- LessonPackagePurchase.create(user, booking, LessonPackageType.package_for_test_drive_count(options[:package_count]))
+ if options[:test_drive]
+ if user.most_recent_test_drive_purchase.nil?
+ LessonPackagePurchase.create(user, booking, LessonPackageType.package_for_test_drive_count(options[:package_count]))
+ end
end
+
if options[:accept]
lesson.accept({message: 'Yeah I got this', slot: slots[0]})
- lesson.errors.any?.should be_false
+ lesson.errors.any?.should be_false unless options[:no_validate]
lesson.reload
- lesson.slot.should eql slots[0]
- lesson.status.should eql LessonSession::STATUS_APPROVED
+ lesson.slot.should eql slots[0] unless options[:no_validate]
+ lesson.status.should eql LessonSession::STATUS_APPROVED unless options[:no_validate]
end
if options[:cancel]
lesson.cancel({canceler: options[:canceler] || user, message: "sorry about that"})
lesson.reload
- lesson.status.should eql LessonSession::STATUS_CANCELED
+ lesson.status.should eql LessonSession::STATUS_CANCELED unless options[:no_validate]
end
if options[:miss]
- # teacher & student get into session
+ Timecop.travel(end_time + 1)
+
- Timecop.travel(end_time + 1)
- lesson.analyse
- lesson.session_completed
- elsif options[:teacher_miss]
- uh2 = FactoryGirl.create(:music_session_user_history, user: user, history: lesson.music_session, created_at: start, session_removed_at: end_time)
- # artificially end the session, which is covered by other background jobs
- lesson.music_session.session_removed_at = end_time
- lesson.music_session.save!
- Timecop.travel(end_time + 1)
- lesson.analyse
- lesson.session_completed
- elsif options[:success]
- uh1 = FactoryGirl.create(:music_session_user_history, user: user, history: lesson.music_session, created_at: start, session_removed_at: end_time)
- uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: lesson.music_session, created_at: start, session_removed_at: end_time)
- # artificially end the session, which is covered by other background jobs
- lesson.music_session.session_removed_at = end_time
- lesson.music_session.save!
- Timecop.travel(end_time + 1)
lesson.analyse
lesson.session_completed
+
elsif options[:finish]
# teacher & student get into session
uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: lesson.music_session, created_at: start, session_removed_at: end_time)
+ if options[:student_show]
+ uh2 = FactoryGirl.create(:music_session_user_history, user: user, history: lesson.music_session, created_at: start, session_removed_at: end_time)
+ end
# artificially end the session, which is covered by other background jobs
lesson.music_session.session_removed_at = end_time
lesson.music_session.save!
+
Timecop.travel(end_time + 1)
+
+
lesson.analyse
lesson.session_completed
+
+ if options[:monthly]
+ LessonBooking.hourly_check
+ end
end
lesson
end
-
-
-def normal_lesson(user, teacher, slots = nil)
-
- if slots.nil?
- slots = []
- slots << FactoryGirl.build(:lesson_booking_slot_single)
- slots << FactoryGirl.build(:lesson_booking_slot_single)
- end
-
- if user.stored_credit_card == false
- user.stored_credit_card = true
- user.save!
- end
-
- booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
- # puts "NORMAL BOOKING #{booking.errors.inspect}"
- booking.errors.any?.should be_false
- lesson = booking.lesson_sessions[0]
- booking.card_presumed_ok.should be_true
-
- #if user.most_recent_test_drive_purchase.nil?
- # LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
- #end
-
- lesson.accept({message: 'Yeah I got this', slot: slots[0]})
- lesson.errors.any?.should be_false
- lesson.reload
- lesson.slot.should eql slots[0]
- lesson.status.should eql LessonSession::STATUS_APPROVED
- lesson.music_session.should_not be_nil
-
- lesson
+def testdrive_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil})
+ options[:test_drive] = true
+ book_lesson(user, teacher, options)
end
-def monthly_lesson(user, teacher, slots = nil)
-
- if slots.nil?
- slots = []
- slots << FactoryGirl.build(:lesson_booking_slot_recurring)
- slots << FactoryGirl.build(:lesson_booking_slot_recurring)
- end
-
- if user.stored_credit_card == false
- user.stored_credit_card = true
- user.save!
- end
-
- booking = LessonBooking.book_normal(user, teacher, slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60)
- # puts "NORMAL BOOKING #{booking.errors.inspect}"
- booking.errors.any?.should be_false
- lesson = booking.lesson_sessions[0]
- booking.card_presumed_ok.should be_true
-
- #if user.most_recent_test_drive_purchase.nil?
- # LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
- #end
-
- lesson.accept({message: 'Yeah I got this', slot: slots[0]})
- lesson.errors.any?.should be_false
- lesson.reload
- lesson.slot.should eql slots[0]
- lesson.status.should eql LessonSession::STATUS_APPROVED
- lesson.music_session.should_not be_nil
-
- lesson
+def normal_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil})
+ options[:normal] = true
+ book_lesson(user, teacher, options)
end
+
+
+def monthly_lesson(user, teacher, options = {finish: false, accept: true, cancel: false, miss: false, slots: nil})
+ options[:monthly] = true
+ book_lesson(user, teacher, options)
+end
\ No newline at end of file