Repository: fossasia/open-event-server

Issue:
Implement Create Session for Speakers through Call for Speakers Page
Parent Issue: https://github.com/fossasia/open-event-orga-server/issues/965

**Email and Login**
- [x] If user is logged in prefill in field "Email" with system email (and make it non-changeable). Add a message: "You can change this email in your profile settings."
- [x] Show "Drafts" in the list of sessions for an event of organizers, but do not send an email to them.
- [x] Send an email to organizer when a user "Submitted" a form with a link to view the session. (#1065)
- [x] Add button "Submit Proposal" to page "Call for Speakers" (`/e/ID/cfs/`) and open form as Lightbox. (#1032)
  - [x] If user was not logged in: After that follow and ensure flow for sign up as defined in https://github.com/fossasia/open-event-orga-server/issues/639
  - [x] If user was logged in he/she needs to have the email prefilled in as mentioned above.
  - [x] If user is not logged in, but wants to use an email address that is registered already, prompt the speaker to login to use that email address or use another email.



Discussion:

Resolving patch:
diff --git a/open_event/helpers/data.py b/open_event/helpers/data.py
--- a/open_event/helpers/data.py
+++ b/open_event/helpers/data.py
@@ -14,7 +14,7 @@
 from werkzeug import secure_filename
 from wtforms import ValidationError
 
-from open_event.helpers.helpers import string_empty
+from open_event.helpers.helpers import string_empty, send_new_session_organizer
 from ..helpers.update_version import VersionUpdater
 from ..helpers.data_getter import DataGetter
 from open_event.helpers.storage import upload
@@ -152,7 +152,9 @@ def add_session_to_event(form, event_id, speaker_img_file, slide_file, audio_fil
                               short_abstract=form.get('short_abstract', ''),
                               state=state)
 
-        new_speaker = Speaker(name=form.get('name', ''),
+        speaker = Speaker.query.filter_by(email=form.get('email', '')).filter_by(event_id=event_id).first()
+        if not speaker:
+            speaker = Speaker(name=form.get('name', ''),
                               short_biography=form.get('short_biography', ''),
                               email=form.get('email', ''),
                               website=form.get('website', ''),
@@ -166,9 +168,16 @@ def add_session_to_event(form, event_id, speaker_img_file, slide_file, audio_fil
                               country=form.get('country', ''),
                               user=login.current_user if login and login.current_user.is_authenticated else None)
 
-        new_session.speakers.append(new_speaker)
+        new_session.speakers.append(speaker)
         save_to_db(new_session, "Session saved")
 
+        if state == 'pending':
+            link = url_for('event_sessions.session_display_view',
+                           event_id=event.id, session_id=new_session.id, _external=True)
+            organizers = DataGetter.get_user_event_roles_by_role_name(event.id, 'organizer')
+            for organizer in organizers:
+                send_new_session_organizer(organizer.user.email, event.name, link)
+
         slide_url = ""
         if slide_file != "":
             slide_url = upload(slide_file,
@@ -184,14 +193,14 @@ def add_session_to_event(form, event_id, speaker_img_file, slide_file, audio_fil
         speaker_img = ""
         if speaker_img_file != "":
             speaker_img = upload(speaker_img_file,
-                                 'events/%d/speaker/%d/photo' % (int(event_id), int(new_speaker.id)))
+                                 'events/%d/speaker/%d/photo' % (int(event_id), int(speaker.id)))
 
-        new_speaker.photo = speaker_img
+        speaker.photo = speaker_img
         new_session.audio = audio_url
         new_session.video = video_url
         new_session.slides = slide_url
         save_to_db(new_session, "Session saved")
-        save_to_db(new_speaker, "Speaker saved")
+        save_to_db(speaker, "Speaker saved")
         update_version(event_id, False, "speakers_ver")
         update_version(event_id, False, "session_ver")
 
@@ -207,14 +216,18 @@ def add_session_to_event(form, event_id, speaker_img_file, slide_file, audio_fil
             Helper.send_email_invitation(email, new_session.title, link)
 
     @staticmethod
-    def add_speaker_to_session(form, event_id, session_id):
+    def add_speaker_to_session(form, event_id, session_id, user=login.current_user):
         """
         Session will be saved to database with proper Event id
+        :param session_id:
+        :param user:
         :param form: view data form
         :param event_id: Session belongs to Event by event id
         """
         session = DataGetter.get_session(session_id)
-        new_speaker = Speaker(name=form["name"] if "name" in form.keys() else "",
+        speaker = Speaker.query.filter_by(email=form.get('email', '')).filter_by(event_id=event_id).first()
+        if not speaker:
+            speaker = Speaker(name=form["name"] if "name" in form.keys() else "",
                               photo=form["photo"] if "photo" in form.keys() else "",
                               short_biography=form["short_biography"] if "short_biography" in form.keys() else "",
                               email=form["email"] if "email" in form.keys() else "",
@@ -227,8 +240,8 @@ def add_speaker_to_session(form, event_id, session_id):
                               organisation=form["organisation"] if "organisation" in form.keys() else "",
                               position=form["position"] if "position" in form.keys() else "",
                               country=form["country"] if "country" in form.keys() else "",
-                              user=login.current_user)
-        session.speakers.append(new_speaker)
+                              user=user)
+        session.speakers.append(speaker)
         save_to_db(session, "Speaker saved")
         update_version(event_id, False, "speakers_ver")
 
@@ -236,7 +249,8 @@ def add_speaker_to_session(form, event_id, session_id):
     def create_speaker_session_relation(session_id, speaker_id, event_id):
         """
         Session, speaker ids will be saved to database
-        :param form: view data form
+        :param speaker_id:
+        :param session_id:
         :param event_id: Session, speaker belongs to Event by event id
         """
         speaker = DataGetter.get_speaker(speaker_id)
@@ -289,27 +303,28 @@ def remove_session(session_id):
         flash('You successfully delete session')
 
     @staticmethod
-    def create_speaker(form, event_id):
+    def create_speaker(form, event_id, user=login.current_user):
         """
         Speaker will be saved to database with proper Event id
+        :param user:
         :param form: view data form
         :param event_id: Speaker belongs to Event by event id
         """
-        new_speaker = Speaker(name=form["name"],
-                              photo="",
-                              short_biography=form["short_biography"],
-                              email=form["email"],
-                              website=form["website"],
-                              event_id=event_id,
-                              twitter="",
-                              facebook="",
-                              github="",
-                              linkedin="",
-                              organisation=form["organisation"],
-                              position="",
-                              country="",
-                              user=login.current_user)
-        save_to_db(new_speaker, "Speaker saved")
+        speaker = Speaker(name=form["name"] if "name" in form.keys() else "",
+                          photo=form["photo"] if "photo" in form.keys() else "",
+                          short_biography=form["short_biography"] if "short_biography" in form.keys() else "",
+                          email=form["email"] if "email" in form.keys() else "",
+                          website=form["website"] if "website" in form.keys() else "",
+                          event_id=event_id,
+                          twitter=form["twitter"] if "twitter" in form.keys() else "",
+                          facebook=form["facebook"] if "facebook" in form.keys() else "",
+                          github=form["github"] if "github" in form.keys() else "",
+                          linkedin=form["linkedin"] if "linkedin" in form.keys() else "",
+                          organisation=form["organisation"] if "organisation" in form.keys() else "",
+                          position=form["position"] if "position" in form.keys() else "",
+                          country=form["country"] if "country" in form.keys() else "",
+                          user=user)
+        save_to_db(speaker, "Speaker saved")
         update_version(event_id, False, "speakers_ver")
 
     @staticmethod
diff --git a/open_event/helpers/data_getter.py b/open_event/helpers/data_getter.py
--- a/open_event/helpers/data_getter.py
+++ b/open_event/helpers/data_getter.py
@@ -1,6 +1,7 @@
 """Copyright 2015 Rafal Kowalski"""
 from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound
 
+from open_event.models.role import Role
 from ..models.event import Event, EventsUsers
 from ..models.session import Session
 from ..models.track import Track
@@ -263,6 +264,10 @@ def get_user_events_roles(event_id):
     def get_user_event_role(role_id):
         return UsersEventsRoles.query.get(role_id)
 
+    @staticmethod
+    def get_user_event_roles_by_role_name(event_id, role_name):
+        return UsersEventsRoles.query.filter_by(event_id=event_id).filter(Role.name == role_name)
+
     @staticmethod
     def get_user_events():
         return Event.query.join(Event.roles, aliased=True).filter_by(user_id=login.current_user.id)
diff --git a/open_event/helpers/helpers.py b/open_event/helpers/helpers.py
--- a/open_event/helpers/helpers.py
+++ b/open_event/helpers/helpers.py
@@ -28,32 +28,42 @@ def is_track_name_unique_in_event(form, event_id, *args):
             return str(track.id) == track_id
         return True
 
-
 HEADERS = {
-    "Authorization": ("Bearer SG.55ztiWJxQYuYK7ToThxDPA.rAc929FzcDQsyj" \
+    "Authorization": ("Bearer SG.55ztiWJxQYuYK7ToThxDPA.rAc929FzcDQsyj"
                       "VwmIvKlPoc1YVpKCSOwhEFWZvxFT8")
 }
 
-
 def send_email_invitation(email, event_name, link):
     """Send email after account create"""
     payload = {'to': email,
                'from': 'open-event@googlegroups.com',
                'subject': "Invitation to Submit Papers for " + event_name,
-               "html": ("Hi %s<br/>" % str(email) + \
-                        "You are invited to submit papers for event: %s" % str(event_name) + \
+               "html": ("Hi %s<br/>" % str(email) +
+                        "You are invited to submit papers for event: %s" % str(event_name) +
                         "<br/> Visit this link to fill up details: %s" % link)}
     requests.post("https://api.sendgrid.com/api/mail.send.json",
                   data=payload,
                   headers=HEADERS)
 
+def send_new_session_organizer(email, event_name, link):
+    """Send email after account create"""
+    payload = {'to': email,
+               'from': 'open-event@googlegroups.com',
+               'subject': "New session proposal for " + event_name,
+               "html": ("Hi %s<br/>" % str(email) +
+                        "The event <strong>%s</strong> has received a new session proposal. " % str(event_name) +
+                        "<br/> Visit this link to view the session: %s" % link)}
+    requests.post("https://api.sendgrid.com/api/mail.send.json",
+                  data=payload,
+                  headers=HEADERS)
+
 
 def send_email_after_account_create(form):
     """Send email after account create"""
     payload = {'to': form['email'],
                'from': 'open-event@googlegroups.com',
                'subject': "Account Created on Open Event",
-               "html": ("Your Account Has Been Created! Congratulations!" \
+               "html": ("Your Account Has Been Created! Congratulations!"
                         "<br/> Your login: ") + form['email']}
     requests.post("https://api.sendgrid.com/api/mail.send.json",
                   data=payload,
@@ -65,7 +75,7 @@ def send_email_confirmation(form, link):
     payload = {'to': form['email'],
                'from': 'open-event@googlegroups.com',
                'subject': "Email Confirmation to Create Account for Open-Event ",
-               "html": ("Hi %s<br/>" % str(form['email']) + \
+               "html": ("Hi %s<br/>" % str(form['email']) +
                         "<br/> Please visit this link to confirm your email: %s" % link)}
 
     requests.post("https://api.sendgrid.com/api/mail.send.json",


Test patch: