From fce2c68f4f2389f02739d1b804c6ff04cb123b3b Mon Sep 17 00:00:00 2001 From: Seth Call Date: Sun, 25 Feb 2018 16:28:12 -0600 Subject: [PATCH] engagement emails --- admin/app/admin/onboarders.rb | 1 - admin/app/admin/onboarding.rb | 47 +++- db/manifest | 3 +- db/up/onboarding_emails.sql | 24 ++ ruby/lib/jam_ruby/app/mailers/user_mailer.rb | 51 ++++ .../take_first_free_lesson.html.erb | 45 ++++ .../take_first_free_lesson.text.erb | 26 +++ .../user_mailer/take_paid_lesson.html.erb | 45 ++++ .../user_mailer/take_paid_lesson.text.erb | 28 +++ .../take_second_free_lesson.html.erb | 29 +++ .../take_second_free_lesson.text.erb | 24 ++ ruby/lib/jam_ruby/models/lesson_booking.rb | 3 +- ruby/lib/jam_ruby/models/lesson_session.rb | 75 ++++-- ruby/lib/jam_ruby/models/user.rb | 47 +++- .../jam_ruby/models/lesson_session_spec.rb | 220 ++++++++++++++++++ ruby/spec/mailers/render_emails_spec.rb | 107 +++++++++ 16 files changed, 755 insertions(+), 20 deletions(-) create mode 100644 db/up/onboarding_emails.sql create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.text.erb diff --git a/admin/app/admin/onboarders.rb b/admin/app/admin/onboarders.rb index 2f4174c6d..bb84642bb 100644 --- a/admin/app/admin/onboarders.rb +++ b/admin/app/admin/onboarders.rb @@ -12,7 +12,6 @@ ActiveAdmin.register JamRuby::User, :as => 'Onboarder' do scope("All Onboarders", default: true) { |scope| scope.where(is_onboarder: true).order(:created_at) } - controller do active_admin_config.includes.push :onboarding_users diff --git a/admin/app/admin/onboarding.rb b/admin/app/admin/onboarding.rb index 7040629d0..33eb7420e 100644 --- a/admin/app/admin/onboarding.rb +++ b/admin/app/admin/onboarding.rb @@ -41,7 +41,11 @@ ActiveAdmin.register JamRuby::User, :as => 'OnboarderManagement' do filter :onboarder, as: :select, :collection => User.where(is_onboarder: true), label: 'Support Consultant' filter :onboarder_id_blank, :as => :boolean, label: 'Unassigned' filter :onboarding_escalation_reason_present, :as => :boolean, label: 'Escalated' - scope("TestDrive/Amazon Users", default: true) { |scope| scope.joins(:posa_cards).where('posa_cards.lesson_package_type_id in (?)', LessonPackageType::AMAZON_PACKAGES + LessonPackageType::LESSON_PACKAGE_TYPES) } + scope("Unassigned", default: true) { |scope| scope.joins(:posa_cards).where(onboarding_status: User::ONBOARDING_STATUS_UNASSIGNED).where('posa_cards.lesson_package_type_id in (?)', LessonPackageType::AMAZON_PACKAGES + LessonPackageType::LESSON_PACKAGE_TYPES) } + scope("Escalated") { |scope| scope.joins(:posa_cards).where('onboarding_status = ?', User::ONBOARDING_STATUS_ESCALATED).where('posa_cards.lesson_package_type_id in (?)', LessonPackageType::AMAZON_PACKAGES + LessonPackageType::LESSON_PACKAGE_TYPES) } + scope("Needs Manual Email") { |scope| scope.joins(:posa_cards).where(onboarding_status: User::ONBOARDING_STATUS_ONBOARDED).where('(stuck_take_flesson = TRUE AND sent_admin_take_flesson_email_at is NULL) OR (stuck_take_2nd_flesson = TRUE AND sent_admin_take_2nd_flesson_email_at IS NULL) OR (stuck_take_plesson = TRUE AND sent_admin_take_plesson_email_at IS NULL)').where('posa_cards.lesson_package_type_id in (?)', LessonPackageType::AMAZON_PACKAGES + LessonPackageType::LESSON_PACKAGE_TYPES) } + scope("Assigned") { |scope| scope.joins(:posa_cards).where('onboarding_status = ? OR onboarding_status = ?', User::ONBOARDING_STATUS_ASSIGNED, User::ONBOARDING_STATUS_EMAILED).where('posa_cards.lesson_package_type_id in (?)', LessonPackageType::AMAZON_PACKAGES + LessonPackageType::LESSON_PACKAGE_TYPES) } + scope("All TestDrive/Amazon Users") { |scope| scope.joins(:posa_cards).where('posa_cards.lesson_package_type_id in (?)', LessonPackageType::AMAZON_PACKAGES + LessonPackageType::LESSON_PACKAGE_TYPES) } controller do @@ -63,6 +67,19 @@ ActiveAdmin.register JamRuby::User, :as => 'OnboarderManagement' do else end end + column "Manual Email Needed" do |user| + + div do + if user.stuck_take_plesson + link_to("sent take paid lesson email", mark_sent_paid_lesson_admin_onboarder_management_path(user.id), {'data-confirm': "You sent an email manually to the user to remind them to take a paid lesson?"}) + elsif user.stuck_take_2nd_flesson + link_to("sent take 2nd lesson email", mark_sent_2nd_free_lesson_admin_onboarder_management_path(user.id), {'data-confirm': "You sent an email manually to the user to remind them to take 2nd free lesson?"}) + elsif user.stuck_take_flesson + link_to("sent take 1st lesson email", mark_sent_1st_free_lesson_admin_onboarder_management_path(user.id), {'data-confirm': "You sent an email manually to the user to remind them to take a 1st free lesson?"}) + else + end + end + end column "Signup" do |user| user.created_at.to_date @@ -74,6 +91,14 @@ ActiveAdmin.register JamRuby::User, :as => 'OnboarderManagement' do column "Email 4", :onboarding_email_4_sent_at column "Email 5", :onboarding_email_5_sent_at column "Test Session", :onboarding_test_session_scheduled_at + column "Admin Actions" do |user| + div do + if user.is_waiting_onboarding || user.is_onboarding + link_to("mark onboarded", mark_onboarded_admin_onboarder_management_path(user.id), { 'data-confirm': "Mark onboarded?"}) + end + end + end + column "Onboarder Notes", :onboarding_onboarder_notes end member_action :update_onboarder, :method => :post do @@ -82,4 +107,24 @@ ActiveAdmin.register JamRuby::User, :as => 'OnboarderManagement' do redirect_to :back end + member_action :mark_sent_paid_lesson, :method => :get do + resource.mark_sent_paid_lesson + redirect_to :back + end + + member_action :mark_sent_2nd_free_lesson, :method => :get do + resource.mark_sent_2nd_free_lesson + redirect_to :back + end + + member_action :mark_sent_1st_free_lesson, :method => :get do + resource.mark_sent_1st_free_lesson + redirect_to :back + end + + member_action :mark_onboarded, :method => :get do + resource.mark_onboarded + redirect_to :back + end + end \ No newline at end of file diff --git a/db/manifest b/db/manifest index 85801522a..ece0a3d84 100755 --- a/db/manifest +++ b/db/manifest @@ -385,4 +385,5 @@ onboarding.sql better_lesson_notices.sql teacher_search_control.sql user_timezone.sql -onboarder_limit.sql \ No newline at end of file +onboarder_limit.sql +onboarding_emails.sql \ No newline at end of file diff --git a/db/up/onboarding_emails.sql b/db/up/onboarding_emails.sql new file mode 100644 index 000000000..e2312537f --- /dev/null +++ b/db/up/onboarding_emails.sql @@ -0,0 +1,24 @@ +ALTER TABLE users ADD COLUMN sent_take_flesson_email_at TIMESTAMP WITHOUT TIME ZONE; +ALTER TABLE users ADD COLUMN sent_take_flesson_email_times INTEGER NOT NULL DEFAULT 0; +ALTER TABLE users ADD COLUMN sent_take_2nd_flesson_email_at TIMESTAMP WITHOUT TIME ZONE; +ALTER TABLE users ADD COLUMN sent_take_2nd_flesson_email_times INTEGER NOT NULL DEFAULT 0; +ALTER TABLE users ADD COLUMN sent_take_plesson_email_at TIMESTAMP WITHOUT TIME ZONE; +ALTER TABLE users ADD COLUMN sent_take_plesson_email_times INTEGER NOT NULL DEFAULT 0; +ALTER TABLE users ADD COLUMN second_onboarding_free_lesson_at timestamp without time zone; +ALTER TABLE users ADD COLUMN sent_admin_take_flesson_email_at TIMESTAMP WITHOUT TIME ZONE; +ALTER TABLE users ADD COLUMN sent_admin_take_2nd_flesson_email_at TIMESTAMP WITHOUT TIME ZONE; +ALTER TABLE users ADD COLUMN sent_admin_take_plesson_email_at TIMESTAMP WITHOUT TIME ZONE; +ALTER TABLE users ADD COLUMN stuck_take_flesson BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE users ADD COLUMN stuck_take_2nd_flesson BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE users ADD COLUMN stuck_take_plesson BOOLEAN NOT NULL DEFAULT FALSE; + +CREATE INDEX index_first_onboarding_paid_lesson_at ON users USING btree(first_onboarding_paid_lesson_at); +CREATE INDEX index_onboarding_onboarded_at ON users USING btree(onboarding_onboarded_at); +CREATE INDEX index_onboarding_status ON users USING btree(onboarding_status); +CREATE INDEX index_stuck_take_plesson ON users USING btree(stuck_take_plesson); +CREATE INDEX index_stuck_take_2nd_flesson ON users USING btree(stuck_take_2nd_flesson); +CREATE INDEX index_stuck_take_flesson ON users USING btree(stuck_take_flesson); +CREATE INDEX index_sent_admin_take_flesson_email_at ON users USING btree(sent_admin_take_flesson_email_at); +CREATE INDEX index_sent_admin_take_2nd_flesson_email_at ON users USING btree(sent_admin_take_2nd_flesson_email_at); +CREATE INDEX index_sent_admin_take_plesson_email_at ON users USING btree(sent_admin_take_plesson_email_at); +CREATE INDEX index_posa_cards_lesson_package_type_id ON posa_cards USING btree(lesson_package_type_id); diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index 296f75580..b10b6a22e 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -49,6 +49,57 @@ module JamRuby end end + def take_paid_lesson(user) + @user = user + @lesson = user.taken_lessons.order(:created_at).last + @teacher = @lesson.teacher + + @subject = "Time to get even better at your instrument" + sendgrid_category "promo_lesson_reminder" + sendgrid_unique_args :type => "promo_lesson_reminder" + + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + + mail(:to => user.email, :subject => @subject) do |format| + format.text + format.html + end + end + + def take_second_free_lesson(user) + @user = user + @lesson = user.taken_lessons.order(:created_at).last + @teacher = @lesson.teacher + + @subject = "A reminder to take your second free lesson" + sendgrid_category "promo_lesson_reminder" + sendgrid_unique_args :type => "promo_lesson_reminder" + + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + + mail(:to => user.email, :subject => @subject) do |format| + format.text + format.html + end + end + + def take_first_free_lesson(user) + @user = user + @subject = "A reminder to take your first free lesson" + sendgrid_category "promo_lesson_reminder" + sendgrid_unique_args :type => "promo_lesson_reminder" + + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + + mail(:to => user.email, :subject => @subject) do |format| + format.text + format.html + end + end + def student_education_welcome_message(user) @user = user @subject = "Welcome to JamKazam and JamClass online lessons!" diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.html.erb new file mode 100644 index 000000000..b3055afbf --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.html.erb @@ -0,0 +1,45 @@ +<% provide(:title, @subject) %> + + +<% if !@user.anonymous? %> +

Hi <%= @user.first_name %>, +

+<% end %> + +<% if @user.sent_take_flesson_email_times == 0 %> + +

We hope you had a great support experience with the JamKazam consultant who prepared you to get into your first free online lesson. Life gets busy. So before you forget about it, please find an instructor who looks great for you, and book your first free lesson now! +

+ +

+ Here is an article that explains how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your first lesson: http://bit.ly/2k3qNMT. +

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+ + <% elsif @user.sent_take_flesson_email_times == 1 %> + +

We noticed you haven't booked your first free lesson yet. Don't forget to take advantage of this amazing limited promotion. Your two free lessons are valued at approximately $60! Book your first lesson today.

+

+ Here is an article that explains how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your first lesson: http://bit.ly/2k3qNMT. +

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+ +<% else %> + + +

It looks like you're busy, but we wanted to remind you once more to book your first free lesson before you forget and let this terrific promotion get away. Start your musical journey with a world-class instructor who can help you achieve your goals. There is no better way to learn and master your new instrument!

+

+ Here is an article that explains how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your first lesson: http://bit.ly/2k3qNMT. +

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+ + <% end %> + +

Best Regards,
+ Team JamKazam

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.text.erb new file mode 100644 index 000000000..869994f72 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_first_free_lesson.text.erb @@ -0,0 +1,26 @@ +<% if !@user.anonymous? %> +Hi <%= @user.first_name %>, +<% end %> + +<% if @user.sent_take_flesson_email_times == 0 %> +We hope you had a great support experience with the JamKazam consultant who prepared you to get into your first free online lesson. Life gets busy. So before you forget about it, please find an instructor who looks great for you, and book your first free lesson now! + +Here is an article that explains how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your first lesson:http://bit.ly/2k3qNMT. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% elsif @user.sent_take_flesson_email_times == 1 %> +We noticed you haven't booked your first free lesson yet. Don't forget to take advantage of this amazing limited promotion. Your two free lessons are valued at approximately $60! Book your first lesson today. + +Here is an article that explains how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your first lesson:http://bit.ly/2k3qNMT. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% else %> +It looks like you're busy, but we wanted to remind you once more to book your first free lesson before you forget and let this terrific promotion get away. Start your musical journey with a world-class instructor who can help you achieve your goals. There is no better way to learn and master your new instrument! + +Here is an article that explains how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your first lesson:http://bit.ly/2k3qNMT. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% end %> + +Best Regards, +Team JamKazam \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.html.erb new file mode 100644 index 000000000..0979d40fc --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.html.erb @@ -0,0 +1,45 @@ +<% provide(:title, @subject) %> + + +<% if !@user.anonymous? %> +

