From bcbd0191ef2917c18a6faf6e8d27a67ee6bf6493 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Fri, 19 Feb 2016 13:36:35 -0600 Subject: [PATCH] * wip --- db/up/lessons.sql | 4 ++ pb/src/client_container.proto | 45 +++----------- ruby/lib/jam_ruby/app/mailers/user_mailer.rb | 50 ++++++++++++---- .../student_lesson_accepted.html.erb | 18 ++++++ .../student_lesson_accepted.text.erb | 3 + .../teacher_lesson_accepted.html.erb | 13 +++++ .../teacher_lesson_accepted.text.erb | 3 + .../jam_ruby/constants/notification_types.rb | 5 +- ruby/lib/jam_ruby/message_factory.rb | 20 +++++++ ruby/lib/jam_ruby/models/lesson_booking.rb | 21 +------ ruby/lib/jam_ruby/models/lesson_session.rb | 58 +++++++++++++++++++ ruby/lib/jam_ruby/models/notification.rb | 50 ++++++++++++++-- .../jam_ruby/models/lesson_session_spec.rb | 5 ++ ruby/spec/mailers/render_emails_spec.rb | 14 +++++ .../api_lesson_sessions_controller.rb | 21 +++++++ 15 files changed, 254 insertions(+), 76 deletions(-) create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.text.erb diff --git a/db/up/lessons.sql b/db/up/lessons.sql index 4a118ac27..79f6ac005 100644 --- a/db/up/lessons.sql +++ b/db/up/lessons.sql @@ -52,6 +52,7 @@ CREATE TABLE lesson_sessions ( teacher_canceled_at TIMESTAMP, student_canceled_reason VARCHAR, teacher_canceled_reason VARCHAR, + status VARCHAR, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); @@ -76,6 +77,9 @@ CREATE TABLE lesson_booking_slots ( updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); +ALTER TABLE lesson_bookings ADD COLUMN default_slot VARCHAR(64) REFERENCES lesson_booking_slots(id); +ALTER TABLE lesson_sessions ADD COLUMN slot VARCHAR(64) REFERENCES lesson_booking_slots(id); + ALTER TABLE chat_messages ADD COLUMN target_user_id VARCHAR(64) REFERENCES users(id); ALTER TABLE chat_messages ADD COLUMN lesson_booking_id VARCHAR(64) REFERENCES lesson_bookings(id); ALTER TABLE users ADD COLUMN remaining_free_lessons INTEGER NOT NULL DEFAULT 1; diff --git a/pb/src/client_container.proto b/pb/src/client_container.proto index 4ea8e6dfa..17337f8ce 100644 --- a/pb/src/client_container.proto +++ b/pb/src/client_container.proto @@ -88,10 +88,7 @@ message ClientMessage { MIXDOWN_SIGN_COMPLETE = 270; MIXDOWN_SIGN_FAILED = 271; - LESSON_REQUESTED = 280; - LESSON_ACCEPTED = 281; - LESSON_TEACHER_COUNTER = 282; - LESSON_STUDENT_COUNTER = 283; + LESSON_MESSAGE = 280; TEST_SESSION_MESSAGE = 295; @@ -209,10 +206,7 @@ message ClientMessage { optional MixdownSignFailed mixdown_sign_failed = 271; // lesson notifications - optional LessonRequested lesson_requested = 280; - optional LessonAccepted lesson_accepted = 281; - optional LessonTeacherCounter lesson_teacher_counter = 282; - optional LessonStudentCounter lesson_student_counter = 283; + optional LessonMessage lesson_message = 280; // Client-Session messages (to/from) optional TestSessionMessage test_session_message = 295; @@ -655,40 +649,17 @@ message MixdownSignFailed { required string mixdown_package_id = 1; // jam track mixdown package id } -message LessonRequested { +message LessonMessage { optional string lesson_session_id = 1; optional string photo_url = 2; optional string msg = 3; optional string notification_id = 4; optional string created_at = 5; - optional string user_id = 6; -} - -message LessonAccepted { - optional string lesson_session_id = 1; - optional string photo_url = 2; - optional string msg = 3; - optional string notification_id = 4; - optional string created_at = 5; - optional string user_id = 6 -} - -message LessonTeacherCounter { - optional string lesson_session_id = 1; - optional string photo_url = 2; - optional string msg = 3; - optional string notification_id = 4; - optional string created_at = 5; - optional string user_id = 6 -} - -message LessonStudentCounter { - optional string lesson_session_id = 1; - optional string photo_url = 2; - optional string msg = 3; - optional string notification_id = 4; - optional string created_at = 5; - optional string user_id = 6 + optional string sender_id = 6; + optional string received_id = 7; + optional bool student_directed = 8; + optional string purpose = 9; + optional string sender_name = 10; } diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index ec73a6d9f..643dc302d 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -661,16 +661,46 @@ end end - # def send_notification(email, subject, msg, unique_args) - # @body = msg - # sendgrid_category "Notification" - # sendgrid_unique_args :type => unique_args[:type] - # mail(:bcc => email, :subject => subject) do |format| - # format.text - # format.html - # end - # end - ############################################################################################# + def student_lesson_accepted(lesson_session, message) + @target = lesson_session.student + @sender = lesson_session.teacher + @lesson_session = lesson_session + @message = message + email = @target.email + subject = "Your lesson request is confirmed!" + unique_args = {:type => "student_lesson_accepted"} + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + + sendgrid_recipients([email]) + sendgrid_substitute('@USERID', [@target.id]) + + mail(:to => email, :subject => subject) do |format| + format.text + format.html { render :layout => "from_user_mailer" } + end + end + + def teacher_lesson_accepted(lesson_session, message) + @target = lesson_session.teacher + @sender = lesson_session.student + @lesson_session = lesson_session + @message = message + email = @target.email + subject = "You have confirmed a lesson!" + unique_args = {:type => "teacher_lesson_accepted"} + + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + + sendgrid_recipients([email]) + sendgrid_substitute('@USERID', [@target.id]) + + mail(:to => email, :subject => subject) do |format| + format.text + format.html { render :layout => "from_user_mailer" } + end + end end end diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.html.erb new file mode 100644 index 000000000..336666fd5 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.html.erb @@ -0,0 +1,18 @@ +<% provide(:title, "Your lesson request is confirmed!") %> +<% provide(:photo_url, @sender.resolved_photo_url) %> + +<% content_for :note do %> +

This teacher has accepted your lesson request! + <% if @message %> +

<%= @sender.name %> says: +
<%= @message %> +
+ <% end %> +

Click the button below to get more information and to add this lesson to your calendar! +

We strongly suggest adding this to your calendar so you don't forget it, or you'll end up paying for a lesson you don't get.

+

+ VIEW LESSON DETAILS +

+<% end %> + + diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.text.erb new file mode 100644 index 000000000..d8a9b849e --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_lesson_accepted.text.erb @@ -0,0 +1,3 @@ +Your lesson has been confirmed by <%= @sender.name %>. + +To see this lesson, click here: <%= @lesson_session.web_url %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.html.erb new file mode 100644 index 000000000..46ca523c2 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.html.erb @@ -0,0 +1,13 @@ +<% provide(:title, "You have confirmed a lesson!") %> +<% provide(:photo_url, @sender.resolved_photo_url) %> + +<% content_for :note do %> +

You have confirmed a lesson request for <%= @sender.name %> +

Click the button below to get more information and to add this lesson to your calendar! +

We strongly suggest adding this to your calendar so you don't forget it.

+

+ VIEW LESSON DETAILS +

+<% end %> + + diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.text.erb new file mode 100644 index 000000000..6823a39f7 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/teacher_lesson_accepted.text.erb @@ -0,0 +1,3 @@ +You have confirmed a lesson request for <%= @sender.name %>. + +To see this lesson, click here: <%= @lesson_session.web_url %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/constants/notification_types.rb b/ruby/lib/jam_ruby/constants/notification_types.rb index 8e435088c..4f2332092 100644 --- a/ruby/lib/jam_ruby/constants/notification_types.rb +++ b/ruby/lib/jam_ruby/constants/notification_types.rb @@ -54,8 +54,5 @@ module NotificationTypes MIXDOWN_SIGN_COMPLETE = "MIXDOWN_SIGN_COMPLETE" MIXDOWN_SIGN_FAILED = "MIXDOWN_SIGN_FAILED" - LESSON_REQUESTED = "LESSON_REQUESTED" - LESSON_ACCEPTED = "LESSON_ACCEPTED" - LESSON_TEACHER_COUNTER = "LESSON_TEACHER_COUNTER" - LESSON_STUDENT_COUNTER = "LESSON_STUDENT_COUNTER" + LESSON_MESSAGE = "LESSON_MESSAGE" end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/message_factory.rb b/ruby/lib/jam_ruby/message_factory.rb index 6297b0b23..a5ca37a91 100644 --- a/ruby/lib/jam_ruby/message_factory.rb +++ b/ruby/lib/jam_ruby/message_factory.rb @@ -897,6 +897,26 @@ module JamRuby ) end + # creates the general purpose text message + def lesson_message(receiver_id, sender_photo_url, sender_name, sender_id, msg, notification_id, lesson_session_id, created_at) + lesson_message = Jampb::LessonMessage.new( + :photo_url => sender_photo_url, + :sender_name => sender_name, + :sender_id => sender_id, + :receiver_id => receiver_id, + :msg => msg, + :notification_id => notification_id, + :lesson_session_id => lesson_session_id, + :created_at => created_at + ) + + Jampb::ClientMessage.new( + :type => ClientMessage::Type::LESSON_MESSAGE, + :route_to => USER_TARGET_PREFIX + receiver_id, + :lesson_message => lesson_message + ) + end + # creates the chat message def chat_message(session_id, sender_name, sender_id, msg, msg_id, created_at, channel) chat_message = Jampb::ChatMessage.new( diff --git a/ruby/lib/jam_ruby/models/lesson_booking.rb b/ruby/lib/jam_ruby/models/lesson_booking.rb index 38b08eeee..c97a57458 100644 --- a/ruby/lib/jam_ruby/models/lesson_booking.rb +++ b/ruby/lib/jam_ruby/models/lesson_booking.rb @@ -8,10 +8,9 @@ module JamRuby STATUS_REQUESTED = 'requested' STATUS_CANCELED = 'canceled' - STATUS_MISSED = 'missed' - STATUS_COMPLETED = 'completed' + STATUS_APPROVED = 'approved' - STATUS_TYPES = [STATUS_REQUESTED, STATUS_CANCELED, STATUS_MISSED, STATUS_COMPLETED] + STATUS_TYPES = [STATUS_REQUESTED, STATUS_CANCELED, STATUS_APPROVED] LESSON_TYPE_FREE = 'single-free' LESSON_TYPE_TEST_DRIVE = 'test-drive' @@ -216,22 +215,6 @@ module JamRuby LessonBooking.where(user_id: current_user.id).where(card_presumed_ok: false) end - # teacher accepts the lesson - def accept(params) - - LessonBooking.transaction do - - message = params[:message] - slot = params[:slot] - - self.accepting = true - slot = LessonBookingSlot.find(slot) - self.accepted_slot = slot - msg = ChatMessage.create(teacher, nil, message, ChatMessage::CHANNEL_LESSON, nil, user, self) - end - - end - def home_url APP_CONFIG.external_root_url + "/client#/jamclass" end diff --git a/ruby/lib/jam_ruby/models/lesson_session.rb b/ruby/lib/jam_ruby/models/lesson_session.rb index 27a17c7fc..3da24a51e 100644 --- a/ruby/lib/jam_ruby/models/lesson_session.rb +++ b/ruby/lib/jam_ruby/models/lesson_session.rb @@ -2,8 +2,19 @@ module JamRuby class LessonSession < ActiveRecord::Base + + attr_accessor :accepting + @@log = Logging.logger[LessonSession] + STATUS_REQUESTED = 'requested' + STATUS_CANCELED = 'canceled' + STATUS_MISSED = 'missed' + STATUS_COMPLETED = 'completed' + STATUS_APPROVED = 'approved' + + STATUS_TYPES = [STATUS_REQUESTED, STATUS_CANCELED, STATUS_MISSED, STATUS_COMPLETED, STATUS_APPROVED] + LESSON_TYPE_SINGLE = 'single' LESSON_TYPE_SINGLE_FREE = 'single-free' LESSON_TYPE_TEST_DRIVE = 'test-drive' @@ -18,11 +29,22 @@ module JamRuby validates :lesson_booking, presence: true validates :lesson_type, inclusion: {in: LESSON_TYPES} validates :price, presence: true + validates :status, presence: true, inclusion: {in: STATUS_TYPES} validates :teacher_complete, inclusion: {in: [true, false]} validates :student_complete, inclusion: {in: [true, false]} validates :teacher_canceled, inclusion: {in: [true, false]} validates :student_canceled, inclusion: {in: [true, false]} + validate :validate_accepted, :if => :accepting + + def validate_accepted + + end + + + def student + music_session.creator + end def self.index(user, params = {}) limit = params[:per_page] @@ -55,5 +77,41 @@ module JamRuby { query: query, next_page: next_page } end end + + # teacher accepts the lesson + def accept(params) + LessonSession.transaction do + + message = params[:message] + slot = params[:slot] + update_all = params[:update_all] + + self.accepting = true + slot = LessonBookingSlot.find(slot) + + if lesson_booking.default_slot.nil? || update_all + lesson_booking.accepting = true + lesson_booking.default_slot = slot + lesson_booking.save! + end + + self.slot = slot + + if self.save + msg = ChatMessage.create(teacher, nil, message, ChatMessage::CHANNEL_LESSON, nil, user, self) + Notification.send_lesson_message('accept', self, true) + UserMailer.student_lesson_accepted(self, message) + UserMailer.teacher_lesson_accepted(self, message) + end + end + end + + def home_url + APP_CONFIG.external_root_url + "/client#/jamclass" + end + + def web_url + APP_CONFIG.external_root_url + "/client#/jamclass/lesson-request/" + id + end end end diff --git a/ruby/lib/jam_ruby/models/notification.rb b/ruby/lib/jam_ruby/models/notification.rb index 41fd837fb..2d88ac204 100644 --- a/ruby/lib/jam_ruby/models/notification.rb +++ b/ruby/lib/jam_ruby/models/notification.rb @@ -372,18 +372,56 @@ module JamRuby end end - def send_lesson_requested(lesson_session) + def send_lesson_message(purpose, lesson_session, student_directed) notification = Notification.new - notification.description = NotificationTypes::LESSON_REQUESTED - notification.source_user_id = lesson_booking.user.id - notification.target_user_id = lesson_booking.target.id + notification.description = NotificationTypes::LESSON_MESSAGE + notification.student_directed = student_directed + if !student_directed + notification.source_user_id = lesson_session.user.id + notification.target_user_id = lesson_session.teacher.id + else + notification.source_user_id = lesson_session.teacher.id + notification.target_user_id = lesson_session.user.id + end + + notification.purpose = purpose notification.lesson_session = lesson_session - notification.message = lesson_session.lesson_booking.description notification.session_id = lesson_session.music_session_id + + notification_msg = 'Lesson Changed' + + if purpose == 'requested' + notification_msg = 'You have received a lesson request' + elsif purpose == 'accept' + notification_msg = 'Your lesson request is confirmed!' + elsif purpose == 'declined' + notification_msg = "We're sorry your lesson request has been declined." + elsif purpose == 'counter' + if student_directed + notification_msg = "Instructor has proposed a different time for your lesson." + else + notification_msg = "Student has proposed a different time for your lesson." + end + elsif purpose == 'reschedule' + 'A lesson reschedule has been requested' + end + + notification.message = notification_msg + notification.save - notification_msg = format_msg(notification.description, {:user => follower}) + # receiver_id, sender_photo_url, sender_name, sender_id, msg, clipped_msg, notification_id, created_at + message = @message_factory.lesson_message( + notification.target.id, + notification.source.resolved_photo_url, + notification.source.name, + notification.source.id, + notification_msg, + notification.id, + notification.lesson_session.id, + notification.created_date + ) if follower.id != user.id if user.online diff --git a/ruby/spec/jam_ruby/models/lesson_session_spec.rb b/ruby/spec/jam_ruby/models/lesson_session_spec.rb index 3c07eaa2f..e3126c189 100644 --- a/ruby/spec/jam_ruby/models/lesson_session_spec.rb +++ b/ruby/spec/jam_ruby/models/lesson_session_spec.rb @@ -7,6 +7,11 @@ describe LessonSession do let(:lesson_session) {FactoryGirl.create(:lesson_session, student: user, teacher: teacher)} let(:lesson_session2) {FactoryGirl.create(:lesson_session, student: user, teacher: teacher)} + describe "accept" do + it "can accept" do + + 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 e1d554f06..5eda9de4e 100644 --- a/ruby/spec/mailers/render_emails_spec.rb +++ b/ruby/spec/mailers/render_emails_spec.rb @@ -57,6 +57,20 @@ describe "RenderMailers", :slow => true do lesson_booking = FactoryGirl.create(:lesson_booking) UserMailer.student_lesson_request(lesson_booking).deliver end + + it "teacher_lesson_accepted" do + @filename = "teacher_lesson_accepted" + + lesson_session = FactoryGirl.create(:lesson_session, student: user, teacher: teacher) + UserMailer.teacher_lesson_accepted(lesson_session, "custom message").deliver + end + + it "student_lesson_accepted" do + @filename = "student_lesson_accepted" + + lesson_session = FactoryGirl.create(:lesson_session, student: user, teacher: teacher) + UserMailer.student_lesson_accepted(lesson_session, "custom message").deliver + end end end diff --git a/web/app/controllers/api_lesson_sessions_controller.rb b/web/app/controllers/api_lesson_sessions_controller.rb index 0001d9757..a63066e71 100644 --- a/web/app/controllers/api_lesson_sessions_controller.rb +++ b/web/app/controllers/api_lesson_sessions_controller.rb @@ -1,6 +1,9 @@ class ApiLessonSessionsController < ApiController before_filter :api_signed_in_user + before_filter :lookup_lesson, except: [:index] + before_filter :is_teacher, only: [:accept] + before_filter :is_student, only: [] respond_to :json def index @@ -11,4 +14,22 @@ class ApiLessonSessionsController < ApiController @next = data[:next_page] render "api_lesson_sessions/index", :layout => nil end + + private + + def lookup_lesson + @lesson_session = LessonSession.find(params[:id]) + end + + def is_teacher + if @lesson_session.teacher != current_user + raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR + end + end + + def is_student + if @lesson_session.teacher != current_user + raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR + end + end end