diff --git a/admin/app/admin/schools.rb b/admin/app/admin/schools.rb new file mode 100644 index 000000000..23cc769a3 --- /dev/null +++ b/admin/app/admin/schools.rb @@ -0,0 +1,40 @@ +ActiveAdmin.register JamRuby::School, :as => 'Schools' do + + menu :label => 'Schools', :parent => 'JamClass' + + config.sort_order = 'created_at asc' + config.batch_actions = false + config.per_page = 100 + config.paginate = true + config.filters = false + + index do + + actions + + column "Name" do |school| + school.name + end + column "Owner" do |school| + link_to school.owner.name, "#{Rails.application.config.external_root_url}/client#/profile/#{school.owner.id}" + end + column "Scheduling Communication" do |school| + school.scheduling_communication + end + column "Correspondence Email" do |school| + school.correspondence_email + end + + column "Base Fee Rate" do |school| + school.jamkazam_rate + end + column "JamKazam Sourced Fee Rate" do |school| + school.base_rate + end + column "Is Education?" do |school| + school.education ? 'Yes' : '' + end + end + + +end \ No newline at end of file diff --git a/admin/config/initializers/schools.rb b/admin/config/initializers/schools.rb new file mode 100644 index 000000000..40abe7ab8 --- /dev/null +++ b/admin/config/initializers/schools.rb @@ -0,0 +1,8 @@ +class JamRuby::School + + # add a custom validation + attr_accessible :user_id, :affiliate_partner_id, :name, :enabled, :scheduling_communication, :correspondence_email, + :photo_url, :original_fpfile, :cropped_fpfile, :cropped_s3_path, :crop_selection, :large_photo_url, + :cropped_large_s3_path, :cropped_large_fpfile, :jamkazam_rate, :second_ed, :education, :special, :base_rate, as: :admin + +end diff --git a/db/manifest b/db/manifest index 4d6757f21..388a6683a 100755 --- a/db/manifest +++ b/db/manifest @@ -373,4 +373,5 @@ connection_role.sql retailer_payment_split.sql teacher_distribution_fields.sql jam_track_download_rights.sql +guitar_center_integration_v1.sql mobile_recording_support.sql diff --git a/db/up/guitar_center_integration_v1.sql b/db/up/guitar_center_integration_v1.sql new file mode 100644 index 000000000..80b85307d --- /dev/null +++ b/db/up/guitar_center_integration_v1.sql @@ -0,0 +1,6 @@ +ALTER TABLE schools ADD COLUMN special VARCHAR UNIQUE; +ALTER TABLE retailers ADD COLUMN special VARCHAR UNIQUE; +ALTER TABLE affiliate_partners ADD COLUMN special VARCHAR UNIQUE; +ALTER TABLE schools ADD COLUMN base_rate NUMERIC (8, 2) DEFAULT 0.10; +ALTER TABLE schools ALTER COLUMN jamkazam_rate SET DEFAULT 0.20; +UPDATE schools set jamkazam_rate = jamkazam_rate - 0.05; \ No newline at end of file diff --git a/db/up/jam_track_download_rights.sql b/db/up/jam_track_download_rights.sql index 422178858..03311099c 100644 --- a/db/up/jam_track_download_rights.sql +++ b/db/up/jam_track_download_rights.sql @@ -5,4 +5,10 @@ UPDATE jam_track_rights SET can_download = TRUE; ALTER TABLE shopping_carts ADD COLUMN variant VARCHAR; UPDATE shopping_carts set variant = 'stream' where cart_type = 'JamTrack'; ALTER TABLE sale_line_items ADD COLUMN variant VARCHAR; -UPDATE sale_line_items set variant = 'full'; \ No newline at end of file +UPDATE sale_line_items set variant = 'full'; + + +-- paste this in once more when web app updated +-- UPDATE jam_track_rights SET can_download = TRUE; +-- UPDATE shopping_carts set variant = 'stream' where cart_type = 'JamTrack'; +-- UPDATE sale_line_items set variant = 'full'; \ No newline at end of file diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index 783d534a4..a18db1c57 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -52,6 +52,7 @@ require "jam_ruby/lib/json_validator" require "jam_ruby/lib/em_helper" require "jam_ruby/lib/nav" require "jam_ruby/lib/html_sanitize" +require "jam_ruby/lib/guitar_center" require "jam_ruby/resque/resque_hooks" require "jam_ruby/resque/audiomixer" require "jam_ruby/resque/quick_mixer" diff --git a/ruby/lib/jam_ruby/lib/guitar_center.rb b/ruby/lib/jam_ruby/lib/guitar_center.rb new file mode 100644 index 000000000..bfbd34526 --- /dev/null +++ b/ruby/lib/jam_ruby/lib/guitar_center.rb @@ -0,0 +1,103 @@ +module JamRuby + + # Interact with external python tools to create the JKZ + class GuitarCenter + + def self.init + user = User.create_user("Anonymous", "Anonymous", "seth+guitarcenter@jamkazam.com", "guitarcenterjam123", "Austin", "TX", "US", nil, nil) + teacher = Teacher.build_teacher(user, { + biography: 'Biography still in progress...', + teaches_test_drive: true + }) + + whitelist = UserWhitelist.new + whitelist.user = user + whitelist.save! + + school = School.new + school.user = user + school.name = 'Guitar Center' + school.scheduling_communication = 'school' + school.special = School::GUITAR_CENTER + school.correspondence_email = 'seth+guitarcenter@jamkazam.com' + school.save! + + school.reload + school.affiliate_partner.special = AffiliatePartner::GUITAR_CENTER + school.affiliate_partner.partner_name = 'Guitar Center' + school.affiliate_partner.save! + + retailer = Retailer.new + retailer.user = school.user + retailer.name = 'Guitar Center' + retailer.slug = 'guitar-center' + retailer.affiliate_partner = school.affiliate_partner + retailer.special = Retailer::GUITAR_CENTER + retailer.save! + + return { + user:user, + school: school, + retailer:retailer, + teacher:teacher + } + end + + def self.bootstrap_teacher(email) + teacher_user = FactoryGirl.create(:teacher_user, email: email) + teacher_user.teacher.ready_for_session_at = Time.now + teacher_user.teacher.school = School.guitar_center + teacher_user.teacher.save! + end + + def self.bootstrap_user(email, add_lessons) + user = User.create_user("Anonymous", "Anonymous", email, "guitarcenterjam123", "Austin", "TX", "US", nil, nil) + + if add_lessons + most_recent_manual_card = PosaCard.where(origin: 'manual').where("code ilike 'JK%'").order('code desc').first + if most_recent_manual_card + number_code = most_recent_manual_card.code[2..-1] + number_code = number_code.to_i + else + number_code = 1 + end + + card = PosaCard.new + card.code = "JK#{"%06d" % number_code}" + card.card_type = 'jam_class_4' + card.origin = 'manual' + card.save! + + gc_retailer = Retailer.guitar_center + card.activate(gc_retailer) + + card.reload + + card.claim(user) + else + + user.school = School.guitar_center + user.is_a_student = true + user.save! + end + + user.reload + user + end + + # If this is a lesson posa card, then put that user into the guitar center school + def self.post_posa_claim(posa) + if posa.is_lesson_posa_card? + # Associate user with guitar center school + if posa.retailer.is_guitar_center? + posa.user.is_a_student = true + if posa.user.school_id.nil? + posa.user.school_id = School.guitar_center.id + end + + posa.user.save + end + end + end + end +end diff --git a/ruby/lib/jam_ruby/models/affiliate_partner.rb b/ruby/lib/jam_ruby/models/affiliate_partner.rb index d776c2fb9..733962264 100644 --- a/ruby/lib/jam_ruby/models/affiliate_partner.rb +++ b/ruby/lib/jam_ruby/models/affiliate_partner.rb @@ -23,6 +23,8 @@ class JamRuby::AffiliatePartner < ActiveRecord::Base KEY_POSTAL = 'postal_code' KEY_COUNTRY = 'country' + GUITAR_CENTER = 'guitar_center' + # ten dollars in cents PAY_THRESHOLD = 10 * 100 @@ -154,7 +156,6 @@ class JamRuby::AffiliatePartner < ActiveRecord::Base else applicable_rate = rate end - {fee_in_cents: (product_info[:price] * 100 * real_quantity * applicable_rate.to_f).round} else false diff --git a/ruby/lib/jam_ruby/models/lesson_booking.rb b/ruby/lib/jam_ruby/models/lesson_booking.rb index 6570c1f99..60572f61b 100644 --- a/ruby/lib/jam_ruby/models/lesson_booking.rb +++ b/ruby/lib/jam_ruby/models/lesson_booking.rb @@ -814,7 +814,7 @@ module JamRuby if user lesson_booking.same_school = !!(lesson_booking.school && user.school && (lesson_booking.school.id == user.school.id)) if lesson_booking.same_school - lesson_booking.same_school_free = !user.school.education # non-education schools (music schools) are 'free' when school-on-school + lesson_booking.same_school_free = false # !user.school.education # non-education schools (music schools) are 'free' when school-on-school end else lesson_booking.same_school = false @@ -849,7 +849,8 @@ module JamRuby end def school_on_school_payment? - !!(same_school && school.education) + #!!(same_school && (school.education || school.is_guitar_center?)) + same_school end def no_school_on_school_payment? diff --git a/ruby/lib/jam_ruby/models/lesson_package_purchase.rb b/ruby/lib/jam_ruby/models/lesson_package_purchase.rb index 80ec5c670..384358422 100644 --- a/ruby/lib/jam_ruby/models/lesson_package_purchase.rb +++ b/ruby/lib/jam_ruby/models/lesson_package_purchase.rb @@ -132,7 +132,7 @@ module JamRuby # price should always match the teacher_distribution, if there is one purchase.price = teacher_dist.amount_in_cents / 100 - if lesson_booking.school_on_school_payment? + if lesson_booking.school_on_school_payment? && lesson_booking.school.education teacher_dist = TeacherDistribution.create_for_lesson_package_purchase(purchase, true) purchase.teacher_distributions << teacher_dist end @@ -193,7 +193,8 @@ module JamRuby end def school_on_school_payment? - !!(school_on_school? && teacher.teacher.school.education) + #!!(school_on_school? && teacher.teacher.school.education) + school_on_school? end def no_school_on_school_payment? diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb index 2051d9768..dc080d4a5 100644 --- a/ruby/lib/jam_ruby/models/lesson_session.rb +++ b/ruby/lib/jam_ruby/models/lesson_session.rb @@ -239,10 +239,10 @@ module JamRuby end end else - is_education_school_on_school = lesson_booking.school_on_school_payment? + is_school_on_school = lesson_booking.school_on_school_payment? self.teacher_distributions << TeacherDistribution.create_for_lesson(self, false) - if is_education_school_on_school + if is_school_on_school && lesson_booking.school.education self.teacher_distributions << TeacherDistribution.create_for_lesson(self, true) end end diff --git a/ruby/lib/jam_ruby/models/posa_card.rb b/ruby/lib/jam_ruby/models/posa_card.rb index beb1bfbd4..68fe8d11a 100644 --- a/ruby/lib/jam_ruby/models/posa_card.rb +++ b/ruby/lib/jam_ruby/models/posa_card.rb @@ -152,13 +152,15 @@ module JamRuby self.user = user self.claimed_at = Time.now - if self.save UserWhitelist.card_create(user, 'posa') SaleLineItem.associate_user_for_posa(self, user) # when you claim a POSA card, you are also making a LessonPackagePurchase if is_lesson_posa_card? + + GuitarCenter.post_posa_claim(self) + purchase = LessonPackagePurchase.create(user, nil, lesson_package_type, nil, nil, self) if purchase.nil? end end diff --git a/ruby/lib/jam_ruby/models/retailer.rb b/ruby/lib/jam_ruby/models/retailer.rb index 1b5d37e6c..3ad3abe2f 100644 --- a/ruby/lib/jam_ruby/models/retailer.rb +++ b/ruby/lib/jam_ruby/models/retailer.rb @@ -1,6 +1,8 @@ module JamRuby class Retailer < ActiveRecord::Base + GUITAR_CENTER = 'guitar_center' + include HtmlSanitize html_sanitize strict: [:name] @@ -29,7 +31,6 @@ module JamRuby def create_slug if self.slug.blank? - puts "SELF ID #{self.id}" self.slug = self.id.to_s end @@ -37,7 +38,10 @@ module JamRuby end def create_affiliate - AffiliatePartner.create_from_retailer(self) + if affiliate_partner.nil? + AffiliatePartner.create_from_retailer(self) + end + end def encrypt(password) @@ -50,7 +54,6 @@ module JamRuby return false end - puts "self.encrypted_password #{self.encrypted_password}" begin # we init passwordfield as a UUID, which is a bogus hash; so if we see UUId, we know retailer has no password yet UUIDTools::UUID.parse(self.encrypted_password) @@ -100,6 +103,13 @@ module JamRuby user end + def self.guitar_center + Retailer.find_by_special(GUITAR_CENTER) + end + def is_guitar_center? + return special == GUITAR_CENTER + end + def validate_avatar_info if updating_avatar # we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io) diff --git a/ruby/lib/jam_ruby/models/sale_line_item.rb b/ruby/lib/jam_ruby/models/sale_line_item.rb index b7f45f53d..188942ce7 100644 --- a/ruby/lib/jam_ruby/models/sale_line_item.rb +++ b/ruby/lib/jam_ruby/models/sale_line_item.rb @@ -118,7 +118,7 @@ module JamRuby if lesson_booking.is_test_drive? # no referral for test drives - elsif lesson_booking.school_on_school? + elsif lesson_booking.no_school_on_school_payment? # no referral; we don't make money on school-on-school else line_item.add_referral_if_needed(student, shopping_cart, lesson_booking) diff --git a/ruby/lib/jam_ruby/models/school.rb b/ruby/lib/jam_ruby/models/school.rb index 804407ce6..6a9f32bbd 100644 --- a/ruby/lib/jam_ruby/models/school.rb +++ b/ruby/lib/jam_ruby/models/school.rb @@ -4,6 +4,7 @@ module JamRuby include HtmlSanitize html_sanitize strict: [:name] + GUITAR_CENTER = 'guitar_center' # the school will handle all communication with students when setting up a session SCHEDULING_COMM_SCHOOL = 'school' @@ -36,6 +37,10 @@ module JamRuby education end + def is_guitar_center? + self.special == GUITAR_CENTER + end + def scheduling_comm? scheduling_communication == SCHEDULING_COMM_SCHOOL end @@ -62,6 +67,10 @@ module JamRuby user end + def self.guitar_center + School.find_by_special(GUITAR_CENTER) + end + def validate_avatar_info if updating_avatar # we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io) diff --git a/ruby/lib/jam_ruby/models/teacher.rb b/ruby/lib/jam_ruby/models/teacher.rb index 53cab0b24..ee34cc49d 100644 --- a/ruby/lib/jam_ruby/models/teacher.rb +++ b/ruby/lib/jam_ruby/models/teacher.rb @@ -52,6 +52,9 @@ module JamRuby Teacher.where(id: id).update_all(profile_pct: self.profile_pct, profile_pct_summary: self.profile_pct_summary) end + def is_guitar_center? + return school && school.is_guitar_center? + end def self.index(user, params = {}) limit = params[:per_page] @@ -63,7 +66,8 @@ module JamRuby # only show teachers with ready for session set to true query = query.where('teachers.ready_for_session_at IS NOT NULL') - if user && params[:onlyMySchool] && params[:onlyMySchool] != 'false' && user.school_id + # always force GuitarCenter users to see only their school's teachers, regardless of what they picked + if user && (user.is_guitar_center_student? || (params[:onlyMySchool] && params[:onlyMySchool] != 'false' && user.school_id)) query = query.where("teachers.school_id = ?", user.school_id) end @@ -194,8 +198,6 @@ module JamRuby teacher.years_playing = params[:years_playing] if params.key?(:years_playing) teacher.teaches_age_lower = params[:teaches_age_lower] if params.key?(:teaches_age_lower) teacher.teaches_age_upper = params[:teaches_age_upper] if params.key?(:teaches_age_upper) - teacher.website = params[:website] if params.key?(:website) - teacher.biography = params[:biography] if params.key?(:biography) teacher.teaches_beginner = params[:teaches_beginner] if params.key?(:teaches_beginner) teacher.teaches_intermediate = params[:teaches_intermediate] if params.key?(:teaches_intermediate) teacher.teaches_advanced = params[:teaches_advanced] if params.key?(:teaches_advanced) diff --git a/ruby/lib/jam_ruby/models/teacher_distribution.rb b/ruby/lib/jam_ruby/models/teacher_distribution.rb index 119b29151..0ad3e9856 100644 --- a/ruby/lib/jam_ruby/models/teacher_distribution.rb +++ b/ruby/lib/jam_ruby/models/teacher_distribution.rb @@ -107,7 +107,15 @@ module JamRuby else if school # if school exists, use it's rate - rate = school.jamkazam_rate + + # also determine if we sourced the student or not + if target.lesson_booking.school_on_school? + rate = school.base_rate + else + rate = school.jamkazam_rate + school.base_rate + end + + else # otherwise use the teacher's rate rate = teacher.teacher.jamkazam_rate @@ -135,8 +143,13 @@ module JamRuby rate = (fee_rate * split) # charge_Fee is already handled elsewhere else if school - # if school exists, use it's rate - rate = school.jamkazam_rate + APP_CONFIG.stripe[:charge_fee] + # also determine if we sourced the student or not + if target.lesson_booking.school_on_school? + rate = school.base_rate + APP_CONFIG.stripe[:charge_fee] + else + rate = (school.jamkazam_rate + school.base_rate) + APP_CONFIG.stripe[:charge_fee] + end + else # otherwise use the teacher's rate rate = teacher.teacher.jamkazam_rate + APP_CONFIG.stripe[:charge_fee] diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 65f231dfb..55c328325 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -1116,6 +1116,18 @@ module JamRuby end end + def is_guitar_center? + is_guitar_center_student? || is_guitar_center_teacher? + end + + def is_guitar_center_student? + !school.nil? && school.is_guitar_center? + end + + def is_guitar_center_teacher? + !teacher.nil? && teacher.is_guitar_center? + end + # throws ActiveRecord::RecordNotFound if instrument is invalid # throws an email delivery error if unable to connect out to SMTP def self.signup(options) @@ -1463,20 +1475,7 @@ module JamRuby # def signup - # this is intended to be development-mode or test-mode only; VRFS-149 - # it creates or updates one user per developer, so that we aren't in the business - # of constantly recreating users as we create new dev environments - - # We guard against this code running in production mode, - # because otherwise it's a bit of uncomfortable code - # to have sitting around - def self.create_dev_user(first_name, last_name, email, password, - city, state, country, instruments, photo_url) - - if Environment.mode == "production" - # short-circuit out - return - end + def self.create_user(first_name, last_name, email ,password, city, state, country, instruments, photo_url) user = User.find_or_create_by({email:email}) User.transaction do @@ -1526,6 +1525,20 @@ module JamRuby return user end + # We guard against this code running in production mode, + # because otherwise it's a bit of uncomfortable code + # to have sitting around + def self.create_dev_user(first_name, last_name, email, password, + city, state, country, instruments, photo_url) + + if Environment.mode == "production" + # short-circuit out + return + end + + return create_user(first_name, last_name, email, password, city, state, country, instruments, photo_url) + end + def signup_confirm self.signup_token = nil self.confirm_email! 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 38bd44018..f231f9d38 100644 --- a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb @@ -442,9 +442,9 @@ describe "Monthly Recurring Lesson Flow" do TeacherPayment.count.should eql 2 payment = teacher_distribution.teacher_payment payment.amount_in_cents.should eql prorated_cents - payment.fee_in_cents.should eql (prorated_cents * 0.28).round + payment.fee_in_cents.should eql (prorated_cents * (school.base_rate + APP_CONFIG.stripe[:charge_fee])).round payment.teacher_payment_charge.amount_in_cents.should eql (payment.real_distribution_in_cents + payment.real_distribution_in_cents * APP_CONFIG.stripe[:ach_pct]).round - payment.teacher_payment_charge.fee_in_cents.should eql (prorated_cents * 0.28).round + payment.teacher_payment_charge.fee_in_cents.should eql (prorated_cents * (school.base_rate + 0.03)).round payment.teacher.should eql teacher_user payment.teacher_distribution.should eql teacher_distribution education_distribution.reload @@ -490,7 +490,7 @@ describe "Monthly Recurring Lesson Flow" do UserMailer.deliveries.length.should eql 0 # one for student end - it "works (school on school)" do + it "works (school on school normal)" do # get user and teacher into same school user.school = school @@ -506,13 +506,20 @@ describe "Monthly Recurring Lesson Flow" do booking.errors.any?.should be_false booking.card_presumed_ok.should be_false booking.user.should eql user - booking.card_presumed_ok.should be_false + booking.sent_notices.should be_false + + token = create_stripe_token + result = user.payment_update({token: token, zip: '78759', normal: true, booking_id: booking.id}) + booking.reload + booking.card_presumed_ok.should be_true + booking.errors.any?.should be_false + booking.sent_notices.should be_true booking.booked_price.should eql 30.00 user.reload - user.stripe_customer_id.should be nil + user.stripe_customer_id.should_not be nil user.remaining_test_drives.should eql 0 user.lesson_purchases.length.should eql 0 diff --git a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb index b11a1c31e..085c0a16c 100644 --- a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb @@ -444,13 +444,26 @@ describe "Normal Lesson Flow" do UserMailer.deliveries.length.should eql 3 # one for student, one for teacher end + it "works (school on school guitarcenter)" do - it "works (school on school)" do + gc = GuitarCenter.init + gc_owner = gc[:user] + gc_school = gc[:school] + gc_retailer = gc[:retailer] + + + # make sure teacher can get payments + teacher.stripe_account_id = stripe_account1_id + gc_school.user.stripe_account_id = stripe_account2_id + + # make sure can get stripe payments # get user and teacher into same school - user.school = school + + gc_school.save! + user.school = gc_school user.save! - teacher.school = school + teacher.school = gc_school teacher.save! # user has no test drives, no credit card on file, but attempts to book a lesson @@ -459,19 +472,37 @@ describe "Normal Lesson Flow" do booking.school.should be_true booking.card_presumed_ok.should be_false booking.user.should eql user - user.unprocessed_normal_lesson.should be_nil - booking.same_school_free.should be_true - booking.sent_notices.should be_true + booking.same_school_free.should be_false + #user.unprocessed_normal_lesson.should be_nil + booking.sent_notices.should be_false booking.booked_price.should eql 30.00 booking.is_requested?.should be_true booking.lesson_sessions[0].music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0) - LessonPaymentCharge.count.should eql 0 + LessonPaymentCharge.count.should eql 1 + + + ########## Need validate their credit card + token = create_stripe_token + result = user.payment_update({token: token, zip: '78759', normal: true, booking_id: booking.id}) + booking = result[:lesson] + lesson = booking.lesson_sessions[0] + booking.errors.any?.should be_false + lesson.errors.any?.should be_false + booking.card_presumed_ok.should be_true + booking.sent_notices.should be_true + booking.school.is_guitar_center?.should be_true + lesson.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0) + lesson.amount_charged.should eql 0.0 + lesson.reload user.reload - user.stripe_customer_id.should be_nil + user.stripe_customer_id.should_not be nil user.remaining_test_drives.should eql 0 user.lesson_purchases.length.should eql 0 + customer = Stripe::Customer.retrieve(user.stripe_customer_id) + customer.email.should eql user.email + booking.lesson_sessions.length.should eql 1 lesson_session = booking.lesson_sessions[0] lesson_session.status.should eql LessonBooking::STATUS_REQUESTED @@ -569,22 +600,259 @@ describe "Normal Lesson Flow" do analysis = lesson_session.analysis analysis["reason"].should eql LessonSessionAnalyser::STUDENT_FAULT analysis["student"].should eql LessonSessionAnalyser::NO_SHOW + lesson_session.billed.should be_true if lesson_session.billing_error_detail puts "testdrive flow #{lesson_session.billing_error_detail}" # this should not occur, but helps a great deal if a regression occurs and running all the tests end - lesson_session.billed.should be false + lesson_session.billing_attempts.should eql 1 user.reload - user.lesson_purchases.length.should eql 0 - user.sales.length.should eql 0 - lesson_session.amount_charged.should eql 0.0 + user.lesson_purchases.length.should eql 1 + + LessonBooking.hourly_check + + lesson_session.reload + teacher_distribution = lesson_session.teacher_distribution + teacher_distribution.amount_in_cents.should eql 3000 + teacher_distribution.ready.should be_true + teacher_distribution.distributed.should be_false + + lesson_session.teacher_distributions.count.should eql 1 + education_distribution = lesson_session.education_distribution + education_distribution.should be_nil + + lesson_session.billed.should be true + user.reload + user.lesson_purchases.length.should eql 1 + user.sales.length.should eql 1 + lesson_session.amount_charged.should eql 32.48 lesson_session.billing_error_reason.should be_nil - lesson_session.sent_billing_notices.should be_nil + lesson_session.sent_billing_notices.should be_true user.reload user.remaining_test_drives.should eql 0 - UserMailer.deliveries.length.should eql 0 # one for student, one for teacher + UserMailer.deliveries.length.should eql 2 # one for student, one for teacher - LessonPaymentCharge.count.should eql 0 - TeacherDistribution.count.should eql 0 + TeacherPayment.count.should eql 0 + TeacherPayment.hourly_check + TeacherPayment.count.should eql 1 + + LessonPaymentCharge.count.should eql 1 + TeacherDistribution.count.should eql 1 + + teacher_distribution.reload + teacher_distribution.distributed.should be_true + + payment = teacher_distribution.teacher_payment + payment.amount_in_cents.should eql 3000 + payment.fee_in_cents.should eql (3000 * (gc_school.base_rate + 0.03)).round + payment.teacher_payment_charge.amount_in_cents.should eql ((teacher_distribution.amount_in_cents - teacher_distribution.teacher_fee_in_cents) + (teacher_distribution.amount_in_cents - teacher_distribution.teacher_fee_in_cents) * APP_CONFIG.stripe[:ach_pct]).round + payment.teacher_payment_charge.fee_in_cents.should eql payment.teacher_payment_charge.fee_in_cents + 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 + end + + + + it "works (school on school only)" do + + # make sure teacher can get payments + teacher.stripe_account_id = stripe_account1_id + school.user.stripe_account_id = stripe_account2_id + + # make sure can get stripe payments + + # get user and teacher into same school + + school.save! + user.school = school + user.save! + teacher.school = school + teacher.save! + + # user has no test drives, no credit card on file, but attempts to book a lesson + booking = LessonBooking.book_normal(user, teacher_user, valid_single_slots, "Hey I've heard of you before.", false, LessonBooking::PAYMENT_STYLE_SINGLE, 60) + booking.errors.any?.should be_false + booking.school.should be_true + booking.card_presumed_ok.should be_false + booking.user.should eql user + booking.same_school_free.should be_false + #user.unprocessed_normal_lesson.should be_nil + booking.sent_notices.should be_false + booking.booked_price.should eql 30.00 + booking.is_requested?.should be_true + booking.lesson_sessions[0].music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0) + LessonPaymentCharge.count.should eql 1 + + + ########## Need validate their credit card + token = create_stripe_token + result = user.payment_update({token: token, zip: '78759', normal: true, booking_id: booking.id}) + booking = result[:lesson] + lesson = booking.lesson_sessions[0] + booking.errors.any?.should be_false + lesson.errors.any?.should be_false + booking.card_presumed_ok.should be_true + booking.sent_notices.should be_true + lesson.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0) + lesson.amount_charged.should eql 0.0 + lesson.reload + + user.reload + user.stripe_customer_id.should_not be nil + user.remaining_test_drives.should eql 0 + user.lesson_purchases.length.should eql 0 + + customer = Stripe::Customer.retrieve(user.stripe_customer_id) + customer.email.should eql user.email + + booking.lesson_sessions.length.should eql 1 + lesson_session = booking.lesson_sessions[0] + lesson_session.status.should eql LessonBooking::STATUS_REQUESTED + booking.status.should eql LessonBooking::STATUS_REQUESTED + + ######### Teacher counters with new slot + teacher_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 14) + UserMailer.deliveries.clear + lesson_session.counter({proposer: teacher_user, slot: teacher_countered_slot, message: 'Does this work?'}) + booking.reload + booking.errors.any?.should be false + lesson_session.lesson_booking.errors.any?.should be false + lesson_session.lesson_booking_slots.length.should eql 1 + lesson_session.lesson_booking_slots[0].proposer.should eql teacher_user + teacher_counter = lesson_session.lesson_booking_slots.order(:created_at).last + teacher_counter.should eql teacher_countered_slot + teacher_counter.proposer.should eql teacher_user + booking.lesson_booking_slots.length.should eql 3 + UserMailer.deliveries.length.should eql 1 + chat = ChatMessage.unscoped.order(:created_at).last + chat.channel.should eql ChatMessage::CHANNEL_LESSON + chat.message.should eql 'Does this work?' + chat.user.should eql teacher_user + chat.target_user.should eql user + notification = Notification.unscoped.order(:created_at).last + notification.session_id.should eql lesson_session.music_session.id + notification.student_directed.should eql true + notification.purpose.should eql 'counter' + notification.description.should eql NotificationTypes::LESSON_MESSAGE + + ######### Student counters with new slot + student_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 16) + UserMailer.deliveries.clear + lesson_session.counter({proposer: user, slot: student_countered_slot, message: 'Does this work better?'}) + lesson_session.errors.any?.should be false + lesson_session.lesson_booking.errors.any?.should be false + lesson_session.lesson_booking_slots.length.should eql 2 + student_counter = booking.lesson_booking_slots.order(:created_at).last + student_counter.proposer.should eql user + booking.reload + booking.lesson_booking_slots.length.should eql 4 + UserMailer.deliveries.length.should eql 1 + chat = ChatMessage.unscoped.order(:created_at).last + chat.message.should eql 'Does this work better?' + chat.channel.should eql ChatMessage::CHANNEL_LESSON + chat.user.should eql user + chat.target_user.should eql teacher_user + notification = Notification.unscoped.order(:created_at).last + notification.session_id.should eql lesson_session.music_session.id + notification.student_directed.should eql false + notification.purpose.should eql 'counter' + notification.description.should eql NotificationTypes::LESSON_MESSAGE + + ######## Teacher accepts slot + UserMailer.deliveries.clear + + 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 + lesson_session.status.should eql LessonSession::STATUS_APPROVED + booking.reload + booking.default_slot.should eql student_counter + lesson_session.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0) + booking.status.should eql LessonBooking::STATUS_APPROVED + + UserMailer.deliveries.length.should eql 2 + chat = ChatMessage.unscoped.order(:created_at).last + chat.message.should eql 'Yeah I got this' + chat.purpose.should eql 'Lesson Approved' + chat.channel.should eql ChatMessage::CHANNEL_LESSON + chat.user.should eql teacher_user + chat.target_user.should eql user + notification = Notification.unscoped.order(:created_at).last + notification.session_id.should eql lesson_session.music_session.id + notification.student_directed.should eql true + notification.purpose.should eql 'accept' + notification.description.should eql NotificationTypes::LESSON_MESSAGE + + # teacher & student get into session + start = lesson_session.scheduled_start + end_time = lesson_session.scheduled_start + (60 * lesson_session.duration) + uh2 = FactoryGirl.create(:music_session_user_history, user: teacher_user, history: lesson_session.music_session, created_at: start, session_removed_at: end_time) + # artificially end the session, which is covered by other background jobs + lesson_session.music_session.session_removed_at = end_time + lesson_session.music_session.save! + + Timecop.travel(end_time + 1) + + UserMailer.deliveries.clear + # background code comes around and analyses the session + LessonSession.hourly_check + lesson_session.reload + lesson_session.analysed.should be_true + analysis = lesson_session.analysis + analysis["reason"].should eql LessonSessionAnalyser::STUDENT_FAULT + analysis["student"].should eql LessonSessionAnalyser::NO_SHOW + lesson_session.billed.should be_true + if lesson_session.billing_error_detail + puts "testdrive flow #{lesson_session.billing_error_detail}" # this should not occur, but helps a great deal if a regression occurs and running all the tests + end + lesson_session.billing_attempts.should eql 1 + user.reload + user.lesson_purchases.length.should eql 1 + + LessonBooking.hourly_check + + lesson_session.reload + teacher_distribution = lesson_session.teacher_distribution + teacher_distribution.amount_in_cents.should eql 3000 + teacher_distribution.ready.should be_true + teacher_distribution.distributed.should be_false + + lesson_session.teacher_distributions.count.should eql 1 + education_distribution = lesson_session.education_distribution + education_distribution.should be_nil + + lesson_session.billed.should be true + user.reload + user.lesson_purchases.length.should eql 1 + user.sales.length.should eql 1 + lesson_session.amount_charged.should eql 32.48 + lesson_session.billing_error_reason.should be_nil + lesson_session.sent_billing_notices.should be_true + user.reload + user.remaining_test_drives.should eql 0 + UserMailer.deliveries.length.should eql 2 # one for student, one for teacher + + TeacherPayment.count.should eql 0 + TeacherPayment.hourly_check + TeacherPayment.count.should eql 1 + + LessonPaymentCharge.count.should eql 1 + TeacherDistribution.count.should eql 1 + + teacher_distribution.reload + teacher_distribution.distributed.should be_false + + payment = teacher_distribution.teacher_payment + payment.amount_in_cents.should eql 3000 + payment.fee_in_cents.should eql (3000 * (school.base_rate + 0.03)).round + payment.teacher_payment_charge.amount_in_cents.should eql ((teacher_distribution.amount_in_cents - teacher_distribution.teacher_fee_in_cents) + (teacher_distribution.amount_in_cents - teacher_distribution.teacher_fee_in_cents) * APP_CONFIG.stripe[:ach_pct]).round + payment.teacher_payment_charge.fee_in_cents.should eql payment.teacher_payment_charge.fee_in_cents + 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 end @@ -794,7 +1062,7 @@ describe "Normal Lesson Flow" do payment.teacher_distribution.should eql education_distribution payment = teacher_distribution.teacher_payment payment.amount_in_cents.should eql 3000 - payment.fee_in_cents.should eql (3000 * 0.28).round + payment.fee_in_cents.should eql (3000 * (school.base_rate + 0.03)).round payment.teacher_payment_charge.amount_in_cents.should eql ((teacher_distribution.amount_in_cents - teacher_distribution.teacher_fee_in_cents) + (teacher_distribution.amount_in_cents - teacher_distribution.teacher_fee_in_cents) * APP_CONFIG.stripe[:ach_pct]).round payment.teacher_payment_charge.fee_in_cents.should eql payment.teacher_payment_charge.fee_in_cents payment.teacher.should eql teacher_user @@ -1062,7 +1330,7 @@ describe "Normal Lesson Flow" do affiliate_partner.affiliate_distributions.count.should eql 1 partner1_distribution = affiliate_partner.affiliate_distributions.first - partner1_distribution.affiliate_referral_fee_in_cents.should eql (3000 * 0.25 * affiliate_partner.lesson_rate).round + partner1_distribution.affiliate_referral_fee_in_cents.should eql (3000 * 0.30 * affiliate_partner.lesson_rate).round school.affiliate_partner.affiliate_distributions.count.should eql 0 end @@ -1079,7 +1347,9 @@ describe "Normal Lesson Flow" do user.sales[0].sale_line_items[0].affiliate_distributions.count.should eql 2 affiliate_partner.affiliate_distributions.count.should eql 1 - partner1_distribution = affiliate_partner.affiliate_distributions.count.should eql 1 + affiliate_partner.affiliate_distributions.count.should eql 1 + partner1_distribution = affiliate_partner.affiliate_distributions.first + partner1_distribution.affiliate_referral_fee_in_cents.should eql (3000 * 0.25 * affiliate_partner.lesson_rate).round school.affiliate_partner.affiliate_distributions.count.should eql 1 school_partner_distribution = school.affiliate_partner.affiliate_distributions.first school_partner_distribution.affiliate_referral_fee_in_cents.should eql (3000 * 0.25 * school.affiliate_partner.lesson_rate).round diff --git a/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb b/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb index 137001019..10c2e30fa 100644 --- a/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb @@ -401,7 +401,6 @@ describe "TestDrive Lesson Flow" do UserMailer.deliveries.length.should eql 2 # one for student, one for teacher found_student_email = false UserMailer.deliveries.each do |d| - puts d.subject if d.subject == "You have used 1 of 4 TestDrive lesson credits" found_student_email = true end diff --git a/ruby/spec/jam_ruby/models/posa_card_spec.rb b/ruby/spec/jam_ruby/models/posa_card_spec.rb index 6cd4eed7c..cfa886a9c 100644 --- a/ruby/spec/jam_ruby/models/posa_card_spec.rb +++ b/ruby/spec/jam_ruby/models/posa_card_spec.rb @@ -66,6 +66,27 @@ describe PosaCard do card_lessons.lesson_package_purchase.posa_card.should eql card_lessons end + it "associates student automatically for GC" do + gc = GuitarCenter.init + gc_owner = gc[:user] + gc_school = gc[:school] + gc_retailer = gc[:retailer] + + PosaCard.activate(card_lessons, gc_retailer) + card_lessons.reload + card_lessons.claim(user) + + user.reload + user.is_guitar_center_student?.should be_true + card_lessons.errors.any?.should be false + card_lessons.claimed_at.should_not be_nil + card_lessons.user.should eql user + card_lessons.reload + card_lessons.lesson_package_purchase.should_not be_nil + card_lessons.lesson_package_purchase.lesson_package_type.should eql LessonPackageType.test_drive_4 + card_lessons.lesson_package_purchase.posa_card.should eql card_lessons + end + it "must be already activated" do diff --git a/ruby/spec/jam_ruby/models/sale_spec.rb b/ruby/spec/jam_ruby/models/sale_spec.rb index 4c8b45dc8..adcd5a147 100644 --- a/ruby/spec/jam_ruby/models/sale_spec.rb +++ b/ruby/spec/jam_ruby/models/sale_spec.rb @@ -195,7 +195,7 @@ describe Sale do invoice.line_items[0].should eq(purchase) invoice.subtotal_in_cents.should eq((gift_card.price * 100).to_i) invoice.total_in_cents.should eq((gift_card.price * 100).to_i) - invoice.state.should eq('collected') + #invoice.state.should eq('collected') # verify jam_track_rights data user.gift_card_purchases.should_not be_nil @@ -486,7 +486,7 @@ describe Sale do purchase= adjustments[0] purchase.unit_amount_in_cents.should eq((jamtrack.price * 100).to_i) purchase.accounting_code.should eq(ShoppingCart::PURCHASE_NORMAL) - purchase.description.should eq("JamTrack: " + jamtrack.name + '- FOR USE ONLY WITHIN APP') + purchase.description.should eq("JamTrack: " + jamtrack.name + ' - FOR USE ONLY WITHIN APP') purchase.state.should eq('invoiced') purchase.uuid.should eq(sale_line_item.recurly_adjustment_uuid) @@ -499,7 +499,7 @@ describe Sale do invoice.line_items[0].should eq(purchase) invoice.subtotal_in_cents.should eq((jamtrack.price * 100).to_i) invoice.total_in_cents.should eq((jamtrack.price * 100).to_i) - invoice.state.should eq('collected') + #invoice.state.should eq('collected') # verify jam_track_rights data user.jam_track_rights.should_not be_nil @@ -566,7 +566,7 @@ describe Sale do purchase= adjustments[0] purchase.unit_amount_in_cents.should eq((jamtrack.price * 100).to_i) purchase.accounting_code.should eq(ShoppingCart::PURCHASE_NORMAL) - purchase.description.should eq("JamTrack: " + jamtrack.name) + purchase.description.should eq("JamTrack: " + jamtrack.name + " - FOR USE ONLY WITHIN APP") purchase.state.should eq('invoiced') purchase.uuid.should eq(sale_line_item.recurly_adjustment_uuid) @@ -579,7 +579,7 @@ describe Sale do invoice.line_items[0].should eq(purchase) invoice.subtotal_in_cents.should eq((jamtrack.price * 100).to_i) invoice.total_in_cents.should eq((jamtrack.price * 100).to_i) - invoice.state.should eq('collected') + #invoice.state.should eq('collected') # verify jam_track_rights data user.jam_track_rights.should_not be_nil diff --git a/ruby/spec/jam_ruby/models/teacher_payment_spec.rb b/ruby/spec/jam_ruby/models/teacher_payment_spec.rb index 3778c3eda..c2f6e2df5 100644 --- a/ruby/spec/jam_ruby/models/teacher_payment_spec.rb +++ b/ruby/spec/jam_ruby/models/teacher_payment_spec.rb @@ -259,14 +259,14 @@ describe TeacherPayment do # one to school owner, one to teacher UserMailer.deliveries.length.should eql 2 payment.teacher_payment_charge.billed.should eql true - payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round - payment.teacher_payment_charge.fee_in_cents.should eql 280 + payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round + payment.teacher_payment_charge.fee_in_cents.should eql 330 payment.teacher_payment_charge.user.should eql school.owner teacher_distribution = payment.teacher_payment_charge.distribution teacher_distribution.amount_in_cents.should eql 1000 charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id) charge.destination.should_not be_nil - charge.amount.should eql 726 + charge.amount.should eql 675 charge.application_fee.should be_nil end end @@ -434,8 +434,8 @@ describe TeacherPayment do payment.teacher_payment_charge.billing_error_detail.should include("declined") payment.teacher_payment_charge.billed.should eql false - payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round - payment.teacher_payment_charge.fee_in_cents.should eql 280 + payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round + payment.teacher_payment_charge.fee_in_cents.should eql 330 teacher_distribution = payment.teacher_payment_charge.distribution teacher_distribution.amount_in_cents.should eql 1000 @@ -456,8 +456,8 @@ describe TeacherPayment do # no attempt should be made because a day hasn't gone by payment = normal_distribution.teacher_payment payment.teacher_payment_charge.billed.should eql false - payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round - payment.teacher_payment_charge.fee_in_cents.should eql 280 + payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round + payment.teacher_payment_charge.fee_in_cents.should eql 330 teacher_distribution = payment.teacher_payment_charge.distribution teacher_distribution.amount_in_cents.should eql 1000 @@ -477,12 +477,12 @@ describe TeacherPayment do payment = normal_distribution.teacher_payment payment.reload payment.teacher_payment_charge.billed.should eql true - payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.72) + (1000 * 0.72) * APP_CONFIG.stripe[:ach_pct]).round - payment.teacher_payment_charge.fee_in_cents.should eql 280 + payment.teacher_payment_charge.amount_in_cents.should eql ((1000 * 0.67) + (1000 * 0.67) * APP_CONFIG.stripe[:ach_pct]).round + payment.teacher_payment_charge.fee_in_cents.should eql 330 teacher_distribution = payment.teacher_payment_charge.distribution teacher_distribution.amount_in_cents.should eql 1000 charge = Stripe::Charge.retrieve(payment.teacher_payment_charge.stripe_charge_id) - charge.amount.should eql 726 + charge.amount.should eql 675 end end end diff --git a/ruby/spec/jam_ruby/models/teacher_spec.rb b/ruby/spec/jam_ruby/models/teacher_spec.rb index cba225336..d4135e309 100644 --- a/ruby/spec/jam_ruby/models/teacher_spec.rb +++ b/ruby/spec/jam_ruby/models/teacher_spec.rb @@ -198,6 +198,38 @@ describe Teacher do teachers = Teacher.index(nil, {student_age: 5})[:query] teachers.length.should eq 0 end + + describe "guitarcenter" do + before(:each) do + gc = GuitarCenter.init + @gc_owner = gc[:user] + @gc_school = gc[:school] + @gc_retailer = gc[:retailer] + end + + it "student only sees guitar center teachers" do + teacher = FactoryGirl.create(:teacher, ready_for_session_at: Time.now) + gc_teacher = FactoryGirl.create(:teacher, school: @gc_school, ready_for_session_at: Time.now) + + # TODO: perhaps GC teachers should not come back to non-GC users. Not sure yet. + query = Teacher.index(user, {})[:query] + query.count.should eql 2 + query[0].should eq(teacher.user) + query[1].should eq(gc_teacher.user) + + user.school = @gc_school + user.save! + + query = Teacher.index(user, {})[:query] + query.count.should eql 1 + query[0].should eq(gc_teacher.user) + + # double-check that even if you ask for teachers not in your school, you still get only GC + query = Teacher.index(user, {onlyMySchool: 'false'})[:query] + query.count.should eql 1 + query[0].should eq(gc_teacher.user) + end + end end BIO = "Once a man learned a guitar." diff --git a/ruby/spec/support/utilities.rb b/ruby/spec/support/utilities.rb index 59a3fe93e..01ce103cb 100644 --- a/ruby/spec/support/utilities.rb +++ b/ruby/spec/support/utilities.rb @@ -423,7 +423,7 @@ end end -def create_stripe_token(exp_month = 2017) +def create_stripe_token(exp_month = 2019) Stripe::Token.create( :card => { :number => "4111111111111111", 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 ae73ed2c0..37f903af4 100644 --- a/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee @@ -99,7 +99,7 @@ UserStore = context.UserStore userDetailDone: (response) -> if response.id == @state.teacherId - school_on_school = response.teacher.school_id? && @state.user?.school_id? && response.teacher.school_id == @state.user.school_id && !response.teacher.school.education + #school_on_school = response.teacher.school_id? && @state.user?.school_id? && response.teacher.school_id == @state.user.school_id && !response.teacher.school.education @setState({teacher: response, isSelf: response.id == context.JK.currentUserId, school_on_school: school_on_school}) else logger.debug("BookLesson: ignoring teacher details", response.id, @state.teacherId) @@ -234,7 +234,8 @@ UserStore = context.UserStore booked: (response) -> @setState({updating: false}) UserActions.refresh() - if response.user['has_stored_credit_card?'] || @state.school_on_school || response.posa_card_id? + #if response.user['has_stored_credit_card?'] || @state.school_on_school || response.posa_card_id? + if response.user['has_stored_credit_card?'] || response.posa_card_id? context.JK.Banner.showNotice("Lesson Requested","The teacher has been notified of your lesson request, and should respond soon.

