diff --git a/app/api/helpers/mail.py b/app/api/helpers/mail.py
index cb43415219..dab4a7bec8 100644
--- a/app/api/helpers/mail.py
+++ b/app/api/helpers/mail.py
@@ -19,7 +19,7 @@
MONTHLY_PAYMENT_EMAIL,
MONTHLY_PAYMENT_FOLLOWUP_EMAIL,
NEW_SESSION,
- SESSION_ACCEPT_REJECT,
+ SESSION_STATE_CHANGE,
TEST_MAIL,
TICKET_CANCELLED,
TICKET_PURCHASED,
@@ -32,6 +32,9 @@
from app.models.user import User
from app.settings import get_settings
+logger = logging.getLogger(__name__)
+# pytype: disable=attribute-error
+
def check_smtp_config(smtp_encryption):
"""
@@ -168,22 +171,39 @@ def send_email_new_session(email, event_name, link):
)
-def send_email_session_accept_reject(email, session, link):
+def send_email_session_state_change(email, session):
"""email for new session"""
- session_name = session.title
- session_acceptance = session.state
+ event = session.event
+
+ settings = get_settings()
+ app_name = settings['app_name']
+ frontend_url = settings['frontend_url']
+ session_link = "{}/events/{}/sessions/{}".format(
+ frontend_url, event.identifier, session.id
+ )
+ event_link = f"{frontend_url}/e/{event.identifier}"
+
+ context = {
+ 'session_name': session.title,
+ 'session_link': session_link,
+ 'session_state': session.state,
+ 'event_name': event.name,
+ 'event_link': event_link,
+ 'app_name': app_name,
+ 'frontend_link': frontend_url,
+ }
+
+ try:
+ mail = MAILS[SESSION_STATE_CHANGE][session.state]
+ except KeyError:
+ logger.error('No mail found for session state change: ' + session.state)
+ return
+
send_email(
to=email,
- action=SESSION_ACCEPT_REJECT,
- subject=MAILS[SESSION_ACCEPT_REJECT]['subject'].format(
- session_name=session_name, acceptance=session_acceptance
- ),
- html=MAILS[SESSION_ACCEPT_REJECT]['message'].format(
- email=email,
- session_name=session_name,
- acceptance=session_acceptance,
- link=link,
- ),
+ action=SESSION_STATE_CHANGE,
+ subject=mail['subject'].format(**context),
+ html=mail['message'].format(**context),
)
diff --git a/app/api/helpers/notification.py b/app/api/helpers/notification.py
index ee8fcdf99a..9dc5703bab 100644
--- a/app/api/helpers/notification.py
+++ b/app/api/helpers/notification.py
@@ -11,7 +11,7 @@
get_monthly_payment_follow_up_notification_actions,
get_monthly_payment_notification_actions,
get_new_session_notification_actions,
- get_session_accept_reject_notification_actions,
+ get_session_state_change_notification_actions,
get_ticket_purchased_attendee_notification_actions,
get_ticket_purchased_notification_actions,
get_ticket_purchased_organizer_notification_actions,
@@ -27,7 +27,7 @@
MONTHLY_PAYMENT_FOLLOWUP_NOTIF,
MONTHLY_PAYMENT_NOTIF,
NEW_SESSION,
- SESSION_ACCEPT_REJECT,
+ SESSION_STATE_CHANGE,
TICKET_CANCELLED,
TICKET_CANCELLED_ORGANIZER,
TICKET_PURCHASED,
@@ -73,9 +73,9 @@ def send_notif_new_session_organizer(user, event_name, link, session_id):
send_notification(user, title, message, actions)
-def send_notif_session_accept_reject(user, session_name, acceptance, link, session_id):
+def send_notif_session_state_change(user, session_name, acceptance, link, session_id):
"""
- Send notification to the session creator about a session being accepted or rejected.
+ Send notification to the session creator about a session status being changed.
:param user:
:param session_name:
:param acceptance:
@@ -84,11 +84,11 @@ def send_notif_session_accept_reject(user, session_name, acceptance, link, sessi
:return:
"""
message_settings = MessageSettings.query.filter_by(
- action=SESSION_ACCEPT_REJECT
+ action=SESSION_STATE_CHANGE
).first()
if not message_settings or message_settings.notification_status == 1:
- actions = get_session_accept_reject_notification_actions(session_id, link)
- notification = NOTIFS[SESSION_ACCEPT_REJECT]
+ actions = get_session_state_change_notification_actions(session_id, link)
+ notification = NOTIFS[SESSION_STATE_CHANGE]
title = notification['title'].format(
session_name=session_name, acceptance=acceptance
)
@@ -156,7 +156,7 @@ def send_notif_monthly_fee_payment(
:return:
"""
message_settings = MessageSettings.query.filter_by(
- action=SESSION_ACCEPT_REJECT
+ action=SESSION_STATE_CHANGE
).first()
if not message_settings or message_settings.notification_status == 1:
actions = get_monthly_payment_notification_actions(event_id, link)
@@ -184,7 +184,7 @@ def send_followup_notif_monthly_fee_payment(
:return:
"""
message_settings = MessageSettings.query.filter_by(
- action=SESSION_ACCEPT_REJECT
+ action=SESSION_STATE_CHANGE
).first()
if not message_settings or message_settings.notification_status == 1:
actions = get_monthly_payment_follow_up_notification_actions(event_id, link)
diff --git a/app/api/helpers/system_mails.py b/app/api/helpers/system_mails.py
index 114512248d..910f2a957d 100644
--- a/app/api/helpers/system_mails.py
+++ b/app/api/helpers/system_mails.py
@@ -19,8 +19,8 @@
PASSWORD_CHANGE,
PASSWORD_RESET,
PASSWORD_RESET_AND_VERIFY,
- SESSION_ACCEPT_REJECT,
SESSION_SCHEDULE,
+ SESSION_STATE_CHANGE,
TEST_MAIL,
TICKET_CANCELLED,
TICKET_PURCHASED,
@@ -52,14 +52,74 @@
+ u"
Visit this link to fill up details: {link}"
),
},
- SESSION_ACCEPT_REJECT: {
+ SESSION_STATE_CHANGE: {
'recipient': 'Speaker',
- 'subject': u'Session {session_name} has been {acceptance}',
- 'message': (
- u"Hi {email},
"
- + u"The session {session_name} has been {acceptance} by the organizer. "
- + u"
Visit this link to view the session: {link}"
- ),
+ 'pending': {
+ 'subject': 'Your speaker submission for {event_name} titled {session_name}',
+ 'message': "Hello,
"
+ "This is an automatic message from {app_name}.
"
+ "We have received your submission {session_name} for {event_name}
"
+ "Your proposal will be reviewed by the event organizers and review team. The current status of your session is now \"Pending\".
"
+ "You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.
"
+ "More details about the event are on the event page at {event_link}.
"
+ "Thank you.
"
+ "{app_name}",
+ },
+ 'accepted': {
+ 'subject': 'Accepted! Congratulations Your submission for {event_name} titled {session_name} has been Accepted',
+ 'message': "Hello,
"
+ "This is an automatic message from {app_name}.
"
+ "Your session status for the submission {session_name} for {event_name} was changed to \"Accepted\". Congratulations!
"
+ "Your proposal will be scheduled by the event organizers and review team. Please (re)confirm your participation with the organizers of the event, if required.
"
+ "You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.
"
+ "More details about the event are on the event page at {event_link}.
"
+ "Thank you.
"
+ "{app_name}",
+ },
+ 'confirmed': {
+ 'subject': 'Confirmed! Congratulations Your submission for {event_name} titled {session_name} has been Confirmed',
+ 'message': "Hello,
"
+ "This is an automatic message from {app_name}.
"
+ "Your session status for the submission {session_name} for {event_name} was changed to \"Confirmed\". Congratulations!
"
+ "Your proposal will be scheduled by the event organizers and review team. Please inform the event organizers in case there are any changes to your participation.
"
+ "You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.
"
+ "More details about the event are on the event page at {event_link}.
"
+ "Thank you.
"
+ "{app_name}",
+ },
+ 'rejected': {
+ 'subject': 'Not Accepted. Your submission for {event_name} titled {session_name} was not accepted',
+ 'message': "Hello,
"
+ "This is an automatic message from {app_name}.
"
+ "Unfortunately your submission {session_name} for {event_name} was not accepted. Your session status was changed to \"Rejected\".
"
+ "The status change was done by event organizers. If there are questions about this change please contact the organizers.
"
+ "You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.
"
+ "More details about the event are on the event page at {event_link}.
"
+ "Thank you.
"
+ "{app_name}",
+ },
+ 'canceled': {
+ 'subject': 'Canceled! Your submission for {event_name} titled {session_name} has been Canceled',
+ 'message': "Hello,
"
+ "This is an automatic message from {app_name}.
"
+ "Your session status for the submission {session_name} for {event_name} was changed to \"Canceled\".
"
+ "The status change was done by event organizers. If there are questions about this change please contact the organizers.
"
+ "You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.
"
+ "More details about the event are on the event page at {event_link}.
"
+ "Thank you.
"
+ "{app_name}",
+ },
+ 'withdrawn': {
+ 'subject': 'Withdrawn! Your submission for {event_name} titled {session_name} has been Withdrawn',
+ 'message': "Hello,
"
+ "This is an automatic message from {app_name}.
"
+ "Your session status for the submission {session_name} for {event_name} was changed to \"Withdrawn\".
"
+ "The status change was done by event organizers. If there are questions about this change please contact the organizers.
"
+ "You can also check the status and details of your submission on the session page {session_link}. You need to be logged in to view it.
"
+ "More details about the event are on the event page at {event_link}.
"
+ "Thank you.
"
+ "{app_name}",
+ },
},
SESSION_SCHEDULE: {
'recipient': 'Owner, Organizer, Speaker',
diff --git a/app/api/helpers/system_notifications.py b/app/api/helpers/system_notifications.py
index 7cbfac1565..e6a45fd24d 100644
--- a/app/api/helpers/system_notifications.py
+++ b/app/api/helpers/system_notifications.py
@@ -16,8 +16,8 @@
NEW_SESSION,
NEXT_EVENT,
PASSWORD_CHANGE,
- SESSION_ACCEPT_REJECT,
SESSION_SCHEDULE,
+ SESSION_STATE_CHANGE,
TICKET_CANCELLED,
TICKET_CANCELLED_ORGANIZER,
TICKET_PURCHASED,
@@ -201,9 +201,9 @@ def get_next_event_notification_actions(event_id, link):
return [view_event_action]
-def get_session_accept_reject_notification_actions(session_id, link):
+def get_session_state_change_notification_actions(session_id, link):
"""
- Get the actions associated with a notification of a session getting accepted/rejected.
+ Get the actions associated with a notification of a session status being changed.
:param session_id: id of the session.
:param link: link to view the session.
:return: actions
@@ -363,7 +363,7 @@ def get_invite_papers_notification_actions(cfs_link, submit_link):
'message': u"Here are upcoming events: {up_coming_events}.",
'recipient': 'Owner, Organizer, Speaker',
},
- SESSION_ACCEPT_REJECT: {
+ SESSION_STATE_CHANGE: {
'title': u'Session {session_name} has been {acceptance}',
'message': u"The session {session_name} has been"
+ u" {acceptance} by the Organizer.",
diff --git a/app/api/helpers/tasks.py b/app/api/helpers/tasks.py
index 54338b066d..3baa72e980 100644
--- a/app/api/helpers/tasks.py
+++ b/app/api/helpers/tasks.py
@@ -100,8 +100,8 @@ def send_email_task_sendgrid(payload, headers, smtp_config):
message.add_attachment(attachment)
sendgrid_client = SendGridAPIClient(get_settings()['sendgrid_key'])
logging.info(
- 'Sending an email regarding {} on behalf of {}'.format(
- payload["subject"], payload["from"]
+ 'Sending an email to {} regarding "{}" on behalf of {}'.format(
+ payload['to'], payload["subject"], payload["from"]
)
)
try:
diff --git a/app/api/schema/message_settings.py b/app/api/schema/message_settings.py
index 5477836378..b22e501cc4 100644
--- a/app/api/schema/message_settings.py
+++ b/app/api/schema/message_settings.py
@@ -14,7 +14,7 @@
PASSWORD_RESET = 'Reset Password'
PASSWORD_CHANGE = 'Change Password'
EVENT_ROLE = 'Event Role Invitation'
-SESSION_ACCEPT_REJECT = 'Session Accept or Reject'
+SESSION_STATE_CHANGE = 'Session State Change'
SESSION_SCHEDULE = 'Session Schedule Change'
EVENT_PUBLISH = 'Event Published'
AFTER_EVENT = 'After Event'
@@ -60,7 +60,7 @@ class Meta:
USER_REGISTER,
PASSWORD_RESET,
EVENT_ROLE,
- SESSION_ACCEPT_REJECT,
+ SESSION_STATE_CHANGE,
SESSION_SCHEDULE,
NEXT_EVENT,
EVENT_PUBLISH,
diff --git a/app/api/sessions.py b/app/api/sessions.py
index eb2a97f3c8..10247bb364 100644
--- a/app/api/sessions.py
+++ b/app/api/sessions.py
@@ -9,10 +9,10 @@
from app.api.helpers.db import get_count, safe_query, safe_query_kwargs, save_to_db
from app.api.helpers.errors import ForbiddenError
from app.api.helpers.files import make_frontend_url
-from app.api.helpers.mail import send_email_new_session, send_email_session_accept_reject
+from app.api.helpers.mail import send_email_new_session, send_email_session_state_change
from app.api.helpers.notification import (
send_notif_new_session_organizer,
- send_notif_session_accept_reject,
+ send_notif_session_state_change,
)
from app.api.helpers.permission_manager import has_access
from app.api.helpers.query import event_query
@@ -259,7 +259,14 @@ def before_update_object(self, session, data, view_kwargs):
if new_state and new_state != session.state:
# State change detected. Verify that state change is allowed
- g.send_email = new_state == 'accepted' or new_state == 'rejected'
+ g.send_email = new_state in [
+ 'accepted',
+ 'rejected',
+ 'confirmed',
+ 'rejected',
+ 'canceled',
+ 'withdrawn',
+ ]
key = 'speaker'
if is_organizer:
key = 'organizer'
@@ -294,32 +301,8 @@ def after_update_object(self, session, data, view_kwargs):
""" Send email if session accepted or rejected """
if data.get('send_email', None) and g.get('send_email'):
- event = session.event
- # Email for speaker
- speakers = session.speakers
- for speaker in speakers:
- frontend_url = get_settings()['frontend_url']
- link = "{}/events/{}/sessions/{}".format(
- frontend_url, event.identifier, session.id
- )
- if not speaker.is_email_overridden:
- send_email_session_accept_reject(speaker.email, session, link)
- send_notif_session_accept_reject(
- speaker, session.title, session.state, link, session.id
- )
+ notify_for_session(session)
- # Email for owner
- if session.event.get_owner():
- owner = session.event.get_owner()
- owner_email = owner.email
- frontend_url = get_settings()['frontend_url']
- link = "{}/events/{}/sessions/{}".format(
- frontend_url, event.identifier, session.id
- )
- send_email_session_accept_reject(owner_email, session, link)
- send_notif_session_accept_reject(
- owner, session.title, session.state, link, session.id
- )
if 'state' in data:
entry_count = SessionsSpeakersLink.query.filter_by(session_id=session.id)
if entry_count.count() == 0:
@@ -355,6 +338,28 @@ def after_update_object(self, session, data, view_kwargs):
}
+def notify_for_session(session):
+ event = session.event
+ frontend_url = get_settings()['frontend_url']
+ link = "{}/events/{}/sessions/{}".format(frontend_url, event.identifier, session.id)
+ # Email for speaker
+ speakers = session.speakers
+ for speaker in speakers:
+ if not speaker.is_email_overridden:
+ send_email_session_state_change(speaker.email, session)
+ send_notif_session_state_change(
+ speaker.user, session.title, session.state, link, session.id
+ )
+
+ # Email for owner
+ if session.event.get_owner():
+ owner = session.event.get_owner()
+ send_email_session_state_change(owner.email, session)
+ send_notif_session_state_change(
+ owner, session.title, session.state, link, session.id
+ )
+
+
class SessionRelationshipRequired(ResourceRelationship):
"""
Session Relationship
diff --git a/app/models/mail.py b/app/models/mail.py
index d6b93c2ef5..4aeb8293fa 100644
--- a/app/models/mail.py
+++ b/app/models/mail.py
@@ -13,7 +13,7 @@
PASSWORD_CHANGE = 'Change Password'
EVENT_ROLE = 'Event Role Invitation'
USER_EVENT_ROLE = 'User Event Role Invitation'
-SESSION_ACCEPT_REJECT = 'Session Accept or Reject'
+SESSION_STATE_CHANGE = 'Session State Change'
SESSION_SCHEDULE = 'Session Schedule Change'
EVENT_PUBLISH = 'Event Published'
AFTER_EVENT = 'After Event'
diff --git a/app/models/message_setting.py b/app/models/message_setting.py
index e5eacc8471..603616944a 100644
--- a/app/models/message_setting.py
+++ b/app/models/message_setting.py
@@ -14,7 +14,7 @@
PASSWORD_RESET = 'Reset Password'
PASSWORD_CHANGE = 'Change Password'
EVENT_ROLE = 'Event Role Invitation'
-SESSION_ACCEPT_REJECT = 'Session Accept or Reject'
+SESSION_STATE_CHANGE = 'Session State Change'
SESSION_SCHEDULE = 'Session Schedule Change'
EVENT_PUBLISH = 'Event Published'
AFTER_EVENT = 'After Event'
@@ -58,7 +58,7 @@ def _email_message(cls, action, attr=None):
USER_REGISTER,
PASSWORD_RESET,
EVENT_ROLE,
- SESSION_ACCEPT_REJECT,
+ SESSION_STATE_CHANGE,
SESSION_SCHEDULE,
NEXT_EVENT,
EVENT_PUBLISH,
@@ -107,7 +107,7 @@ def _notification_message(cls, action, attr=None):
NEW_SESSION,
SESSION_SCHEDULE,
NEXT_EVENT,
- SESSION_ACCEPT_REJECT,
+ SESSION_STATE_CHANGE,
INVITE_PAPERS,
AFTER_EVENT,
EVENT_PUBLISH,
diff --git a/app/models/notification.py b/app/models/notification.py
index 976191f7af..2eec20afa4 100644
--- a/app/models/notification.py
+++ b/app/models/notification.py
@@ -13,7 +13,7 @@
EVENT_IMPORTED = 'Event Imported'
SESSION_SCHEDULE = 'Session Schedule Change'
NEXT_EVENT = 'Next Event'
-SESSION_ACCEPT_REJECT = 'Session Accept or Reject'
+SESSION_STATE_CHANGE = 'Session State Change'
INVITE_PAPERS = 'Invitation For Papers'
AFTER_EVENT = 'After Event'
EVENT_PUBLISH = 'Event Published'
diff --git a/migrations/versions/rev-2020-08-08-16:56:27-61bec04ae010_.py b/migrations/versions/rev-2020-08-08-16:56:27-61bec04ae010_.py
new file mode 100644
index 0000000000..a610aa8e7b
--- /dev/null
+++ b/migrations/versions/rev-2020-08-08-16:56:27-61bec04ae010_.py
@@ -0,0 +1,30 @@
+"""empty message
+
+Revision ID: 61bec04ae010
+Revises: 507022789bcb
+Create Date: 2020-08-08 16:56:27.061106
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+import sqlalchemy_utils
+
+
+# revision identifiers, used by Alembic.
+revision = '61bec04ae010'
+down_revision = '507022789bcb'
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.execute("UPDATE mails set action = 'Session State Change' WHERE action = 'Session Accept or Reject'")
+ op.execute("UPDATE message_settings set action = 'Session State Change' WHERE action = 'Session Accept or Reject'")
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.execute("UPDATE mails set action = 'Session Accept or Reject' WHERE action = 'Session State Change'")
+ op.execute("UPDATE message_settings set action = 'Session Accept or Reject' WHERE action = 'Session State Change'")
+ # ### end Alembic commands ###
diff --git a/populate_db.py b/populate_db.py
index e47dfc6270..5c979a685f 100644
--- a/populate_db.py
+++ b/populate_db.py
@@ -351,7 +351,7 @@ def create_admin_message_settings():
"Invitation For Papers",
"After Event",
"Ticket(s) Purchased",
- "Session Accept or Reject",
+ "Session State Change",
"Event Published",
"Event Export Failed",
"Event Exported",
diff --git a/tests/all/integration/api/helpers/test_notification.py b/tests/all/integration/api/helpers/test_notification.py
index e8e75569a4..208b592878 100644
--- a/tests/all/integration/api/helpers/test_notification.py
+++ b/tests/all/integration/api/helpers/test_notification.py
@@ -8,7 +8,7 @@
send_notif_event_role,
send_notif_monthly_fee_payment,
send_notif_new_session_organizer,
- send_notif_session_accept_reject,
+ send_notif_session_state_change,
send_notif_ticket_purchase_organizer,
)
from app.models.notification import Notification
@@ -39,9 +39,9 @@ def test_send_notif_new_session_organizer(user):
)
-def test_send_notif_session_accept_reject(user):
+def test_send_notif_session_state_change(user):
"""Method to test session accept reject notification"""
- send_notif_session_accept_reject(
+ send_notif_session_state_change(
user, 'Homeless Therapy', 'accepted', link, 1,
)
notification = Notification.query.first()
diff --git a/tests/all/integration/api/helpers/test_systemnotifications.py b/tests/all/integration/api/helpers/test_systemnotifications.py
index 89e2306c47..204274eee1 100644
--- a/tests/all/integration/api/helpers/test_systemnotifications.py
+++ b/tests/all/integration/api/helpers/test_systemnotifications.py
@@ -10,8 +10,8 @@
get_monthly_payment_notification_actions,
get_new_session_notification_actions,
get_next_event_notification_actions,
- get_session_accept_reject_notification_actions,
get_session_schedule_notification_actions,
+ get_session_state_change_notification_actions,
get_ticket_purchased_attendee_notification_actions,
get_ticket_purchased_notification_actions,
get_ticket_purchased_organizer_notification_actions,
@@ -277,7 +277,7 @@ def test_session_accept_reject_notif(self):
with self.app.test_request_context():
request_url = 'https://localhost/e/session/345525'
request_session_id = 1
- response = get_session_accept_reject_notification_actions(
+ response = get_session_state_change_notification_actions(
request_session_id, request_url
)
expected_action = NotificationAction(