Hi <%= @user.first_name %>, +

+<% end %> + +<% if @user.sent_take_plesson_email_times == 0 %> +

+ Now that you've enjoyed your first two lessons free, continue down the musical path you've started with your instructor. Schedule recurring weekly lessons for the best results and fastest progress, or schedule lessons one at a time. It's up to you. +

+

+ You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. +

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+ <% elsif @user.sent_take_plesson_email_times == 1 %> +

+ You're off to a great start with your music teacher. Don't lose momentum! +

+

+ You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. +

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+ <% else %> +

+ The best way - by far - to master your instrument and reach your musical goals is to have a great instructor - someone who can guide you, build the right foundation and technique from the beginning, inspire you, and make your practice pay off with the greatest return on your investment of time. If you want to play well, stay on the path with your instructor. +

+

+ You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. +

+

+ Or if you need to find a different instructor for any reason, here's an article on how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your lesson: http://bit.ly/2k3qNMT. +

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+ <% end %> + +

Best Regards,
+ Team JamKazam

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.text.erb new file mode 100644 index 000000000..935699c18 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_paid_lesson.text.erb @@ -0,0 +1,28 @@ +<% if !@user.anonymous? %> +Hi <%= @user.first_name %>, +<% end %> + +<% if @user.sent_take_plesson_email_times == 0 %> +Now that you've enjoyed your first two lessons free, continue down the musical path you've started with your instructor. Schedule recurring weekly lessons for the best results and fastest progress, or schedule lessons one at a time. It's up to you. + +You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% elsif @user.sent_take_plesson_email_times == 1 %> +You're off to a great start with your music teacher. Don't lose momentum! + +You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% else %> +The best way - by far - to master your instrument and reach your musical goals is to have a great instructor - someone who can guide you, build the right foundation and technique from the beginning, inspire you, and make your practice pay off with the greatest return on your investment of time. If you want to play well, stay on the path with your instructor. + +You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. + +Or if you need to find a different instructor for any reason, here's an article on how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your lesson: http://bit.ly/2k3qNMT. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% end %> + +Best Regards, +Team JamKazam diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.html.erb new file mode 100644 index 000000000..bca989c40 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.html.erb @@ -0,0 +1,29 @@ +<% provide(:title, @subject) %> + + +<% if !@user.anonymous? %> +

