diff --git a/ruby/lib/jam_ruby/models/lesson_booking.rb b/ruby/lib/jam_ruby/models/lesson_booking.rb index ba0b86176..5a844cf9b 100644 --- a/ruby/lib/jam_ruby/models/lesson_booking.rb +++ b/ruby/lib/jam_ruby/models/lesson_booking.rb @@ -187,6 +187,7 @@ module JamRuby scheduled_lessons(times) end + # sensitive to current time def predicted_times_for_month(year, month) first_day = Date.new(year, month, 1) last_day = Date.new(year, month, -1) @@ -201,9 +202,18 @@ module JamRuby start_day = first_day if last_session - start_day = last_session.scheduled_start.day + start_day = last_session.scheduled_start.to_date + 1 end + # now flesh out the rest of the month with predicted times + + more_times = default_slot.scheduled_times(5, start_day) + + more_times.each do |time| + if time.to_date >= first_day && time.to_date <= last_day + times << time + end + end times end @@ -496,5 +506,9 @@ module JamRuby def web_url APP_CONFIG.external_root_url + "/client#/jamclass/lesson-request/" + id end + + def admin_url + APP_CONFIG.admin_root_url + "/admin/lesson_bookings/" + id + end end end diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb index 2fd144fd4..d1e1d7388 100644 --- a/ruby/lib/jam_ruby/models/lesson_session.rb +++ b/ruby/lib/jam_ruby/models/lesson_session.rb @@ -583,5 +583,9 @@ module JamRuby def update_payment_url APP_CONFIG.external_root_url + "/client#/jamclass/update-payment" end + + def admin_url + APP_CONFIG.admin_root_url + "/admin/lesson_sessions/" + id + end end end diff --git a/ruby/lib/jam_ruby/models/lesson_session_monthly_price.rb b/ruby/lib/jam_ruby/models/lesson_session_monthly_price.rb index 0c33ef324..068721a2b 100644 --- a/ruby/lib/jam_ruby/models/lesson_session_monthly_price.rb +++ b/ruby/lib/jam_ruby/models/lesson_session_monthly_price.rb @@ -2,11 +2,26 @@ module JamRuby class LessonSessionMonthlyPrice # calculate the price for a given month - def price(lesson_booking, start_day) + def self.price(lesson_booking, start_day) - lesson_booking.default_slot.scheduled_times + raise "lesson_booking is not monthly paid #{lesson_booking.admin_url}" if !lesson_booking.is_monthly_payment? - lesson_booking.lesson + times = lesson_booking.predicted_times_for_month(start_day.year, start_day.month) + + result = nil + if times.length == 0 + result = 0 + elsif times.length == 1 + result = (lesson_booking.booked_price * 0.25).round(2) + elsif times.length == 2 + result = (lesson_booking.booked_price * 0.50).round(2) + elsif times.length == 3 + result = (lesson_booking.booked_price * 0.75).round(2) + else + result = lesson_booking.booked_price + end + + result end end end diff --git a/ruby/spec/jam_ruby/models/lesson_booking_spec.rb b/ruby/spec/jam_ruby/models/lesson_booking_spec.rb index 3e271c862..bfa5a06b9 100644 --- a/ruby/spec/jam_ruby/models/lesson_booking_spec.rb +++ b/ruby/spec/jam_ruby/models/lesson_booking_spec.rb @@ -13,6 +13,67 @@ describe LessonBooking do let(:valid_single_slots) {[lesson_booking_slot_single1, lesson_booking_slot_single2]} let(:valid_recurring_slots) {[lesson_booking_slot_recurring1, lesson_booking_slot_recurring2]} + describe "predicted_times_for_month" do + after do + Timecop.return + end + it "fills up month" do + + next_year = Time.now.year + 1 + jan1 = Date.new(next_year, 1, 1) + jan31 = Date.new(next_year, 1, -1) + Timecop.freeze(jan1) + slot = valid_recurring_slots[0] + slot.day_of_week = jan1.wday + + booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60) + times = booking.predicted_times_for_month(next_year, 1) + times.length.should eql 5 + times[0].to_date.should eql (jan1) + times[1].to_date.should eql (Date.new(next_year, 1, 8)) + times[2].to_date.should eql (Date.new(next_year, 1, 15)) + times[3].to_date.should eql (Date.new(next_year, 1, 22)) + times[4].to_date.should eql (Date.new(next_year, 1, 29)) + end + + it "fills up partial month" do + next_year = Time.now.year + 1 + jan1 = Date.new(next_year, 1, 1) + jan15 = Date.new(next_year, 1, 15) + jan31 = Date.new(next_year, 1, -1) + Timecop.freeze(jan15) + slot = valid_recurring_slots[0] + slot.day_of_week = jan1.wday + + booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60) + times = booking.predicted_times_for_month(next_year, 1) + times.length.should eql 3 + times[0].to_date.should eql (Date.new(next_year, 1, 15)) + times[1].to_date.should eql (Date.new(next_year, 1, 22)) + times[2].to_date.should eql (Date.new(next_year, 1, 29)) + end + + it "let's assume JamKazam is messed up for a few weeks" do + next_year = Time.now.year + 1 + jan1 = Date.new(next_year, 1, 1) + jan15 = Date.new(next_year, 1, 15) + jan31 = Date.new(next_year, 1, -1) + Timecop.freeze(jan1) + slot = valid_recurring_slots[0] + slot.day_of_week = jan1.wday + + # book a session on jan1 + booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_WEEKLY, 60) + + # but don't run the computation of times per month for weeks + Timecop.freeze(Date.new(next_year, 1, 23)) + times = booking.predicted_times_for_month(next_year, 1) + times.length.should eql 2 + times[0].to_date.should eql (Date.new(next_year, 1, 1)) + times[1].to_date.should eql (Date.new(next_year, 1, 29)) + end + end + describe "book_free" do it "works" do diff --git a/ruby/spec/jam_ruby/models/lesson_session_monthly_price_spec.rb b/ruby/spec/jam_ruby/models/lesson_session_monthly_price_spec.rb new file mode 100644 index 000000000..caa69ff30 --- /dev/null +++ b/ruby/spec/jam_ruby/models/lesson_session_monthly_price_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +describe LessonSessionMonthlyPrice do + + let(:user) { FactoryGirl.create(:user) } + let(:teacher) { FactoryGirl.create(:teacher_user) } + let(:start) { Time.now } + let(:lesson_booking_slot_single1) { FactoryGirl.build(:lesson_booking_slot_single) } + let(:lesson_booking_slot_single2) { FactoryGirl.build(:lesson_booking_slot_single) } + let(:lesson_booking_slot_recurring1) { FactoryGirl.build(:lesson_booking_slot_recurring) } + let(:lesson_booking_slot_recurring2) { FactoryGirl.build(:lesson_booking_slot_recurring) } + let(:valid_single_slots) { [lesson_booking_slot_single1, lesson_booking_slot_single2] } + let(:valid_recurring_slots) { [lesson_booking_slot_recurring1, lesson_booking_slot_recurring2] } + + describe "price" do + after do + Timecop.return + end + + it "start of the month" do + + jan1 = Date.new(2016, 1, 1) + Timecop.freeze(jan1) + + booking = LessonBooking.book_normal(user, teacher, valid_recurring_slots, "Monthly time!", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60) + + booking.booked_price.should eql 30.00 + + booking.booked_price.should eql(LessonSessionMonthlyPrice.price(booking, jan1)) + end + + it "middle of the month" do + + jan17 = Date.new(2016, 1, 17) + Timecop.freeze(jan17) + + booking = LessonBooking.book_normal(user, teacher, valid_recurring_slots, "Monthly time!", true, LessonBooking::PAYMENT_STYLE_MONTHLY, 60) + + booking.booked_price.should eql 30.00 + + ((booking.booked_price * 0.50).round(2)).should eql(LessonSessionMonthlyPrice.price(booking, jan17)) + end + end +end