diff --git a/admin/Rakefile b/admin/Rakefile index 3065cf5e9..d88365d80 100644 --- a/admin/Rakefile +++ b/admin/Rakefile @@ -1,3 +1,4 @@ + #!/usr/bin/env rake # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. diff --git a/admin/app/admin/user_source.rb b/admin/app/admin/user_source.rb new file mode 100644 index 000000000..3e6c6556d --- /dev/null +++ b/admin/app/admin/user_source.rb @@ -0,0 +1,32 @@ +ActiveAdmin.register JamRuby::User, :as => 'UserSource' do + + menu :label => 'User Campaigns', :parent => 'Users' + + config.sort_order = 'created_at DESC' + config.batch_actions = false + config.clear_action_items! + config.filters = false + + scope("Most Recent First", default: true) { |scope| scope.unscoped.order('created_at desc')} + + index do + column "Email" do |user| + user.email + end + column "Bought TestDrive" do |user| + !user.most_recent_test_drive_purchase.nil? ? "Yes" : "No" + end + column "UTM Source" do |user| + user.origin_utm_source + end + column "UTM Medium" do |user| + user.origin_utm_medium + end + column "UTM Campaign" do |user| + user.origin_utm_campaign + end + column "Referrer" do |user| + user.origin_referrer + end + end +end diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index bd5742c36..2ee1f29a7 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -297,7 +297,10 @@ require "jam_ruby/models/affiliate_distribution" require "jam_ruby/models/teacher_intent" require "jam_ruby/models/school" require "jam_ruby/models/school_invitation" - +require "jam_ruby/models/teacher_instrument" +require "jam_ruby/models/teacher_subject" +require "jam_ruby/models/teacher_language" +require "jam_ruby/models/teacher_genre" include Jampb module JamRuby diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index 6bccf6e58..b5f055419 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -1770,5 +1770,28 @@ module JamRuby format.html { render :layout => "from_user_mailer" } end end + + def lesson_attachment(sender, target, lesson_session, attachment) + @sender = sender + @target = target + @lesson_session = lesson_session + @attachment = attachment + + + email = target.email + @subject = "An attachment has been added to your lesson by #{sender.name}" + unique_args = {:type => "lesson_attachment"} + + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + sendgrid_recipients([email]) + sendgrid_substitute('@USERID', [@target.id]) + + mail(:to => email, :subject => @subject) do |format| + format.text + format.html { render :layout => "from_user_mailer" } + end + + end end end diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/lesson_attachment.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/lesson_attachment.html.erb new file mode 100644 index 000000000..fc49d2163 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/lesson_attachment.html.erb @@ -0,0 +1,20 @@ +<% provide(:title, @subject) %> +<% provide(:photo_url, @sender.resolved_photo_url) %> + +<% content_for :note do %> +
+ <% if @attachment.is_a?(JamRuby::MusicNotation) %> + <% if @attachment.is_notation? %> + A music notation has been added to your lesson. You can download "><%= @attachment.file_name %> directly or at any time in the message window for this lesson. + <% else %> + A audio file has been added to your lesson. You can download "><%= @attachment.file_name %> directly or at any time in the message window for this lesson. + <% end %> + <% else %> + A recording named "<%= @attachment.name %>" has been added to your lesson. It can be viewed ">here or found within the message window for this lesson. + <% end %> +
+<% end %> + + diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/lesson_attachment.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/lesson_attachment.text.erb new file mode 100644 index 000000000..8756d460c --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/lesson_attachment.text.erb @@ -0,0 +1,12 @@ +<% if @attachment.is_a?(JamRuby::MusicNotation) %> +<% if @attachment.is_notation? %> +A music notation has been added to your lesson. You can download (<%= APP_CONFIG.external_root_url + "/api/music_notations/#{@attachment.id}" %>">)<%= @attachment.file_name %> directly or at any time in the message window for this lesson. +<% else %> +A audio file has been added to your lesson. You can download (<%= APP_CONFIG.external_root_url + "/api/music_notations/#{@attachment.id}" %>">)<%= @attachment.file_name %> directly or at any time in the message window for this lesson. +<% end %> +<% else %> +A recording named "<%= @attachment.name %>" has been added to your lesson. It can be viewed (<%= APP_CONFIG.external_root_url + "/recordings/#{@attachment.id}" %>">) here or found within the message window for this lesson. +<% end %> +VIEW LESSON DETAILS (<%= @lesson_session.web_url %>) + + diff --git a/ruby/lib/jam_ruby/models/genre.rb b/ruby/lib/jam_ruby/models/genre.rb index 3f81b8bbf..24a93a830 100644 --- a/ruby/lib/jam_ruby/models/genre.rb +++ b/ruby/lib/jam_ruby/models/genre.rb @@ -16,7 +16,8 @@ module JamRuby has_and_belongs_to_many :recordings, :class_name => "JamRuby::Recording", :join_table => "recordings_genres" # teachers - has_and_belongs_to_many :teachers, :class_name => "JamRuby::Teacher", :join_table => "teachers_genres" + has_many :teachers, :class_name => "JamRuby::Teacher", :through => :teachers_genres + has_many :teachers_genres, :class_name => "JamRuby::TeacherGenre" # jam tracks has_many :genres_jam_tracks, :class_name => "JamRuby::GenreJamTrack", :foreign_key => "genre_id" diff --git a/ruby/lib/jam_ruby/models/instrument.rb b/ruby/lib/jam_ruby/models/instrument.rb index be18c5eb5..e8b407135 100644 --- a/ruby/lib/jam_ruby/models/instrument.rb +++ b/ruby/lib/jam_ruby/models/instrument.rb @@ -44,7 +44,8 @@ module JamRuby has_and_belongs_to_many :music_sessions, :class_name => "JamRuby::ActiveMusicSession", :join_table => "genres_music_sessions" # teachers - has_and_belongs_to_many :teachers, :class_name => "JamRuby::Teacher", :join_table => "teachers_instruments" + has_many :teachers, :class_name => "JamRuby::Teacher", through: :teachers_instruments + has_many :teachers_instruments, class_name: "JamRuby::TeacherInstrument" def self.standard_list return Instrument.where('instruments.popularity > 0').order('instruments.description ASC') diff --git a/ruby/lib/jam_ruby/models/language.rb b/ruby/lib/jam_ruby/models/language.rb index ae249ff8e..4492f800b 100644 --- a/ruby/lib/jam_ruby/models/language.rb +++ b/ruby/lib/jam_ruby/models/language.rb @@ -2,7 +2,8 @@ module JamRuby class Language < ActiveRecord::Base include HtmlSanitize html_sanitize strict: [:name, :description] - has_and_belongs_to_many :teachers, :class_name => "JamRuby::Teacher", :join_table => "teachers_languages" + has_many :teachers, :class_name => "JamRuby::Teacher", :through => :teachers_languages + has_many :teachers_languages, class_name: "JamRuby::TeacherLanguage" def self.english_sort languages = Language.order(:description) diff --git a/ruby/lib/jam_ruby/models/lesson_booking.rb b/ruby/lib/jam_ruby/models/lesson_booking.rb index 0d69548fc..ca52d8131 100644 --- a/ruby/lib/jam_ruby/models/lesson_booking.rb +++ b/ruby/lib/jam_ruby/models/lesson_booking.rb @@ -243,7 +243,12 @@ module JamRuby minimum_start_time = create_minimum_booking_time # get all sessions that are already scheduled for this booking ahead of the minimum time - sessions = MusicSession.joins(:lesson_session).where("lesson_sessions.lesson_booking_id = ?", id).where("scheduled_start is not null").where("scheduled_start > ?", minimum_start_time).order(:created_at) + + sessions= MusicSession.joins(:lesson_session).where("lesson_sessions.lesson_booking_id = ?", id).where("scheduled_start is not null").order(:created_at) + if recurring + # only want times ahead of this for recurring + sessions = sessions.where("scheduled_start > ?", minimum_start_time) + end if @default_slot_did_change # # adjust all session times @@ -421,6 +426,9 @@ module JamRuby self.errors.add(:status, "This lesson is already #{self.status}.") end + if self.accepter.nil? + self.errors.add(:accepter, "No one has been indicated as accepting the lesson") + end self.accepting = false end diff --git a/ruby/lib/jam_ruby/models/lesson_booking_slot.rb b/ruby/lib/jam_ruby/models/lesson_booking_slot.rb index 911fd8739..6c64a39e6 100644 --- a/ruby/lib/jam_ruby/models/lesson_booking_slot.rb +++ b/ruby/lib/jam_ruby/models/lesson_booking_slot.rb @@ -33,6 +33,9 @@ module JamRuby validate :validate_proposer before_validation :before_validation + def is_recurring? + slot_type == SLOT_TYPE_RECURRING + end def before_validation if proposer.nil? self.proposer = container.student @@ -81,6 +84,7 @@ module JamRuby candidate = scheduled_time(i + week_offset) #puts "#{i}: candidate #{candidate} week_offset:#{week_offset}" + #puts "DAY_OF_WEEK #{day_of_week}" if day_of_week && candidate <= minimum_start_time # move it up a week week_offset += 1 @@ -173,7 +177,7 @@ module JamRuby duration = lesson_length * 60 # convert from minutes to seconds end_time = start_time + duration if with_timezone - "#{start_time.strftime("%A, %B %e")}, #{start_time.strftime("%l:%M").strip}-#{end_time.strftime("%l:%M %p").strip} #{tz.pretty_name}" + "#{start_time.strftime("%A, %B %e")}, #{start_time.strftime("%l:%M").strip}-#{end_time.strftime("%l:%M %p").strip} (#{tz.pretty_name})" else "#{start_time.strftime("%A, %B %e")} - #{start_time.strftime("%l:%M%P").strip}" end diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb index a1c946359..e4225be2e 100644 --- a/ruby/lib/jam_ruby/models/lesson_session.rb +++ b/ruby/lib/jam_ruby/models/lesson_session.rb @@ -5,7 +5,7 @@ module JamRuby include HtmlSanitize html_sanitize strict: [:cancel_message] - attr_accessor :accepting, :creating, :countering, :autocanceling, :countered_slot, :countered_lesson, :canceling, :assigned_student + attr_accessor :accepting, :creating, :countering, :countering_flag, :autocanceling, :countered_slot, :countered_lesson, :canceling, :assigned_student @@log = Logging.logger[LessonSession] @@ -61,6 +61,7 @@ module JamRuby validates :post_processed, inclusion: {in: [true, false]} validate :validate_creating, :if => :creating + validate :validate_countering, :if => :countering_flag validate :validate_accepted, :if => :accepting validate :validate_canceled, :if => :canceling validate :validate_autocancel, :if => :autocanceling @@ -165,7 +166,7 @@ module JamRuby end # test drives don't have a lesson_payment_charge, so we don't join against them - MusicSession.joins(lesson_session: [:lesson_booking]).where('lesson_sessions.status = ?', LessonSession::STATUS_COMPLETED).where('lesson_sessions.lesson_type = ?', LESSON_TYPE_TEST_DRIVE).where("session_removed_at IS NOT NULL OR ? > scheduled_start + (INTERVAL '1 minutes' * duration)", Time.now).where('analysed = true').where('lesson_sessions.post_processed = false').each do |music_session| + MusicSession.joins(lesson_session: [:lesson_booking]).where('lesson_sessions.status = ?', LessonSession::STATUS_COMPLETED).where('lesson_sessions.lesson_type = ?', LESSON_TYPE_TEST_DRIVE).where("? > scheduled_start + (INTERVAL '1 minutes' * duration)", Time.now).where('analysed = true').where('lesson_sessions.post_processed = false').each do |music_session| lession_session = music_session.lesson_session lession_session.session_completed end @@ -366,7 +367,9 @@ module JamRuby end def recurring_completed + puts "RECURRING COMPLETED #{success}" if success + if lesson_booking.is_monthly_payment? # monthly payments are handled at beginning of month; just poke with email, and move on @@ -399,6 +402,7 @@ module JamRuby end else + puts "STUDENT NO BILL SENT #{self.id}" if !sent_notices if !school_on_school? # bad session; just poke user @@ -422,6 +426,7 @@ module JamRuby else if !sent_notices if !school_on_school? + puts "STUDENT NO BILL SENT #{success}" UserMailer.student_lesson_normal_no_bill(self).deliver UserMailer.teacher_lesson_normal_no_bill(self).deliver end @@ -501,6 +506,22 @@ module JamRuby end end + def validate_countering + + if counter_slot.nil? + errors.add(:counter_slot, "must be specified") + elsif !approved_before? && (status == STATUS_REQUESTED || status == STATUS_COUNTERED) + if recurring && !counter_slot.update_all + errors.add(:counter_slot, "Only 'update all' counter-proposals are allowed for un-approved, recurring lessons") + end + + if recurring && !counter_slot.is_recurring? + errors.add(:counter_slot, "Only 'recurring' counter-proposals are allowed for un-approved, recurring lessons") + end + end + + self.countering_flag = false + end def validate_accepted if self.status_was != STATUS_REQUESTED && self.status_was != STATUS_COUNTERED self.errors.add(:status, "This session is already #{self.status_was}.") @@ -787,6 +808,7 @@ module JamRuby update_all = slot.update_all || !lesson_booking.recurring self.countering = true + self.countering_flag = true slot.proposer = proposer slot.lesson_session = self slot.message = message @@ -796,11 +818,12 @@ module JamRuby self.countered_slot = slot self.countered_lesson = self self.status = STATUS_COUNTERED - if !update_all + #if !update_all self.counter_slot = slot - end + #end if self.save - if update_all && !lesson_booking.counter(self, proposer, slot) + #if update_all && !lesson_booking.counter(self, proposer, slot) + if !lesson_booking.counter(self, proposer, slot) response = lesson_booking raise ActiveRecord::Rollback end diff --git a/ruby/lib/jam_ruby/models/music_notation.rb b/ruby/lib/jam_ruby/models/music_notation.rb index 767453d14..21406b384 100644 --- a/ruby/lib/jam_ruby/models/music_notation.rb +++ b/ruby/lib/jam_ruby/models/music_notation.rb @@ -48,6 +48,9 @@ module JamRuby s3_manager.sign_url(self[:file_url], {:expires => expiration_time, :secure => true}) end + def is_notation? + self.attachment_type == TYPE_NOTATION + end private def self.construct_filename(notation) diff --git a/ruby/lib/jam_ruby/models/subject.rb b/ruby/lib/jam_ruby/models/subject.rb index f20d75626..a99a9745d 100644 --- a/ruby/lib/jam_ruby/models/subject.rb +++ b/ruby/lib/jam_ruby/models/subject.rb @@ -2,6 +2,7 @@ module JamRuby class Subject < ActiveRecord::Base include HtmlSanitize html_sanitize strict: [:name, :description] - has_and_belongs_to_many :teachers, :class_name => "JamRuby::Teacher", :join_table => "teachers_subjects" + has_many :teachers, :class_name => "JamRuby::Teacher", :through => :teachers_subjects + has_many :teachers_subjects, class_name: "JamRuby::TeacherSubject" end end diff --git a/ruby/lib/jam_ruby/models/teacher.rb b/ruby/lib/jam_ruby/models/teacher.rb index 74e15d854..4e1485fb9 100644 --- a/ruby/lib/jam_ruby/models/teacher.rb +++ b/ruby/lib/jam_ruby/models/teacher.rb @@ -4,10 +4,14 @@ module JamRuby html_sanitize strict: [:biography, :website] attr_accessor :validate_introduction, :validate_basics, :validate_pricing attr_accessible :genres, :teacher_experiences, :experiences_teaching, :experiences_education, :experiences_award - has_and_belongs_to_many :genres, :class_name => "JamRuby::Genre", :join_table => "teachers_genres", :order => "description" - has_and_belongs_to_many :instruments, :class_name => "JamRuby::Instrument", :join_table => "teachers_instruments", :order => "description" - has_and_belongs_to_many :subjects, :class_name => "JamRuby::Subject", :join_table => "teachers_subjects", :order => "description" - has_and_belongs_to_many :languages, :class_name => "JamRuby::Language", :join_table => "teachers_languages", :order => "description" + has_many :genres, :class_name => "JamRuby::Genre", :through => :teachers_genres # , :order => "description" + has_many :teachers_genres, :class_name => "JamRuby::TeacherGenre" + has_many :instruments, :class_name => "JamRuby::Instrument", through: :teachers_instruments # , :order => "description" + has_many :teachers_instruments, class_name: "JamRuby::TeacherInstrument" + has_many :subjects, :class_name => "JamRuby::Subject", :through => :teachers_subjects # , :order => "description" + has_many :teachers_subjects, class_name: "JamRuby::TeacherSubject" + has_many :languages, :class_name => "JamRuby::Language", :through => :teachers_languages # , :order => "description" + has_many :teachers_languages, class_name: "JamRuby::TeacherLanguage" has_many :teacher_experiences, :class_name => "JamRuby::TeacherExperience" has_many :experiences_teaching, :class_name => "JamRuby::TeacherExperience", conditions: {experience_type: 'teaching'} has_many :experiences_education, :class_name => "JamRuby::TeacherExperience", conditions: {experience_type: 'education'} @@ -36,7 +40,7 @@ module JamRuby validate :offer_duration, :if => :validate_pricing validate :teaches_ages, :if => :validate_basics - default_scope { includes(:genres).order('created_at desc') } + #default_scope { includes(:genres).order('created_at desc') } after_save :update_profile_pct @@ -53,7 +57,7 @@ module JamRuby limit ||= 20 limit = limit.to_i - query = User.joins(:teacher) + query = User.unscoped.joins(:teacher) # only show teachers with ready for session set to true query = query.where('teachers.ready_for_session_at IS NOT NULL') diff --git a/ruby/lib/jam_ruby/models/teacher_genre.rb b/ruby/lib/jam_ruby/models/teacher_genre.rb new file mode 100644 index 000000000..549219dff --- /dev/null +++ b/ruby/lib/jam_ruby/models/teacher_genre.rb @@ -0,0 +1,11 @@ +module JamRuby + class TeacherGenre < ActiveRecord::Base + self.table_name = "teachers_genres" + + belongs_to :teacher, class_name: "JamRuby::Teacher" + belongs_to :genre, class_name: "JamRuby::Genre" + + validates :teacher, presence:true + validates :genre, presence: true + end +end diff --git a/ruby/lib/jam_ruby/models/teacher_instrument.rb b/ruby/lib/jam_ruby/models/teacher_instrument.rb new file mode 100644 index 000000000..f1f60db41 --- /dev/null +++ b/ruby/lib/jam_ruby/models/teacher_instrument.rb @@ -0,0 +1,11 @@ +module JamRuby + class TeacherInstrument < ActiveRecord::Base + self.table_name = "teachers_instruments" + + belongs_to :teacher, class_name: "JamRuby::Teacher" + belongs_to :instrument, class_name: "JamRuby::Instrument" + + validates :teacher, presence:true + validates :instrument, presence: true + end +end diff --git a/ruby/lib/jam_ruby/models/teacher_language.rb b/ruby/lib/jam_ruby/models/teacher_language.rb new file mode 100644 index 000000000..f0cfcf3d1 --- /dev/null +++ b/ruby/lib/jam_ruby/models/teacher_language.rb @@ -0,0 +1,11 @@ +module JamRuby + class TeacherLanguage < ActiveRecord::Base + self.table_name = "teachers_languages" + + belongs_to :teacher, class_name: "JamRuby::Teacher" + belongs_to :language, class_name: "JamRuby::Language" + + validates :teacher, presence:true + validates :language, presence: true + end +end diff --git a/ruby/lib/jam_ruby/models/teacher_subject.rb b/ruby/lib/jam_ruby/models/teacher_subject.rb new file mode 100644 index 000000000..953ff9fd2 --- /dev/null +++ b/ruby/lib/jam_ruby/models/teacher_subject.rb @@ -0,0 +1,11 @@ +module JamRuby + class TeacherSubject < ActiveRecord::Base + self.table_name = "teachers_subjects" + + belongs_to :teacher, class_name: "JamRuby::Teacher" + belongs_to :subject, class_name: "JamRuby::Subject" + + validates :teacher, presence:true + validates :subject, presence: true + end +end diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 91321138e..93b19b48f 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -51,7 +51,7 @@ module JamRuby has_many :user_authorizations, :class_name => "JamRuby::UserAuthorization" has_many :reviews, :class_name => "JamRuby::Review" - has_one :review_summary, :class_name => "JamRuby::ReviewSummary" + has_one :review_summary, :class_name => "JamRuby::ReviewSummary", as: :target # calendars (for scheduling NOT in music_session) has_many :calendars, :class_name => "JamRuby::Calendar" @@ -2090,7 +2090,7 @@ module JamRuby LessonBooking.unprocessed(self).where(lesson_type: LessonBooking::LESSON_TYPE_PAID).first end - def most_recent_test_drive_purchase + def most_recent_test_drive_purchase lesson_purchases.where('lesson_package_type_id in (?)', LessonPackageType.test_drive_package_ids).order('created_at desc').first end diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb index 4a3b6a247..8cde0eff7 100644 --- a/ruby/spec/factories.rb +++ b/ruby/spec/factories.rb @@ -1057,5 +1057,13 @@ FactoryGirl.define do factory :email_blacklist, class: "JamRuby::EmailBlacklist" do sequence(:email) { |n| "person_#{n}@example.com"} end + + factory :music_notation, class: "JamRuby::MusicNotation" do + attachment_type {JamRuby::MusicNotation::TYPE_NOTATION} + association :user, factory: :user + file_url 'abc' + size 100 + file_name 'some_file.jpg' + end end diff --git a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb index ee2aea0bf..ea39a1573 100644 --- a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb @@ -42,7 +42,6 @@ describe "Monthly Recurring Lesson Flow" do ########## Need validate their credit card token = create_stripe_token result = user.payment_update({token: token, zip: '78759', normal: true, booking_id: booking.id}) - puts "result #{result.inspect}" booking.reload booking.card_presumed_ok.should be_true booking.errors.any?.should be_false @@ -118,7 +117,7 @@ describe "Monthly Recurring Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false, accepter: teacher_user}) UserMailer.deliveries.each do |del| # puts del.inspect end @@ -203,7 +202,7 @@ describe "Monthly Recurring Lesson Flow" do payment = TeacherPayment.first payment.amount_in_cents.should eql 3000 payment.fee_in_cents.should eql (3000 * 0.28).round - payment.teacher_payment_charge.amount_in_cents.should eql 3000 + payment.teacher_payment_charge.amount_in_cents.should eql (3000 + 3000 * APP_CONFIG.stripe[:ach_pct]).round 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 @@ -320,7 +319,7 @@ describe "Monthly Recurring Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false, accepter: teacher_user}) UserMailer.deliveries.each do |del| # puts del.inspect end @@ -419,6 +418,7 @@ describe "Monthly Recurring Lesson Flow" do it "affiliate gets their cut" do + Timecop.travel(2016, 05, 15) user.affiliate_referral = affiliate_partner user.save! teacher_user.affiliate_referral = affiliate_partner2 @@ -429,7 +429,6 @@ describe "Monthly Recurring Lesson Flow" do user.reload - puts "user.lesson_purchases #{user.lesson_purchases}" user.lesson_purchases.count.should eql 1 lesson_package_purchase = user.lesson_purchases.first teacher_distribution = lesson_package_purchase.teacher_distribution @@ -447,6 +446,7 @@ describe "Monthly Recurring Lesson Flow" do end it "school affiliate gets nothing when teacher school is involved" do + Timecop.travel(2016, 05, 15) teacher.school = school teacher.save! @@ -469,6 +469,8 @@ describe "Monthly Recurring Lesson Flow" do end it "student school affiliates gets cut when student school is involved. so does teacher's" do + # in the middle of the month so that we don't get the next month's in-advance purchase put on us + Timecop.travel(2016, 05, 15) user.affiliate_referral = school.affiliate_partner user.save! diff --git a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb index b9a558afd..e0fbde071 100644 --- a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb @@ -68,7 +68,7 @@ describe "Normal Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: booking.default_slot.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: booking.default_slot.id, update_all: false, accepter: teacher_user}) lesson_session.errors.any?.should be_false lesson_session.reload lesson_session.slot.should eql booking.default_slot @@ -251,7 +251,7 @@ describe "Normal Lesson Flow" do payment = TeacherPayment.first payment.amount_in_cents.should eql 3000 payment.fee_in_cents.should eql (3000 * 0.28).round - payment.teacher_payment_charge.amount_in_cents.should eql 3000 + payment.teacher_payment_charge.amount_in_cents.should eql (3000 + 3000 * APP_CONFIG.stripe[:ach_pct]).round 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 @@ -352,7 +352,7 @@ describe "Normal Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false,accepter: teacher_user}) lesson_session.errors.any?.should be_false lesson_session.reload lesson_session.slot.should eql student_counter @@ -508,7 +508,7 @@ describe "Normal Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false, accepter: teacher_user}) lesson_session.errors.any?.should be_false lesson_session.reload lesson_session.slot.should eql student_counter diff --git a/ruby/spec/jam_ruby/flows/recurring_lesson_spec.rb b/ruby/spec/jam_ruby/flows/recurring_lesson_spec.rb index 00924d4e6..d84e21e83 100644 --- a/ruby/spec/jam_ruby/flows/recurring_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/recurring_lesson_spec.rb @@ -55,7 +55,7 @@ describe "Recurring Lesson Flow" do booking.status.should eql LessonBooking::STATUS_REQUESTED ######### Teacher counters with new slot - teacher_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 14, update_all: true) + teacher_countered_slot = FactoryGirl.build(:lesson_booking_slot_recurring, hour: 14, update_all: true) UserMailer.deliveries.clear lesson_session.counter({proposer: teacher_user, slot: teacher_countered_slot, message: 'Does this work?'}) booking.reload @@ -81,7 +81,7 @@ describe "Recurring Lesson Flow" do #notification.message.should eql "Instructor has proposed a different time for your lesson." ######### Student counters with new slot - student_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 16, update_all: true) + student_countered_slot = FactoryGirl.build(:lesson_booking_slot_recurring, hour: 16, update_all: true) UserMailer.deliveries.clear lesson_session.counter({proposer: user, slot: student_countered_slot, message: 'Does this work better?'}) lesson_session.errors.any?.should be false @@ -105,7 +105,7 @@ describe "Recurring Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, accepter: teacher_user}) UserMailer.deliveries.each do |del| # puts del.inspect end @@ -132,7 +132,11 @@ describe "Recurring Lesson Flow" do notification.student_directed.should eql true notification.purpose.should eql 'accept' notification.description.should eql NotificationTypes::LESSON_MESSAGE + user.reload + user.sales.length.should eql 0 + booking.reload + booking.lesson_sessions[0].scheduled_start.should_not eql booking.lesson_sessions[1].scheduled_start # teacher & student get into session start = lesson_session.scheduled_start @@ -181,6 +185,9 @@ describe "Recurring Lesson Flow" do lesson_session.sent_billing_notices.should be true user.reload user.remaining_test_drives.should eql 0 + UserMailer.deliveries.each do |d| + puts d.subject + end UserMailer.deliveries.length.should eql 2 # one for student, one for teacher end end diff --git a/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb b/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb index 5db43fb37..5d258f958 100644 --- a/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb @@ -140,7 +140,7 @@ describe "TestDrive Lesson Flow" do ######## Teacher accepts slot UserMailer.deliveries.clear - lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false}) + lesson_session.accept({message: 'Yeah I got this', slot: student_counter.id, update_all: false, accepter: teacher_user}) lesson_session.errors.any?.should be_false lesson_session.reload lesson_session.slot.should eql student_counter @@ -237,7 +237,7 @@ describe "TestDrive Lesson Flow" do teacher_distribution.ready.should be_true teacher_distribution.distributed.should be_true - teacher_payment.teacher_payment_charge.amount_in_cents.should eql 1000 + teacher_payment.teacher_payment_charge.amount_in_cents.should eql (1000 + 1000 * APP_CONFIG.stripe[:ach_pct]).round teacher_payment.teacher_payment_charge.fee_in_cents.should eql 0 user.sales.count.should eql 1 diff --git a/ruby/spec/jam_ruby/models/lesson_booking_spec.rb b/ruby/spec/jam_ruby/models/lesson_booking_spec.rb index 4ac09e8ba..57a546006 100644 --- a/ruby/spec/jam_ruby/models/lesson_booking_spec.rb +++ b/ruby/spec/jam_ruby/models/lesson_booking_spec.rb @@ -741,6 +741,14 @@ describe LessonBooking do UserMailer.deliveries.clear Timecop.freeze(7.days.ago) + + mailer = mock + mailer.should_receive(:deliver).exactly(2).times + UserMailer.should_receive(:student_lesson_booking_canceled).and_return(mailer) + UserMailer.should_receive(:teacher_lesson_booking_canceled).and_return(mailer) + UserMailer.should_receive(:student_lesson_canceled).exactly(0).times + UserMailer.should_receive(:teacher_lesson_canceled).exactly(0).times + lesson_session.cancel({canceler: user, message: 'meh', slot: booking.default_slot.id, update_all: true}) lesson_session.errors.any?.should be_false lesson_session.reload @@ -748,14 +756,32 @@ describe LessonBooking do booking.reload booking.status.should eql LessonSession::STATUS_CANCELED booking.canceler.should eql user - UserMailer.deliveries.length.should eql 2 end end describe "rescheduling" do - after do - Timecop.return + it "initial slot is in the past" do + booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60) + + lesson_session = booking.lesson_sessions[0] + + initial_scheduled_time = lesson_session.scheduled_start + + counter = FactoryGirl.build(:lesson_booking_slot_single, preferred_day: Date.today + 20) + lesson_session.counter({proposer: user, slot: counter, message: 'ACtually, let\'s do this instead for just this one'}) + + Timecop.travel(initial_scheduled_time + 1) + + lesson_session.accept({accepter: teacher_user, message: 'Yeah I got this', slot: counter, update_all: false}) + booking.reload + booking.status.should eql LessonBooking::STATUS_APPROVED + booking.lesson_sessions.count.should eql 1 + lesson_session.errors.any?.should be_false + lesson_session.reload + lesson_session.status.should eql LessonSession::STATUS_APPROVED + lesson_session.scheduled_start.should eql counter.scheduled_time(0) end + it "non-recurring, accepted with new slot" do booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60) lesson_session = booking.lesson_sessions[0] diff --git a/ruby/spec/jam_ruby/models/lesson_session_spec.rb b/ruby/spec/jam_ruby/models/lesson_session_spec.rb index 3988a2176..c269ac0d3 100644 --- a/ruby/spec/jam_ruby/models/lesson_session_spec.rb +++ b/ruby/spec/jam_ruby/models/lesson_session_spec.rb @@ -10,6 +10,63 @@ describe LessonSession do let(:lesson_booking) {b = LessonBooking.book_normal(user, teacher, [slot1, slot2], "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60); b.card_presumed_ok = true; b.save!; b} let(:lesson_session) {lesson_booking.lesson_sessions[0]} + describe "counter" do + describe "recurring" do + it "counter madness" do + lesson = monthly_lesson(user, teacher, {accept:false}) + # start with the student + invalid = FactoryGirl.build(:lesson_booking_slot_single, update_all: false) + + lesson.counter({proposer: user, message: "crumble and bumble", slot: invalid}) + lesson.errors.any?.should be_true + lesson.errors[:counter_slot].should eql ["Only 'update all' counter-proposals are allowed for un-approved, recurring lessons", "Only 'recurring' counter-proposals are allowed for un-approved, recurring lessons"] + lesson.reload + lesson.counter_slot.should be_nil + + counter1 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: true) + + lesson.counter({proposer: user, message: "crumble and bumble take 2", slot: counter1}) + lesson.errors.any?.should be_false + lesson.reload + lesson.status.should eql LessonSession::STATUS_COUNTERED + lesson.counter_slot.id.should eql counter1.id + lesson.lesson_booking.counter_slot.id.should eql counter1.id + + counter2 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: true) + + lesson.counter({proposer: teacher, message: "crumble and bumble take 3", slot: counter2}) + lesson.errors.any?.should be_false + lesson.reload + lesson.status.should eql LessonSession::STATUS_COUNTERED + lesson.counter_slot.id.should eql counter2.id + lesson.lesson_booking.counter_slot.id.should eql counter2.id + + lesson.accept({accepter: user, message: "burp", slot: counter2}) + lesson.errors.any?.should be_false + lesson.reload + lesson.status.should eql LessonSession::STATUS_APPROVED + + counter3 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: false) + + lesson.counter({proposer: user, message: "crumble and bumble take 4", slot: counter3}) + lesson.errors.any?.should be_false + lesson.reload + lesson.status.should eql LessonSession::STATUS_COUNTERED + lesson.counter_slot.id.should eql counter3.id + lesson.lesson_booking.counter_slot.id.should eql counter3.id + + counter4 = FactoryGirl.build(:lesson_booking_slot_recurring, update_all: true) + + lesson.counter({proposer: teacher, message: "crumble and bumble take 5", slot: counter4}) + lesson.errors.any?.should be_false + lesson.reload + lesson.status.should eql LessonSession::STATUS_COUNTERED + lesson.counter_slot.id.should eql counter4.id + lesson.lesson_booking.counter_slot.id.should eql counter4.id + end + end + end + describe "autocancel" do it "can't autocancel in the past" do lesson_session.status.should eql LessonSession::STATUS_REQUESTED diff --git a/ruby/spec/jam_ruby/models/teacher_spec.rb b/ruby/spec/jam_ruby/models/teacher_spec.rb index 32003f0cc..a5fd51e50 100644 --- a/ruby/spec/jam_ruby/models/teacher_spec.rb +++ b/ruby/spec/jam_ruby/models/teacher_spec.rb @@ -45,18 +45,20 @@ describe Teacher do it "instruments" do teacher = FactoryGirl.create(:teacher, ready_for_session_at: Time.now) - teachers = Teacher.index(nil, {instruments: ['acoustic guitar']})[:query] - teachers.length.should eq 0 + #teachers = Teacher.index(nil, {instruments: ['acoustic guitar']})[:query] + #teachers.length.should eq 0 teacher.instruments << Instrument.find('acoustic guitar') teacher.save! - teachers = Teacher.index(nil, {instruments: ['acoustic guitar']})[:query] - teachers.length.should eq 1 - teachers[0].should eq(teacher.user) + #teachers = Teacher.index(nil, {instruments: ['acoustic guitar']})[:query] + #teachers.length.should eq 1 + #teachers[0].should eq(teacher.user) - teacher.instruments << Instrument.find('electric guitar') - teacher.save! + #teacher.instruments << Instrument.find('electric guitar') + #teacher.save! + puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" teachers = Teacher.index(nil, {instruments: ['acoustic guitar']})[:query] + puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!---" teachers.length.should eq 1 teachers[0].should eq(teacher.user) end diff --git a/ruby/spec/jam_ruby/resque/google_analytics_event_spec.rb b/ruby/spec/jam_ruby/resque/google_analytics_event_spec.rb index 587080fe5..a9ebd1a28 100644 --- a/ruby/spec/jam_ruby/resque/google_analytics_event_spec.rb +++ b/ruby/spec/jam_ruby/resque/google_analytics_event_spec.rb @@ -9,6 +9,7 @@ describe GoogleAnalyticsEvent do end describe "track band analytics" do + pending "job is commented out" it 'reports first recording' do ResqueSpec.reset! user = FactoryGirl.create(:user) @@ -26,6 +27,7 @@ describe GoogleAnalyticsEvent do end it 'reports first real session' do + pending "job is commented out" ResqueSpec.reset! JamRuby::GoogleAnalyticsEvent::BandSessionTracker.should have_schedule_size_of(0) user = FactoryGirl.create(:user) @@ -72,6 +74,7 @@ describe GoogleAnalyticsEvent do ResqueSpec.reset! end it 'reports size increment' do + pending "job is commented out" user = FactoryGirl.create(:user) music_session = FactoryGirl.create(:active_music_session, :creator => user, @@ -86,6 +89,7 @@ describe GoogleAnalyticsEvent do end it 'reports duration' do + pending "job is commented out" user = FactoryGirl.create(:user) JamRuby::GoogleAnalyticsEvent::SessionDurationTracker.should have_schedule_size_of(0) music_session = FactoryGirl.create(:active_music_session, diff --git a/ruby/spec/mailers/render_emails_spec.rb b/ruby/spec/mailers/render_emails_spec.rb index ae09837eb..ea653fe61 100644 --- a/ruby/spec/mailers/render_emails_spec.rb +++ b/ruby/spec/mailers/render_emails_spec.rb @@ -162,6 +162,26 @@ describe "RenderMailers", :slow => true do UserMailer.deliveries.clear UserMailer.lesson_starting_soon_student(lesson).deliver end + + it "music_notation_attachment" do + @filename = "music_notation_attachment" + + lesson = testdrive_lesson(user, teacher) + + UserMailer.deliveries.clear + notation = FactoryGirl.create(:music_notation, user: user) + UserMailer.lesson_attachment(user, teacher, lesson, notation).deliver + end + + it "recording_attachment" do + @filename = "recording_attachment" + + lesson = testdrive_lesson(user, teacher) + + UserMailer.deliveries.clear + claim = FactoryGirl.create(:claimed_recording, user: user) + UserMailer.lesson_attachment(user, teacher, lesson, claim).deliver + end end end diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb index 911452807..bc1163e38 100644 --- a/ruby/spec/spec_helper.rb +++ b/ruby/spec/spec_helper.rb @@ -38,7 +38,7 @@ require 'timecop' require 'resque_spec/scheduler' # uncomment this to see active record logs -# ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base) +ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base) include JamRuby diff --git a/ruby/spec/support/lesson_session.rb b/ruby/spec/support/lesson_session.rb index 855f13a46..1a731423e 100644 --- a/ruby/spec/support/lesson_session.rb +++ b/ruby/spec/support/lesson_session.rb @@ -65,7 +65,6 @@ def book_lesson(user, teacher, options) LessonPackagePurchase.create(user, booking, LessonPackageType.package_for_test_drive_count(options[:package_count])) end elsif options[:monthly] - puts "did it" LessonPackagePurchase.create(user, booking, LessonPackageType.single, Date.today.year, Date.today.month) end @@ -83,7 +82,7 @@ def book_lesson(user, teacher, options) end if options[:accept] - lesson.accept({message: 'Yeah I got this', slot: slots[0]}) + lesson.accept({message: 'Yeah I got this', slot: slots[0], accepter: teacher}) lesson.errors.any?.should be_false lesson.reload lesson.slot.should eql slots[0] diff --git a/web/app/assets/javascripts/feedHelper.js b/web/app/assets/javascripts/feedHelper.js index 3d68671ff..61f7b69e8 100644 --- a/web/app/assets/javascripts/feedHelper.js +++ b/web/app/assets/javascripts/feedHelper.js @@ -581,6 +581,9 @@ if(!defaults.show_checkbox) { $feedItem.find('.select-box').hide(); } + else { + context.JK.checkbox($feedItem.find('.select-box')) + } if(defaults.hide_avatar) { $feedItem.find('.avatar-small.ib').hide(); } @@ -598,6 +601,7 @@ $feedItem.data('original-max-height', $feedItem.css('height')); context.JK.bindHoverEvents($feedItem); context.JK.bindProfileClickEvents($feedItem); + context.JK.popExternalLinks($feedItem) } else { logger.warn("skipping feed type: " + feed.type); diff --git a/web/app/assets/javascripts/ga.js b/web/app/assets/javascripts/ga.js index 0c47505ff..d68ece250 100644 --- a/web/app/assets/javascripts/ga.js +++ b/web/app/assets/javascripts/ga.js @@ -99,6 +99,10 @@ ioTargetFail : 'ioTargetFail' } + var jamClassReasons = { + testDrive: 'TestDrive' + } + var networkTestFailReasons = { stun : 'STUN', bandwidth : 'Bandwidth', @@ -129,7 +133,8 @@ jkFollow : 'jkFollow', jkFavorite : 'jkFavorite', jkComment : 'jkComment', - fileDownload: "DownloadFile" + fileDownload: "DownloadFile", + jamclass: 'JamClass' }; // JamTrack categories and actions: @@ -204,6 +209,11 @@ context.ga('send', 'event', categories.register, action, registrationType); } + function trackTestDrivePurchase(count) { + + context.ga('send', 'event', categories.jamclass, jamClassReasons.testDrive, count); + + } function trackDownload(platform) { var normalizedPlatform = translatePlatformForGA(platform); @@ -490,6 +500,7 @@ GA.virtualPageView = virtualPageView; GA.trackTiming = trackTiming; GA.trackFileDownload = trackFileDownload; + GA.trackTestDrivePurchase = trackTestDrivePurchase; context.JK.GA = GA; diff --git a/web/app/assets/javascripts/globals.js b/web/app/assets/javascripts/globals.js index d59831d01..3954949c6 100644 --- a/web/app/assets/javascripts/globals.js +++ b/web/app/assets/javascripts/globals.js @@ -228,7 +228,7 @@ "Electric Guitar": { "client_id": 50, "server_id": "electric guitar" }, "Keyboard": { "client_id": 60, "server_id": "keyboard" }, "Piano": { "client_id": 61, "server_id": "piano" }, - "Upright Bass": { "client_id": 62, "server_id": "upright bass" }, + "Upright Bass": { "client_id": 62, "server_id": "double bass" }, "Voice": { "client_id": 70, "server_id": "voice" }, "Flute": { "client_id": 80, "server_id": "flute" }, "Clarinet": { "client_id": 90, "server_id": "clarinet" }, @@ -250,6 +250,9 @@ "Other": { "client_id": 250, "server_id": "other" } }; + + + context.JK.client_to_server_instrument_map = { 10: { "server_id": "acoustic guitar" }, 20: { "server_id": "bass guitar" }, @@ -259,7 +262,7 @@ 50: { "server_id": "electric guitar" }, 60: { "server_id": "keyboard" }, 61: { "server_id": "piano"} , - 62: { "server_id": "upright bass"} , + 62: { "server_id": "double bass"} , 70: { "server_id": "voice" }, 80: { "server_id": "flute" }, 90: { "server_id": "clarinet" }, @@ -283,10 +286,21 @@ context.JK.instrument_id_to_instrument = {}; + context.JK.server_to_client_instrument_alpha = []; + (function() { $.each(context.JK.server_to_client_instrument_map, function(key, value) { context.JK.instrument_id_to_instrument[value.server_id] = { client_id: value.client_id, display: key } + context.JK.server_to_client_instrument_alpha.push({ client_id: value.client_id, display: key, server_id: value.server_id }) }); + + context.JK.server_to_client_instrument_alpha.sort(function(a, b){ + if ( a.display < b.display ) + return -1; + if ( a.display > b.display ) + return 1; + return 0; + }); })(); diff --git a/web/app/assets/javascripts/helpBubbleHelper.js b/web/app/assets/javascripts/helpBubbleHelper.js index f6b7622f0..0c7c05f65 100644 --- a/web/app/assets/javascripts/helpBubbleHelper.js +++ b/web/app/assets/javascripts/helpBubbleHelper.js @@ -82,7 +82,7 @@ } function subtlePulse($element) { - $element.find('.bt-content').pulse({'background-color' : '#868686'}, {pulses: 3}, function() { $element.css('background-color', '#980006')}) + $element.find('.bt-content').pulse({'background-color' : '#868686'}, {pulses: 2, duration: 1000, interval:300}, function() { $element.css('background-color', '#980006')}) } helpBubble.rotateJamTrackLandingBubbles = function($preview, $video, $ctaButton, $alternativeCta) { @@ -203,7 +203,7 @@ helpBubble.showBuyTestDrive = function($element, $offsetParent, user, callback) { return context.JK.onceBubble($element, 'side-buy-test-drive', user, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) { subtlePulse(container) - var $bookNow = container('a.book-now') + var $bookNow = container.find('a.book-now') $bookNow.off('click').on('click', function(e) { e.preventDefault() callback() diff --git a/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee b/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee index 733cd77b9..75f5f84be 100644 --- a/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee @@ -24,7 +24,7 @@ AttachmentStore = context.AttachmentStore notationUploadDone: () -> logger.debug("AttachmentStatus: notationUploadDone") - context.JK.Banner.showNotice('Notation Uploaded', 'The music notation file has been uploaded, and can be accessed from the Messages window for this lesson.') + #context.JK.Banner.showNotice('Notation Uploaded', 'The music notation file has been uploaded, and can be accessed from the Messages window for this lesson.') notationUploadFail: () -> logger.debug("AttachmentStatus: notationUploadFail") @@ -32,11 +32,11 @@ AttachmentStore = context.AttachmentStore audioSelected: (e) -> files = $(e.target).get(0).files logger.debug("audio files selected: ", files) - window.AttachmentActions.uploadAudio.trigger(files, @notationUploadDone, @notationUploadFail) + window.AttachmentActions.uploadAudios.trigger(files, @notationUploadDone, @notationUploadFail) audioUploadDone: () -> logger.debug("AttachmentStatus: audioUploadDone") - context.JK.Banner.showNotice('Audio file Uploaded', 'The audio file has been uploaded, and can be accessed from the Messages window for this lesson.') + #context.JK.Banner.showNotice('Audio file Uploaded', 'The audio file has been uploaded, and can be accessed from the Messages window for this lesson.') audioUploadFail: () -> logger.debug("AttachmentStatus: audioUploadFail") diff --git a/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee b/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee index 7a7b64f39..54264ab47 100644 --- a/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee @@ -1,3 +1,4 @@ + context = window rest = context.JK.Rest() logger = context.JK.logger diff --git a/web/app/assets/javascripts/react-components/ChatWindow.js.jsx.coffee b/web/app/assets/javascripts/react-components/ChatWindow.js.jsx.coffee index c01269302..beb1fc840 100644 --- a/web/app/assets/javascripts/react-components/ChatWindow.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/ChatWindow.js.jsx.coffee @@ -125,6 +125,7 @@ ChatActions = @ChatActions else purpose = null + additional = null if msg.purpose == 'Notation File' additional = `{msg.music_notation.file_name}` else if msg.purpose == 'Audio File' diff --git a/web/app/assets/javascripts/react-components/CheckBoxList.js.jsx.coffee b/web/app/assets/javascripts/react-components/CheckBoxList.js.jsx.coffee index da12cb587..2364c52c5 100644 --- a/web/app/assets/javascripts/react-components/CheckBoxList.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/CheckBoxList.js.jsx.coffee @@ -44,7 +44,7 @@ logger = context.JK.logger for object in this.props.sourceObjects nm = "check_#{object.id}" checked = @isChecked(object.id) - object_options.push `` + object_options.push `You are proposing to change the date/time of the lesson currently scheduled for {this.slotTime(this.state.booking.default_slot)}
` + else + detail = `Your {this.lessonDesc()} will take place this {this.slotTime(this.state.booking.default_slot)}
` + else + if @onlyOption() && @rescheduling() + detail = `You are proposing to change the date/time of the lesson currently scheduled for {this.slotTime(this.state.booking.default_slot)}
` + else + detail = `Your {this.lessonDesc()} will take place each {this.slotTime(this.state.booking.default_slot)}
` + detail + + rescheduling: () -> + @state.purpose == 'rescheduling' + renderStudentComplete: () -> @renderStudentApproved() @@ -746,10 +853,7 @@ UserStore = context.UserStore if @studentMadeDefaultSlot() message = this.slotMessage(this.state.booking.default_slot, 'accept') - if @isRecurring() - detail = `Your {this.lessonDesc()} will take place each {this.slotTime(this.state.booking.default_slot)}
` - else - detail = `Your {this.lessonDesc()} will take place this {this.slotTime(this.state.booking.default_slot)}
` + detail = @createDetail() summary = `Has accepted your lesson request.
@@ -766,10 +870,7 @@ UserStore = context.UserStore if @studentMadeDefaultSlot() message = this.slotMessage(this.state.booking.default_slot, 'accept') - if @isRecurring() - detail = `Your {this.lessonDesc()} will take place each {this.slotTime(this.state.booking.default_slot)}
` - else - detail = `Your {this.lessonDesc()} will take place this {this.slotTime(this.state.booking.default_slot)}
` + detail = @createDetail() summary = `Has accepted your lesson request.
@@ -780,10 +881,7 @@ UserStore = context.UserStore if @studentMadeDefaultSlot() message = this.slotMessage(this.state.booking.default_slot, 'accept') - if @isRecurring() - detail = `Your {this.lessonDesc()} will take place each {this.slotTime(this.state.booking.default_slot)}
` - else - detail = `Your {this.lessonDesc()} will take place this {this.slotTime(this.state.booking.default_slot)}
` + detail = @createDetail() summary = `Your {this.lessonDesc()} will take place each {this.slotTime(this.state.booking.default_slot)}
` - else - detail = `Your {this.lessonDesc()} will take place this {this.slotTime(this.state.booking.default_slot)}
` + detail = @createDetail() summary = `Is ready to take the lesson.
@@ -869,10 +964,7 @@ UserStore = context.UserStore if @studentMadeDefaultSlot() message = this.slotMessage(this.state.booking.default_slot, 'accept') - if @isRecurring() - detail = `Your {this.lessonDesc()} will take place each {this.slotTime(this.state.booking.default_slot)}
` - else - detail = `Your {this.lessonDesc()} will take place this {this.slotTime(this.state.booking.default_slot)}
` + detail = @createDetail() summary = `While you're getting this done, if you want to learn more about all the nifty features you can access in - JamClass and in JamKazam in general, you can check out our online JamClass + JamClass and in JamKazam in general, you can check out our online JamClass User Guide.