engagement emails

This commit is contained in:
Seth Call 2018-02-25 16:28:12 -06:00
parent 13f22abaa8
commit fce2c68f4f
16 changed files with 755 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -385,4 +385,5 @@ onboarding.sql
better_lesson_notices.sql
teacher_search_control.sql
user_timezone.sql
onboarder_limit.sql
onboarder_limit.sql
onboarding_emails.sql

View File

@ -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);

View File

@ -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!"

View File

@ -0,0 +1,45 @@
<% provide(:title, @subject) %>
<% if !@user.anonymous? %>
<p>Hi <%= @user.first_name %>,
</p>
<% end %>
<% if @user.sent_take_flesson_email_times == 0 %>
<p>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!
</p>
<p>
Here is an article that explains how to search for your ideal teacher: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. And here is an article that explains how to book your first lesson: <a href="http://bit.ly/2k3qNMT" style="color:#fc0">http://bit.ly/2k3qNMT</a>.
</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% elsif @user.sent_take_flesson_email_times == 1 %>
<p>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.</p>
<p>
Here is an article that explains how to search for your ideal teacher: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. And here is an article that explains how to book your first lesson: <a href="http://bit.ly/2k3qNMT" style="color:#fc0">http://bit.ly/2k3qNMT</a>.
</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% else %>
<p>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!</p>
<p>
Here is an article that explains how to search for your ideal teacher: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. And here is an article that explains how to book your first lesson: <a href="http://bit.ly/2k3qNMT" style="color:#fc0">http://bit.ly/2k3qNMT</a>.
</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% end %>
<p>Best Regards,<br/>
Team JamKazam</p>

View File

@ -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

View File

@ -0,0 +1,45 @@
<% provide(:title, @subject) %>
<% if !@user.anonymous? %>
<p>Hi <%= @user.first_name %>,
</p>
<% end %>
<% if @user.sent_take_plesson_email_times == 0 %>
<p>
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.
</p>
<p>
You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <a href="<%= @teacher.teacher_profile_url %>" style="color:#fc0"><%= @teacher.teacher_profile_url %></a>.
</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% elsif @user.sent_take_plesson_email_times == 1 %>
<p>
You're off to a great start with your music teacher. Don't lose momentum!
</p>
<p>
You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <a href="<%= @teacher.teacher_profile_url %>" style="color:#fc0"><%= @teacher.teacher_profile_url %></a>.
</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% else %>
<p>
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.
</p>
<p>
You can book your regular weekly or one-at-a-time lessons with your instructor at his/her profile page here: <a href="<%= @teacher.teacher_profile_url %>" style="color:#fc0"><%= @teacher.teacher_profile_url %></a>.
</p>
<p>
Or if you need to find a different instructor for any reason, here's an article on how to search for your ideal teacher: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. And here is an article that explains how to book your lesson: <a href="http://bit.ly/2k3qNMT" style="color:#fc0">http://bit.ly/2k3qNMT</a>.
</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% end %>
<p>Best Regards,<br/>
Team JamKazam</p>

View File

@ -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: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. 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

View File

@ -0,0 +1,29 @@
<% provide(:title, @subject) %>
<% if !@user.anonymous? %>
<p>Hi <%= @user.first_name %>,
</p>
<% end %>
<% if @user.sent_take_2nd_flesson_email_times == 0 %>
<p>We hope you had a great first music lesson with <%= @teacher.name %>. Schedule your second free lesson with this instructor now at this page: <a href="<%= @teacher.teacher_profile_url %>" style="color:#fc0"><%= @teacher.teacher_profile_url %></a>, and continue your musical journey!</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% elsif @user.sent_take_2nd_flesson_email_times == 1 %>
<p>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: <a href="<%= @teacher.teacher_profile_url %>" style="color:#fc0"><%= @teacher.teacher_profile_url %></a>.</p>
<p>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: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. And here is an article that explains how to book your lesson: <a href="http://bit.ly/2k3qNMT" style="color:#fc0">http://bit.ly/2k3qNMT</a>.</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% else %>
<p>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: <a href="<%= @teacher.teacher_profile_url %>" style="color:#fc0"><%= @teacher.teacher_profile_url %></a>.</p>
<p>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: <a href="http://bit.ly/2kBPXBz" style="color:#fc0">http://bit.ly/2kBPXBz</a>. And here is an article that explains how to book your lesson: <a href="http://bit.ly/2k3qNMT" style="color:#fc0">http://bit.ly/2k3qNMT</a>.</p>
<p>
If you have any trouble, please email us at <a href="mailto:support@jamkazam.com" style="color:#fc0">support@jamkazam.com</a>. Or you can call us at <a href="tel:+18773768742">877-376-8742</a>.
</p>
<% end %>
<p>Best Regards,<br/>
Team JamKazam</p>

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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