Hi <%= @user.first_name %>, +

+<% end %> + +<% if @user.sent_take_2nd_flesson_email_times == 0 %> +

We hope you had a great first music lesson with <%= @teacher.name %>. Schedule your second free lesson with this instructor now at this page: <%= @teacher.teacher_profile_url %>, and continue your musical journey!

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+<% elsif @user.sent_take_2nd_flesson_email_times == 1 %> +

Just a quick reminder to take advantage of your second free lesson, and book it today! Schedule your second lesson with the same instructor from your first lesson at this page: <%= @teacher.teacher_profile_url %>.

+

Or if you didn't love your instructor for any reason, you can search for a different instructor for your second free lesson. Here's the article on how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your lesson: http://bit.ly/2k3qNMT.

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+<% else %> +

We're sending you one last reminder to book your second free lesson. Don't put it off to later and forget! A great instructor will make a huge difference in the progress you make in mastering your new instrument. You can book another lesson with your first instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>.

+

Or if you didn't love your instructor for any reason, you can search for a different instructor for your second free lesson. Here's the article on how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your lesson: http://bit.ly/2k3qNMT.

+

+ If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +

+<% end %> + +

Best Regards,
+ Team JamKazam

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.text.erb new file mode 100644 index 000000000..115ee401a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/take_second_free_lesson.text.erb @@ -0,0 +1,24 @@ +<% if !@user.anonymous? %> +Hi <%= @user.first_name %>, +<% end %> + +<% if @user.sent_take_2nd_flesson_email_times == 0 %> +We hope you had a great first music lesson with <%= @teacher.name %>. Schedule your second free lesson with this instructor now at this page: <%= @teacher.teacher_profile_url %>, and continue your musical journey! + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% elsif @user.sent_take_2nd_flesson_email_times == 1 %> +Just a quick reminder to take advantage of your second free lesson, and book it today! Schedule your second lesson with the same instructor from your first lesson at this page: <%= @teacher.teacher_profile_url %>. + +Or if you didn't love your instructor for any reason, you can search for a different instructor for your second free lesson. Here's the article on how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your lesson: http://bit.ly/2k3qNMT. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% else %> +We're sending you one last reminder to book your second free lesson. Don't put it off to later and forget! A great instructor will make a huge difference in the progress you make in mastering your new instrument. You can book another lesson with your first instructor at his/her profile page here: <%= @teacher.teacher_profile_url %>. + +Or if you didn't love your instructor for any reason, you can search for a different instructor for your second free lesson. Here's the article on how to search for your ideal teacher: http://bit.ly/2kBPXBz. And here is an article that explains how to book your lesson: http://bit.ly/2k3qNMT. + +If you have any trouble, please email us at support@jamkazam.com. Or you can call us at 877-376-8742. +<% end %> + +Best Regards, +Team JamKazam \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/lesson_booking.rb b/ruby/lib/jam_ruby/models/lesson_booking.rb index 58c4baa38..758c94710 100644 --- a/ruby/lib/jam_ruby/models/lesson_booking.rb +++ b/ruby/lib/jam_ruby/models/lesson_booking.rb @@ -840,7 +840,8 @@ module JamRuby if !user.has_test_drives? && !user.can_buy_test_drive? errors.add(:user, "have no remaining test drives") elsif teacher.has_booked_test_drive_with_student?(user) && !user.admin - errors.add(:user, "have an in-progress or successful TestDrive with this teacher already") + # we don't want to restrict this anymore. just let'em go to same teacher + # errors.add(:user, "have an in-progress or successful TestDrive with this teacher already") end end diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb index 922bdb854..83a2f116c 100644 --- a/ruby/lib/jam_ruby/models/lesson_session.rb +++ b/ruby/lib/jam_ruby/models/lesson_session.rb @@ -94,11 +94,11 @@ module JamRuby end def teacher_distribution - teacher_distributions.where(education:false).where('retailer_id is null').first + teacher_distributions.where(education: false).where('retailer_id is null').first end def education_distribution - teacher_distributions.where(education:true).first + teacher_distributions.where(education: true).first end def retailer_distribution @@ -131,6 +131,7 @@ module JamRuby complete_sessions remind_counters remind_counters_recurring + onboarding_email_reminders end def self.minutely_check @@ -144,7 +145,7 @@ module JamRuby .where("? > (COALESCE(lesson_sessions.sent_counter_reminder_at, lesson_sessions.countered_at, lesson_bookings.sent_notices_at) + (INTERVAL '24 hours'))", Time.now).each do |music_session| lesson_session = music_session.lesson_session if lesson_session.student_last_proposed? - relevant_time = [lesson_session.countered_at, lesson_session.lesson_booking.sent_notices_at].find{|x|!x.nil?} + relevant_time = [lesson_session.countered_at, lesson_session.lesson_booking.sent_notices_at].find { |x| !x.nil? } UserMailer.student_no_comm_other(lesson_session.lesson_booking, relevant_time < Time.now - 3.days).deliver_now UserMailer.teacher_counter_reminder(lesson_session).deliver_now @@ -159,7 +160,7 @@ module JamRuby def self.remind_counters_recurring MusicSession.joins(lesson_session: :lesson_booking) - .where("lesson_bookings.status = ? AND lesson_bookings.sent_counter_reminder = false AND lesson_bookings.recurring = TRUE",LessonBooking::STATUS_COUNTERED) + .where("lesson_bookings.status = ? AND lesson_bookings.sent_counter_reminder = false AND lesson_bookings.recurring = TRUE", LessonBooking::STATUS_COUNTERED) .where("? > (COALESCE(lesson_sessions.countered_at, lesson_bookings.sent_notices_at) + (INTERVAL '24 hours'))", Time.now).each do |music_session| lesson_session = music_session.lesson_session if lesson_session.student_last_proposed? @@ -172,6 +173,51 @@ module JamRuby end end + def self.remindable_onboarding_users + User.where('first_onboarding_paid_lesson_at IS NULL AND onboarding_onboarded_at IS NOT NULL') + .where('stuck_take_flesson = FALSE and stuck_take_2nd_flesson = FALSE and stuck_take_plesson = FALSE') + end + + def self.onboarding_email_reminders + remindable_onboarding_users.each do |user| + if user.second_onboarding_free_lesson_at && user.sent_take_plesson_email_times < 4 + + last_sent = user.sent_take_plesson_email_at || user.second_onboarding_free_lesson_at + if last_sent < 2.days.ago + if user.sent_take_plesson_email_times == 3 + User.update_all(id: user.id, stuck_take_plesson: true) + else + UserMailer.take_paid_lesson(user).deliver_now + User.update_all(id: user.id, sent_take_plesson_email_times: user.sent_take_plesson_email_times + 1, sent_take_plesson_email_at: Time.now) + end + end + + elsif user.first_onboarding_free_lesson_at && user.sent_take_2nd_flesson_email_times < 4 + last_sent = user.sent_take_2nd_flesson_email_at || user.first_onboarding_free_lesson_at + if last_sent < 2.days.ago + if user.sent_take_2nd_flesson_email_times == 3 + User.update_all(id: user.id, stuck_take_2nd_flesson: true) + else + UserMailer.take_second_free_lesson(user).deliver_now + User.update_all(id: user.id, sent_take_2nd_flesson_email_times: user.sent_take_2nd_flesson_email_times + 1, sent_take_2nd_flesson_email_at: Time.now) + end + end + + elsif user.sent_take_flesson_email_times < 4 + last_sent = user.sent_take_flesson_email_at || user.onboarding_onboarded_at + if last_sent < 2.days.ago + if user.sent_take_flesson_email_times == 3 + User.update_all(id: user.id, stuck_take_flesson: true) + else + UserMailer.take_first_free_lesson(user).deliver_now + User.update_all(id: user.id, sent_take_flesson_email_times: user.sent_take_flesson_email_times + 1, sent_take_flesson_email_at: Time.now) + end + end + end + end + end + + # give 2 days to auto-cancel; this lets people just jump in a session and mark it done def self.auto_cancel MusicSession.joins(lesson_session: :lesson_booking).where('lesson_sessions.status = ? OR lesson_bookings.status = ?', LessonSession::STATUS_REQUESTED, LessonBooking::STATUS_COUNTERED).where("? > scheduled_start + (INTERVAL '2 days') + (INTERVAL '1 minutes' * (duration))", Time.now).each do |music_session| @@ -319,15 +365,16 @@ module JamRuby if student.first_onboarding_free_lesson_at.nil? student.first_onboarding_free_lesson_at = Time.now student.save + elsif student.second_onboarding_free_lesson_at.nil? + student.second_onboarding_free_lesson_at = Time.now + student.save end else if student.first_onboarding_paid_lesson_at.nil? student.first_onboarding_paid_lesson_at = Time.now student.save end - end - end mark_lesson(analysis[:bill]) @@ -399,6 +446,7 @@ module JamRuby student end end + def session_completed LessonSession.transaction do self.lock! @@ -473,7 +521,7 @@ module JamRuby if !sent_notices if success - teacher_distributions.update_all(ready:true) # possibly there are 0 distributions on this lesson + teacher_distributions.update_all(ready: true) # possibly there are 0 distributions on this lesson student.test_drive_succeeded(self) else student.test_drive_failed(self) @@ -1137,6 +1185,7 @@ module JamRuby 'TBD' end end + def timed_description if is_test_drive? "TestDrive session with #{self.lesson_booking.student.name} on #{time_for_admin}" @@ -1151,11 +1200,11 @@ module JamRuby def cancel_by_admin self.cancel({ - canceler: nil, - canceled_by_admin: true, - message: 'Canceled by JamKazam administrator', - update_all: false - }) + canceler: nil, + canceled_by_admin: true, + message: 'Canceled by JamKazam administrator', + update_all: false + }) end def intervened @@ -1178,7 +1227,7 @@ module JamRuby end def last_response_time - [countered_at, lesson_booking.sent_notices_at].find{|x|!x.nil?} + [countered_at, lesson_booking.sent_notices_at].find { |x| !x.nil? } end def stripe_description(lesson_booking) diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 8b7b0083f..535eaae81 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -38,7 +38,7 @@ module JamRuby ONBOARDING_STATUS_ONBOARDED = "Onboarded" ONBOARDING_STATUS_LOST = "Lost" ONBOARDING_STATUS_ESCALATED = "Escalated" - ONBOARDING_STATUS_FREE_LESSON = "Free Lesson Taken" + ONBOARDING_STATUS_FREE_LESSON = "One Free Lesson Taken" ONBOARDING_STATUS_PAID_LESSON = "Paid Lesson Taken" ONBOARDING_STATUES = [ONBOARDING_STATUS_UNASSIGNED, ONBOARDING_STATUS_ASSIGNED, ONBOARDING_STATUS_EMAILED, ONBOARDING_STATUS_ONBOARDED, ONBOARDING_STATUS_LOST, ONBOARDING_STATUS_ESCALATED, ONBOARDING_STATUS_FREE_LESSON, ONBOARDING_STATUS_PAID_LESSON ] SESSION_OUTCOME_SUCCESSFUL = "Successful" @@ -328,8 +328,18 @@ module JamRuby onboarding_email_5_sent_at_changed? || first_onboarding_free_lesson_at_changed? || first_onboarding_paid_lesson_at_changed? || + second_onboarding_free_lesson_at? || onboarding_onboarded_at - User.where(id: self.id).update_all(onboarding_status: self.computed_onboarding_status) + + updates = {onboarding_status: self.computed_onboarding_status} + + if first_onboarding_free_lesson_at_changed? || first_onboarding_paid_lesson_at_changed? || second_onboarding_free_lesson_at? + updates[:stuck_take_flesson] = false + updates[:stuck_take_2nd_flesson] = false + updates[:stuck_take_plesson] = false + end + + User.where(id: self.id).update_all(updates) end end def update_teacher_pct @@ -338,6 +348,14 @@ module JamRuby end end + def is_waiting_onboarding + ONBOARDING_STATUS_UNASSIGNED + end + + def is_onboarding + ONBOARDING_STATUS_ASSIGNED || ONBOARDING_STATUS_ESCALATED || ONBOARDING_STATUS_EMAILED || ONBOARDING_STATUS_LOST + end + def user_progression_fields @user_progression_fields ||= Set.new ["first_downloaded_client_at", "first_ran_client_at", "first_music_session_at", "first_real_music_session_at", "first_good_music_session_at", "first_certified_gear_at", "first_invited_at", "first_friended_at", "first_recording_at", "first_social_promoted_at", "first_played_jamtrack_at"] end @@ -2502,6 +2520,29 @@ module JamRuby self.save! end + def mark_sent_paid_lesson + self.stuck_take_plesson = false + self.sent_admin_take_plesson_email_at = Time.now + self.save! + end + + def mark_sent_2nd_free_lesson + self.stuck_take_2nd_flesson = false + self.sent_admin_take_2nd_flesson_email_at = Time.now + self.save! + end + + def mark_sent_1st_free_lesson + self.stuck_take_flesson = false + self.sent_admin_take_flesson_email_at = Time.now + self.save! + end + + def mark_onboarded + self.onboarding_onboarded_at = Time.now + self.save! + end + def has_booked_with_student?(student, since_at = nil) LessonBooking.engaged_bookings(student, self, since_at).count > 0 end @@ -2517,7 +2558,7 @@ module JamRuby def computed_onboarding_status if first_onboarding_paid_lesson_at ONBOARDING_STATUS_PAID_LESSON - elsif first_onboarding_free_lesson_at + elsif second_onboarding_free_lesson_at || first_onboarding_free_lesson_at ONBOARDING_STATUS_FREE_LESSON elsif onboarding_onboarded_at ONBOARDING_STATUS_ONBOARDED diff --git a/ruby/spec/jam_ruby/models/lesson_session_spec.rb b/ruby/spec/jam_ruby/models/lesson_session_spec.rb index dba6e68de..c7d0bbfbf 100644 --- a/ruby/spec/jam_ruby/models/lesson_session_spec.rb +++ b/ruby/spec/jam_ruby/models/lesson_session_spec.rb @@ -504,6 +504,226 @@ describe LessonSession do end end + describe "remindable_onboarding_users" do + it "works" do + LessonSession.remindable_onboarding_users.count.should eql 0 + + user.onboarding_onboarded_at = Time.now + user.first_onboarding_paid_lesson_at = nil + user.save! + + LessonSession.remindable_onboarding_users.count.should eql 1 + + user.sent_take_plesson_email_times = 3 + user.sent_take_2nd_flesson_email_times = 3 + user.sent_take_plesson_email_times = 3 + user.save! + + LessonSession.remindable_onboarding_users.count.should eql 0 + end + end + + describe "onboarding_email_reminders" do + it "works" do + user.onboarding_onboarded_at = Time.now + user.first_onboarding_paid_lesson_at = nil + user.save! + + mailer = mock + UserMailer.deliveries.clear + + LessonSession.onboarding_email_reminders + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_first_free_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + #UserMailer.deliveries.count.should eql 1 + user.reload + user.sent_take_flesson_email_times.should eql 1 + user.sent_take_2nd_flesson_email_times.should eql 0 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + #RSpec::Mocks.space.proxy_for(mailer).reset + #RSpec::Mocks.space.proxy_for(UserMailer).reset + UserMailer.deliveries.clear + + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 1 + user.sent_take_2nd_flesson_email_times.should eql 0 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + #RSpec::Mocks.space.proxy_for(mailer).reset + #RSpec::Mocks.space.proxy_for(UserMailer).reset + UserMailer.deliveries.clear + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_first_free_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 2 + user.sent_take_2nd_flesson_email_times.should eql 0 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + #RSpec::Mocks.space.proxy_for(mailer).reset + #RSpec::Mocks.space.proxy_for(UserMailer).reset + UserMailer.deliveries.clear + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_first_free_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 0 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + #RSpec::Mocks.space.proxy_for(mailer).reset + #RSpec::Mocks.space.proxy_for(UserMailer).reset + UserMailer.deliveries.clear + + Timecop.travel(Date.today + 3) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 0 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_true + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + #RSpec::Mocks.space.proxy_for(mailer).reset + #RSpec::Mocks.space.proxy_for(UserMailer).reset + UserMailer.deliveries.clear + + user.first_onboarding_free_lesson_at = Time.now + user.save! + + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 0 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_second_free_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 1 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_second_free_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 2 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_second_free_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_true + user.stuck_take_plesson.should be_false + + user.second_onboarding_free_lesson_at = Time.now + user.save! + + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 0 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_paid_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 1 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_paid_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 2 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + mailer.should_receive(:deliver_now).once + UserMailer.should_receive(:take_paid_lesson).and_return(mailer) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 3 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_false + + Timecop.travel(Date.today + 3) + LessonSession.onboarding_email_reminders + user.reload + user.sent_take_flesson_email_times.should eql 3 + user.sent_take_2nd_flesson_email_times.should eql 3 + user.sent_take_plesson_email_times.should eql 3 + user.stuck_take_flesson.should be_false + user.stuck_take_2nd_flesson.should be_false + user.stuck_take_plesson.should be_true + + end + end + describe "index" do it "finds single lesson as student" do diff --git a/ruby/spec/mailers/render_emails_spec.rb b/ruby/spec/mailers/render_emails_spec.rb index 7db4da562..2425f5661 100644 --- a/ruby/spec/mailers/render_emails_spec.rb +++ b/ruby/spec/mailers/render_emails_spec.rb @@ -210,6 +210,113 @@ describe "RenderMailers", :slow => true do UserMailer.deliveries.clear UserMailer.student_no_comm_other(lesson.lesson_booking, true).deliver_now end + + it "take_first_free_lesson 1" do + @filename = "take_first_free_lesson_1" + + user.sent_take_flesson_email_times = 0 + user.save! + + UserMailer.deliveries.clear + UserMailer.take_first_free_lesson(user).deliver_now + end + + it "take_first_free_lesson 2" do + @filename = "take_first_free_lesson_2" + + user.sent_take_flesson_email_times = 1 + user.save! + + UserMailer.deliveries.clear + UserMailer.take_first_free_lesson(user).deliver_now + end + + it "take_first_free_lesson 3" do + @filename = "take_first_free_lesson_3" + + user.sent_take_flesson_email_times = 2 + user.save! + + UserMailer.deliveries.clear + UserMailer.take_first_free_lesson(user).deliver_now + end + + it "take_second_free_lesson 1" do + @filename = "take_second_free_lesson_1" + + user.sent_take_2nd_flesson_email_times = 0 + user.save! + + lesson = testdrive_lesson(user, teacher) + + + UserMailer.deliveries.clear + UserMailer.take_second_free_lesson(user).deliver_now + end + + it "take_second_free_lesson 2" do + @filename = "take_second_free_lesson_2" + + user.sent_take_2nd_flesson_email_times = 1 + user.save! + + lesson = testdrive_lesson(user, teacher) + + UserMailer.deliveries.clear + UserMailer.take_second_free_lesson(user).deliver_now + end + + it "take_second_free_lesson 3" do + @filename = "take_second_free_lesson_3" + + user.sent_take_2nd_flesson_email_times = 2 + user.save! + + lesson = testdrive_lesson(user, teacher) + + UserMailer.deliveries.clear + UserMailer.take_second_free_lesson(user).deliver_now + end + + it "take_paid_lesson 1" do + @filename = "take_paid_lesson_1" + + user.sent_take_plesson_email_times = 0 + user.save! + + lesson = testdrive_lesson(user, teacher) + lesson = testdrive_lesson(user, teacher) + + + UserMailer.deliveries.clear + UserMailer.take_paid_lesson(user).deliver_now + end + + it "take_paid_lesson 2" do + @filename = "take_paid_lesson_2" + + user.sent_take_plesson_email_times = 1 + user.save! + + lesson = testdrive_lesson(user, teacher) + lesson = testdrive_lesson(user, teacher) + + UserMailer.deliveries.clear + UserMailer.take_paid_lesson(user).deliver_now + end + + it "take_paid_lesson 3" do + @filename = "take_paid_lesson_3" + + user.sent_take_plesson_email_times = 2 + user.save! + + lesson = testdrive_lesson(user, teacher) + lesson = testdrive_lesson(user, teacher) + + UserMailer.deliveries.clear + UserMailer.take_paid_lesson(user).deliver_now + end end end