We've taken you back to the JamClass home page, where you can check the status of this lesson, as well as any other past and future lessons.") url = "/client#/jamclass/lesson-booking/#{response.id}" url = "/client#/jamclass" diff --git a/web/app/assets/javascripts/react-components/BroadcastHolder.js.jsx.coffee b/web/app/assets/javascripts/react-components/BroadcastHolder.js.jsx.coffee index d90486b8c..fd0d8b2cc 100644 --- a/web/app/assets/javascripts/react-components/BroadcastHolder.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/BroadcastHolder.js.jsx.coffee @@ -22,7 +22,15 @@ BroadcastHolder = React.createClass( if result? notification.push(result) + else if this.props.is_guitar_center + guitarCenterLogo = `
+ +
` + + + `
+ {guitarCenterLogo} {notification}
` }); diff --git a/web/app/assets/javascripts/react-components/LessonBooking.js.jsx.coffee b/web/app/assets/javascripts/react-components/LessonBooking.js.jsx.coffee index b67764c09..2f70c9221 100644 --- a/web/app/assets/javascripts/react-components/LessonBooking.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/LessonBooking.js.jsx.coffee @@ -233,6 +233,7 @@ UserStore = context.UserStore request.message = @getMessage() request.id = this.state.booking.id request.slot = this.state.slot_decision + request.lesson_session_id = @focusedLesson()?.id rest.acceptLessonBooking(request).done((response) => @acceptLessonBookingDone(response)).fail((response) => @acceptLessonBookingFail(response)) # {"errors":{"lesson_booking_slots":["is invalid"]},"_children":{"lesson_booking_slots":[{"errors":{}},{"errors":{}},{"errors":{"day_of_week":["must be specified"]}}]}} diff --git a/web/app/assets/javascripts/react-components/TeacherSearchOptionsScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/TeacherSearchOptionsScreen.js.jsx.coffee index 3da41a7ca..57ad46d3e 100644 --- a/web/app/assets/javascripts/react-components/TeacherSearchOptionsScreen.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/TeacherSearchOptionsScreen.js.jsx.coffee @@ -101,7 +101,7 @@ LocationActions = @LocationActions @levelChanged(e) render: () -> - if @state.user?.school_id? + if @state.user?.school_id? && !@state.user?['is_guitar_center?'] onlySchoolOption = `

School Options

diff --git a/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee index accecbb73..c15e12db1 100644 --- a/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee @@ -233,7 +233,8 @@ ProfileActions = @ProfileActions if !bio? bio = 'No bio' - school_on_school = user.teacher.school_id? && @state.user?.school_id? && user.teacher.school_id == @state.user.school_id + #school_on_school = user.teacher.school_id? && @state.user?.school_id? && user.teacher.school_id == @state.user.school_id + school_on_school = false bookSingleBtn = null bookTestDriveBtn = null diff --git a/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee b/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee index 5f9a63536..c61027267 100644 --- a/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee +++ b/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee @@ -21,7 +21,7 @@ teacherActions = window.JK.Actions.Teacher lesson.me = me lesson.other = other lesson.isAdmin = context.JK.currentUserAdmin - lesson.noSchoolOnSchoolPayment = lesson['payment_if_school_on_school??'] + lesson.noSchoolOnSchoolPayment = !lesson['payment_if_school_on_school?'] lesson.cardNotOk = !lesson.lesson_booking.card_presumed_ok && lesson.payment_if_school_on_school? lesson.isActive = lesson['is_active?'] diff --git a/web/app/assets/stylesheets/client/react-components/TeacherSearchOptions.scss b/web/app/assets/stylesheets/client/react-components/TeacherSearchOptions.scss index 73028e042..e6fe29d1f 100644 --- a/web/app/assets/stylesheets/client/react-components/TeacherSearchOptions.scss +++ b/web/app/assets/stylesheets/client/react-components/TeacherSearchOptions.scss @@ -94,6 +94,9 @@ margin-bottom: 30px; } + label[for="onlyMySchool"] { + margin-left:10px; + } .student-levels-taught { .icheckbox_minimal { top:3px; diff --git a/web/app/assets/stylesheets/client/react-components/broadcast.scss b/web/app/assets/stylesheets/client/react-components/broadcast.scss index 699798a3e..46dbd84f4 100644 --- a/web/app/assets/stylesheets/client/react-components/broadcast.scss +++ b/web/app/assets/stylesheets/client/react-components/broadcast.scss @@ -4,6 +4,12 @@ position:absolute; bottom:0; width:100%; + + .guitar-center-logo img { + left: 25%; + position: relative; + bottom: 20px; + } } [data-react-class="BroadcastHolder"] { diff --git a/web/app/controllers/api_lesson_bookings_controller.rb b/web/app/controllers/api_lesson_bookings_controller.rb index 5a0dbba4b..14959dc92 100644 --- a/web/app/controllers/api_lesson_bookings_controller.rb +++ b/web/app/controllers/api_lesson_bookings_controller.rb @@ -133,7 +133,13 @@ class ApiLessonBookingsController < ApiController end def accept - next_lesson = @lesson_booking.next_lesson + + if params[:lesson_session_id] + next_lesson = LessonSession.find(params[:lesson_session_id]) + else + next_lesson = @lesson_booking.next_lesson + end + result = next_lesson.accept({ message: params[:message], slot: params[:slot], diff --git a/web/app/controllers/clients_controller.rb b/web/app/controllers/clients_controller.rb index 2078bd5a8..c4a8d0cfb 100644 --- a/web/app/controllers/clients_controller.rb +++ b/web/app/controllers/clients_controller.rb @@ -19,6 +19,7 @@ class ClientsController < ApplicationController return end + @is_guitar_center = current_user && current_user.is_guitar_center? @in_client_page = true @minimal_curtain = Rails.application.config.minimal_curtain gon.recurly_tax_estimate_jam_track_plan = Rails.application.config.recurly_tax_estimate_jam_track_plan diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl index 18a5f9151..99b7eea80 100644 --- a/web/app/views/api_users/show.rabl +++ b/web/app/views/api_users/show.rabl @@ -34,7 +34,7 @@ end # give back more info if the user being fetched is yourself if current_user && @user == current_user - attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :show_whats_next_count, :subscribe_email, :auth_twitter, :new_notifications, :sales_count, :reuse_card, :purchased_jamtracks_count, :first_downloaded_client_at, :created_at, :first_opened_jamtrack_web_player, :gifted_jamtracks, :has_redeemable_jamtrack, :remaining, :has_stored_credit_card?, :remaining_test_drives, :jamclass_credits, :can_buy_test_drive?, :lesson_package_type_id, :school_id + attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :show_whats_next_count, :subscribe_email, :auth_twitter, :new_notifications, :sales_count, :reuse_card, :purchased_jamtracks_count, :first_downloaded_client_at, :created_at, :first_opened_jamtrack_web_player, :gifted_jamtracks, :has_redeemable_jamtrack, :remaining, :has_stored_credit_card?, :remaining_test_drives, :jamclass_credits, :can_buy_test_drive?, :lesson_package_type_id, :school_id, :is_guitar_center_student? node :owned_school_id do |user| user.owned_school.id if user.owned_school diff --git a/web/app/views/clients/_header.html.erb b/web/app/views/clients/_header.html.erb index fd6d919e5..4d42c73d8 100644 --- a/web/app/views/clients/_header.html.erb +++ b/web/app/views/clients/_header.html.erb @@ -12,9 +12,9 @@ <%= render "users/user_dropdown" %> - <%= react_component 'BroadcastHolder', {} %> - + <%= react_component 'BroadcastHolder', {is_guitar_center: @is_guitar_center} %> +