lesson fixes

This commit is contained in:
Seth Call 2016-05-26 18:10:05 -05:00
parent cc3576f70f
commit ea049068e0
13 changed files with 151 additions and 126 deletions

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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 = `<div className="message">
@ -61,18 +69,19 @@ context = window
content = `<div className="message">
<p>You need to wait in this session for</p>
<p className="time">{this.displayTime()}</p>
<p>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.</p>
<p>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}.</p>
</div>`
else if @props.lessonSession.teacherFault
if @props.lessonSession.teacherPresent?
if @props.lessonSession.isStudent
content = `<div className="message">
<p>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.</p>
<p>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.</p>
<p>You may now leave the session.</p>
<p>Your teacher will be marked absent and penalized for missing the lesson. You will not be charged for this lesson.</p>
<p>We apologize for your inconvenience, and we will work to remedy this situation.</p>
</div>`
else
content = `<div className="message">
<p>You may now leave the session.</p>
<p>Your teacher will be marked absent and penalized for missing the lesson. You will not be charged for this lesson.</p>
<p>Your student will be marked absent and penalized for missing the lesson. You will still received payment for this lesson.</p>
<p>We apologize for your inconvenience, and we will work to remedy this situation.</p>
</div>`

View File

@ -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}"

View File

@ -177,7 +177,7 @@
<select className="hour">{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
<select className="am_pm">{this.am_pm}</select>
<br/>
<span>* Time will be local to {context.JK.currentTimezone()}</span>
<span>* Time will be local to {window.JK.currentTimezone()}</span>
{errorText}
</span>
@ -199,7 +199,7 @@
<select className="hour">{this.hours}</select> : <select disabled={this.props.disabled} className="minute">{this.minutes}</select>
<select disabled={this.props.disabled} className="am_pm">{this.am_pm}</select>
<br/>
<span>*Time will be local to {context.JK.currentTimezone()}</span>
<span>*Time will be local to {window.JK.currentTimezone()}</span>
{errorText}
</span>
</div>`

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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 { %}'

View File

@ -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

View File

@ -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