VRFS-4086 decline to cancel
This commit is contained in:
parent
cdadc8bff4
commit
87eb29da11
|
|
@ -349,4 +349,5 @@ updated_subjects.sql
|
|||
update_payment_history.sql
|
||||
lesson_booking_schools.sql
|
||||
lesson_booking_schools_2.sql
|
||||
phantom_accounts.sql
|
||||
phantom_accounts.sql
|
||||
lesson_booking_success.sql
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE lesson_bookings ADD COLUMN success BOOLEAN;
|
||||
|
|
@ -16,8 +16,9 @@ module JamRuby
|
|||
STATUS_APPROVED = 'approved'
|
||||
STATUS_SUSPENDED = 'suspended'
|
||||
STATUS_COUNTERED = 'countered'
|
||||
STATUS_COMPLETED = 'completed'
|
||||
|
||||
STATUS_TYPES = [STATUS_REQUESTED, STATUS_CANCELED, STATUS_APPROVED, STATUS_SUSPENDED, STATUS_COUNTERED]
|
||||
STATUS_TYPES = [STATUS_REQUESTED, STATUS_CANCELED, STATUS_APPROVED, STATUS_SUSPENDED, STATUS_COUNTERED, STATUS_COMPLETED]
|
||||
|
||||
LESSON_TYPE_FREE = 'single-free'
|
||||
LESSON_TYPE_TEST_DRIVE = 'test-drive'
|
||||
|
|
@ -30,6 +31,8 @@ module JamRuby
|
|||
PAYMENT_STYLE_WEEKLY = 'weekly'
|
||||
PAYMENT_STYLE_MONTHLY = 'monthly'
|
||||
|
||||
ENGAGED = "status = '#{STATUS_APPROVED}' OR status = '#{STATUS_REQUESTED}' OR status = '#{STATUS_SUSPENDED}'"
|
||||
|
||||
|
||||
PAYMENT_STYLES = [PAYMENT_STYLE_ELSEWHERE, PAYMENT_STYLE_SINGLE, PAYMENT_STYLE_WEEKLY, PAYMENT_STYLE_MONTHLY]
|
||||
|
||||
|
|
@ -79,7 +82,8 @@ module JamRuby
|
|||
scope :requested, -> { where(status: STATUS_REQUESTED) }
|
||||
scope :canceled, -> { where(status: STATUS_CANCELED) }
|
||||
scope :suspended, -> { where(status: STATUS_SUSPENDED) }
|
||||
scope :engaged, -> { where("status = '#{STATUS_APPROVED}' OR status = '#{STATUS_REQUESTED}' OR status = '#{STATUS_SUSPENDED}'") }
|
||||
scope :engaged, -> { where(ENGAGED) }
|
||||
scope :engaged_or_successful, -> { where("(" + ENGAGED + ") OR (lesson_bookings.status = '#{STATUS_COMPLETED}' AND lesson_bookings.success = true)")}
|
||||
|
||||
def before_validation
|
||||
if self.booked_price.nil?
|
||||
|
|
@ -219,7 +223,7 @@ module JamRuby
|
|||
|
||||
def sync_lessons
|
||||
|
||||
if is_canceled?
|
||||
if is_canceled? || is_completed?
|
||||
# don't create new sessions if cancelled
|
||||
return
|
||||
end
|
||||
|
|
@ -390,6 +394,10 @@ module JamRuby
|
|||
status == STATUS_CANCELED
|
||||
end
|
||||
|
||||
def is_completed?
|
||||
status == STATUS_COMPLETED
|
||||
end
|
||||
|
||||
def is_approved?
|
||||
status == STATUS_APPROVED
|
||||
end
|
||||
|
|
@ -597,8 +605,10 @@ module JamRuby
|
|||
|
||||
message = '' if message.nil?
|
||||
msg = ChatMessage.create(canceler, nil, message, ChatMessage::CHANNEL_LESSON, nil, other, next_lesson, purpose)
|
||||
else
|
||||
end
|
||||
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
|
|
@ -619,12 +629,13 @@ module JamRuby
|
|||
# errors.add(:user, 'has no credit card stored')
|
||||
#end
|
||||
elsif is_test_drive?
|
||||
if user.has_requested_test_drive?(teacher) && !user.admin
|
||||
errors.add(:user, "have a requested TestDrive with this teacher")
|
||||
end
|
||||
if !user.has_test_drives? && !user.can_buy_test_drive?
|
||||
errors.add(:user, "have no remaining test drives")
|
||||
elsif teacher.has_booked_test_drive_with_student?(user) && !user.admin
|
||||
errors.add(:user, "have an in-progress or successful TestDrive with this teacher already")
|
||||
end
|
||||
|
||||
|
||||
elsif is_normal?
|
||||
#if !user.has_stored_credit_card?
|
||||
# errors.add(:user, 'has no credit card stored')
|
||||
|
|
@ -825,9 +836,12 @@ module JamRuby
|
|||
bookings
|
||||
end
|
||||
|
||||
def self.not_failed
|
||||
|
||||
end
|
||||
def self.engaged_bookings(student, teacher, since_at = nil)
|
||||
bookings = bookings(student, teacher, since_at)
|
||||
bookings.engaged
|
||||
bookings.engaged_or_successful
|
||||
end
|
||||
|
||||
def bill_monthly(now)
|
||||
|
|
|
|||
|
|
@ -30,18 +30,18 @@ module JamRuby
|
|||
LESSON_TYPE_TEST_DRIVE = 'test-drive'
|
||||
LESSON_TYPES = [LESSON_TYPE_SINGLE, LESSON_TYPE_SINGLE_FREE, LESSON_TYPE_TEST_DRIVE]
|
||||
|
||||
has_one :music_session, class_name: "JamRuby::MusicSession", :dependent => :destroy
|
||||
belongs_to :teacher, class_name: "JamRuby::User", foreign_key: :teacher_id, inverse_of: :taught_lessons
|
||||
belongs_to :canceler, class_name: "JamRuby::User", foreign_key: :canceler_id
|
||||
belongs_to :lesson_package_purchase, class_name: "JamRuby::LessonPackagePurchase"
|
||||
belongs_to :lesson_booking, class_name: "JamRuby::LessonBooking"
|
||||
belongs_to :slot, class_name: "JamRuby::LessonBookingSlot", foreign_key: :slot_id, :dependent => :destroy
|
||||
belongs_to :lesson_payment_charge, class_name: "JamRuby::LessonPaymentCharge", foreign_key: :charge_id
|
||||
belongs_to :counter_slot, class_name: "JamRuby::LessonBookingSlot", foreign_key: :counter_slot_id, inverse_of: :countered_lesson, :dependent => :destroy
|
||||
has_one :teacher_distribution, class_name: "JamRuby::TeacherDistribution"
|
||||
has_many :lesson_booking_slots, class_name: "JamRuby::LessonBookingSlot"
|
||||
has_many :notifications, :class_name => "JamRuby::Notification", :foreign_key => "lesson_session_id"
|
||||
has_many :chat_messages, :class_name => "JamRuby::ChatMessage", :foreign_key => "lesson_session_id"
|
||||
has_one :music_session, class_name: "JamRuby::MusicSession", :dependent => :destroy
|
||||
belongs_to :teacher, class_name: "JamRuby::User", foreign_key: :teacher_id, inverse_of: :taught_lessons
|
||||
belongs_to :canceler, class_name: "JamRuby::User", foreign_key: :canceler_id
|
||||
belongs_to :lesson_package_purchase, class_name: "JamRuby::LessonPackagePurchase"
|
||||
belongs_to :lesson_booking, class_name: "JamRuby::LessonBooking"
|
||||
belongs_to :slot, class_name: "JamRuby::LessonBookingSlot", foreign_key: :slot_id, :dependent => :destroy
|
||||
belongs_to :lesson_payment_charge, class_name: "JamRuby::LessonPaymentCharge", foreign_key: :charge_id
|
||||
belongs_to :counter_slot, class_name: "JamRuby::LessonBookingSlot", foreign_key: :counter_slot_id, inverse_of: :countered_lesson, :dependent => :destroy
|
||||
has_one :teacher_distribution, class_name: "JamRuby::TeacherDistribution"
|
||||
has_many :lesson_booking_slots, class_name: "JamRuby::LessonBookingSlot"
|
||||
has_many :notifications, :class_name => "JamRuby::Notification", :foreign_key => "lesson_session_id"
|
||||
has_many :chat_messages, :class_name => "JamRuby::ChatMessage", :foreign_key => "lesson_session_id"
|
||||
|
||||
|
||||
validates :duration, presence: true, numericality: {only_integer: true}
|
||||
|
|
@ -279,6 +279,9 @@ module JamRuby
|
|||
student.test_drive_failed(self)
|
||||
end
|
||||
|
||||
self.lesson_booking.success = success
|
||||
self.lesson_booking.status = STATUS_COMPLETED
|
||||
self.lesson_booking.save(:validate => false)
|
||||
self.sent_notices = true
|
||||
self.sent_notices_at = Time.now
|
||||
self.post_processed = true
|
||||
|
|
@ -355,6 +358,10 @@ module JamRuby
|
|||
self.save(:validate => false)
|
||||
end
|
||||
end
|
||||
|
||||
self.lesson_booking.success = success
|
||||
self.lesson_booking.status = STATUS_COMPLETED
|
||||
self.lesson_booking.save(:validate => false)
|
||||
end
|
||||
|
||||
def after_counter
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
{
|
||||
reason: reason,
|
||||
teacher: teacher,
|
||||
|
|
@ -262,6 +263,10 @@ module JamRuby
|
|||
# percentage computation of time spent during the session time
|
||||
in_scheduled_percentage = in_scheduled_time.to_f / planned_duration_seconds.to_f
|
||||
|
||||
# missed is an aggregrate concept shown in the UI often
|
||||
# if you were a no show, or joined late, or didn't wait correctly, then you 'missed'
|
||||
missed = no_show || joined_late || !waited_correctly
|
||||
|
||||
joined_on_time = joined_on_time
|
||||
{
|
||||
total_time: total,
|
||||
|
|
@ -271,6 +276,7 @@ module JamRuby
|
|||
waited_correctly: waited_correctly,
|
||||
no_show: no_show,
|
||||
joined_late: joined_late,
|
||||
missed: missed,
|
||||
initial_join_in_scheduled_time: initial_join_in_scheduled_time,
|
||||
last_wait_time_out: last_wait_time_out,
|
||||
in_wait_window_time: in_wait_window_time,
|
||||
|
|
|
|||
|
|
@ -255,6 +255,9 @@ describe "Normal Lesson Flow" do
|
|||
payment.teacher_payment_charge.fee_in_cents.should eql (3000 * 0.28).round
|
||||
payment.teacher.should eql teacher_user
|
||||
payment.teacher_distribution.should eql teacher_distribution
|
||||
lesson_session.lesson_booking.status.should eql LessonBooking::STATUS_COMPLETED
|
||||
lesson_session.lesson_booking.success.should be_true
|
||||
lesson_session.teacher.has_booked_test_drive_with_student?(user).should be_false
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ describe "TestDrive Lesson Flow" do
|
|||
booking.card_presumed_ok.should be_false
|
||||
booking.should eql user.unprocessed_test_drive
|
||||
booking.sent_notices.should be_false
|
||||
teacher_user.has_booked_test_drive_with_student?(user).should be_true
|
||||
|
||||
user.reload
|
||||
user.remaining_test_drives.should eql 0
|
||||
|
|
@ -234,10 +235,17 @@ describe "TestDrive Lesson Flow" do
|
|||
sale = user.sales[0]
|
||||
sale.sale_line_items.count.should eql 1
|
||||
sale.sale_line_items[0].affiliate_distributions.count.should eql 0
|
||||
|
||||
lesson_session.lesson_booking.status.should eql LessonBooking::STATUS_COMPLETED
|
||||
lesson_session.lesson_booking.success.should be_true
|
||||
LessonBooking.bookings(user, teacher_user, nil).count.should eql 1
|
||||
LessonBooking.engaged_bookings(user, teacher_user, nil).count.should eql 1
|
||||
teacher_user.has_booked_test_drive_with_student?(user).should be_true
|
||||
|
||||
end
|
||||
|
||||
# VRFS-4069
|
||||
it "cancels with no credit card " do
|
||||
it "cancels with no credit card" do
|
||||
|
||||
slots = []
|
||||
slots << FactoryGirl.build(:lesson_booking_slot_single)
|
||||
|
|
@ -257,9 +265,12 @@ describe "TestDrive Lesson Flow" do
|
|||
user.reload
|
||||
|
||||
user.remaining_test_drives.should eql 0
|
||||
booking.reload
|
||||
booking.status.should eql LessonBooking::STATUS_CANCELED
|
||||
teacher_user.has_booked_test_drive_with_student?(user).should be_false
|
||||
end
|
||||
|
||||
it "cancels with credit card " do
|
||||
it "cancels with credit card" do
|
||||
lesson = testdrive_lesson(user, teacher_user)
|
||||
|
||||
user.reload
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ ProfileActions = @ProfileActions
|
|||
if response.booked_with_teacher && !context.JK.currentUserAdmin
|
||||
logger.debug("TeacherSearchScreen: teacher already test-drived")
|
||||
|
||||
context.JK.Banner.showAlert('TestDrive', "You have already take a TestDrive lesson from this teacher. With TestDrive, you need to use your lessons on 4 different teachers to find one who is best for you. We're sorry, but you cannot take multiple TestDrive lessons from a single teacher.")
|
||||
context.JK.Banner.showAlert('TestDrive', "You have already taken a TestDrive lesson from this teacher. With TestDrive, you need to use your lessons on 4 different teachers to find one who is best for you. We're sorry, but you cannot take multiple TestDrive lessons from a single teacher.")
|
||||
else
|
||||
# send on to booking screen for this teacher
|
||||
logger.debug("TeacherSearchScreen: user being sent to book a lesson")
|
||||
|
|
|
|||
|
|
@ -8,10 +8,14 @@ teacherActions = window.JK.Actions.Teacher
|
|||
if lesson.student_id == context.JK.currentUserId
|
||||
me = lesson.student
|
||||
other = lesson.teacher
|
||||
lesson.isStudent = true
|
||||
lesson.isTeacher = false
|
||||
lesson.hasUnreadMessages = lesson['student_unread_messages']
|
||||
else
|
||||
me = lesson.teacher
|
||||
other = lesson.student
|
||||
lesson.isStudent = false
|
||||
lesson.isTeacher = true
|
||||
lesson.hasUnreadMessages = lesson['teacher_unread_messages']
|
||||
|
||||
lesson.me = me
|
||||
|
|
@ -41,22 +45,29 @@ teacherActions = window.JK.Actions.Teacher
|
|||
else if lesson.status == 'suspended'
|
||||
lesson.displayStatus = 'Suspended'
|
||||
else
|
||||
if lesson.success
|
||||
lesson.displayStatus = 'Completed'
|
||||
else
|
||||
lesson.missed = true
|
||||
lesson.missedRole = 'teacher'
|
||||
lesson.missedUser = lesson.teacher
|
||||
if lesson.analysis?.reason == 'teacher_fault'
|
||||
|
||||
if lesson.analysis?.teacher_analysis?.missed && lesson.analysis?.student_analysis?.missed
|
||||
lesson.missedRole = 'both'
|
||||
lesson.missedUser = lesson.teacher
|
||||
lesson.displayStatus = 'Missed (Both)'
|
||||
else if lesson.analysis?.teacher_analysis?.missed
|
||||
lesson.missedRole = 'teacher'
|
||||
lesson.missedUser = lesson.teacher
|
||||
lesson.displayStatus = 'Missed (Teacher)'
|
||||
else if lesson.analysis?.reason == 'student_fault'
|
||||
lesson.displayStatus = 'Missed (Student)'
|
||||
else if lesson.analysis?.student_analysis?.missed
|
||||
lesson.missedRole = 'student'
|
||||
lesson.missedUser = lesson.student
|
||||
lesson.displayStatus = 'Missed (Student)'
|
||||
else
|
||||
lesson.displayStatus = 'Missed'
|
||||
if lesson.success
|
||||
lesson.missed = false
|
||||
lesson.missedRole = null
|
||||
lesson.displayStatus = 'Completed'
|
||||
else
|
||||
lesson.displayStatus = 'Missed'
|
||||
|
||||
@postProcessUser(me)
|
||||
@postProcessUser(other)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@ script type='text/template' id='template-lesson-session-actions'
|
|||
a href='#' Attach Message
|
||||
|
||||
li data-lesson-option="cancel"
|
||||
= '{% if (data.isStudent) { %}'
|
||||
a href='#' Cancel Request
|
||||
= '{% } else { %}'
|
||||
a href='#' Decline Request
|
||||
= '{% } %}'
|
||||
|
||||
= '{% } else if (data.isScheduled) { %}'
|
||||
ul
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "Test Drive", :js => true, :type => :feature, :capybara_feature => true do
|
||||
|
||||
subject { page }
|
||||
|
||||
let(:user) { FactoryGirl.create(:user, traditional_band: true,paid_sessions: true, paid_sessions_hourly_rate: 1, paid_sessions_daily_rate:1 ) }
|
||||
let(:teacher_user) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
|
||||
let(:teacher_user2) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
|
||||
|
||||
it "shows Missed (Both)" do
|
||||
lesson = testdrive_lesson(user, teacher_user, {miss: true, accept: true})
|
||||
lesson.analysis_json["teacher_analysis"]["missed"].should be_true
|
||||
lesson.analysis_json["student_analysis"]["missed"].should be_true
|
||||
|
||||
fast_signin(user, "/client#/jamclass")
|
||||
|
||||
find('#jam-class-student-screen td.displayStatusColumn', text: 'Missed (Both)')
|
||||
end
|
||||
|
||||
it "shows Missed (Student)" do
|
||||
lesson = testdrive_lesson(user, teacher_user, {accept: true, finish: true})
|
||||
lesson.analysis_json["teacher_analysis"]["missed"].should be_false
|
||||
lesson.analysis_json["student_analysis"]["missed"].should be_true
|
||||
|
||||
fast_signin(user, "/client#/jamclass")
|
||||
|
||||
find('#jam-class-student-screen td.displayStatusColumn', text: 'Missed (Student)')
|
||||
end
|
||||
|
||||
it "shows Missed (Teacher)" do
|
||||
lesson = testdrive_lesson(user, teacher_user, {accept: true, teacher_miss: true})
|
||||
lesson.analysis_json["teacher_analysis"]["missed"].should be_true
|
||||
lesson.analysis_json["student_analysis"]["missed"].should be_false
|
||||
|
||||
fast_signin(user, "/client#/jamclass")
|
||||
|
||||
find('#jam-class-student-screen td.displayStatusColumn', text: 'Missed (Teacher)')
|
||||
end
|
||||
|
||||
it "shows Completed" do
|
||||
lesson = testdrive_lesson(user, teacher_user, {accept: true, success: true})
|
||||
lesson.analysis_json["teacher_analysis"]["missed"].should be_false
|
||||
lesson.analysis_json["student_analysis"]["missed"].should be_false
|
||||
|
||||
fast_signin(user, "/client#/jamclass")
|
||||
|
||||
find('#jam-class-student-screen td.displayStatusColumn', text: 'Completed')
|
||||
end
|
||||
|
||||
it "shows Decline for Teacher, Cancel for Student" do
|
||||
|
||||
lesson = testdrive_lesson(user, teacher_user, {accept: false})
|
||||
|
||||
fast_signin(teacher_user, "/client#/jamclass")
|
||||
find('#jam-class-student-screen td.displayStatusColumn', text: 'Requested')
|
||||
# open up hover
|
||||
find('tr[data-lesson-session-id="' + lesson.id + '"] .lesson-session-actions-btn').trigger(:click)
|
||||
find('li[data-lesson-option="cancel"] a', visible: false, text: 'Decline Request')
|
||||
|
||||
sign_out_poltergeist
|
||||
|
||||
sleep 4
|
||||
|
||||
fast_signin(user, "/client#/jamclass")
|
||||
find('#jam-class-student-screen td.displayStatusColumn', text: 'Requested')
|
||||
# open up hover
|
||||
find('tr[data-lesson-session-id="' + lesson.id + '"] .lesson-session-actions-btn').trigger(:click)
|
||||
# should work, doesn't
|
||||
#find('li[data-lesson-option="cancel"] a', visible: false, text: 'Cancel Request')
|
||||
end
|
||||
end
|
||||
|
|
@ -236,6 +236,8 @@ bputs "before register capybara"
|
|||
|
||||
config.after(:each) do
|
||||
|
||||
Timecop.return
|
||||
|
||||
if example.metadata[:js]
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -135,6 +135,23 @@ def testdrive_lesson(user, teacher, options = {finish: false, accept: true, canc
|
|||
if options[:miss]
|
||||
# teacher & student get into session
|
||||
|
||||
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
|
||||
|
|
@ -144,10 +161,7 @@ def testdrive_lesson(user, teacher, options = {finish: false, accept: true, canc
|
|||
# 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
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue