Commit afbf3e61 by Waheed Ahmed

Course run submit to PC for review instead of MKTG.

ECOM-7526
parent 7f9e7bd2
......@@ -329,18 +329,24 @@ class CourseRunStateSerializerTests(TestCase):
serializer.update(self.run_state, data)
self.assertEqual(self.run_state.name, CourseRunStateChoices.Review)
self.assertEqual(len(mail.outbox), 1)
course_key = CourseKey.from_string(self.course_run.lms_course_id)
subject = 'Review requested: {course_name} {run_name}'.format(
course_name=self.course_run.course.title,
run_name=course_key.run
)
self.assertIn(subject, str(mail.outbox[0].subject))
self.assertFalse(self.run_state.preview_accepted)
serializer.update(self.run_state, {'preview_accepted': True})
self.assertTrue(CourseRun.objects.get(id=self.course_run.id).preview_url)
self.assertEqual(len(mail.outbox), 1)
course_key = CourseKey.from_string(self.course_run.lms_course_id)
self.assertEqual(len(mail.outbox), 2)
subject = 'Publication requested: {course_name} {run_name}'.format(
course_name=self.course_run.course.title,
run_name=course_key.run
)
self.assertIn(subject, str(mail.outbox[0].subject))
self.assertIn(subject, str(mail.outbox[1].subject))
def test_update_with_error(self):
"""
......
......@@ -625,10 +625,10 @@ class ChangeCourseRunStateViewTests(TestCase):
Verify that user can change course-run workflow state and owner role will be changed to `CourseTeam`.
"""
self.run_state.name = CourseRunStateChoices.Draft
self.run_state.owner_role = PublisherUserRole.MarketingReviewer
self.run_state.owner_role = PublisherUserRole.ProjectCoordinator
self.run_state.save()
self._assign_role(self.course_run.course, PublisherUserRole.MarketingReviewer, self.user)
self._assign_role(self.course_run.course, PublisherUserRole.ProjectCoordinator, self.user)
course_team_user = UserFactory()
self._assign_role(self.course_run.course, PublisherUserRole.CourseTeam, course_team_user)
......@@ -663,7 +663,7 @@ class ChangeCourseRunStateViewTests(TestCase):
self.run_state.save()
self._assign_role(self.course_run.course, PublisherUserRole.CourseTeam, self.user)
self._assign_role(self.course_run.course, PublisherUserRole.MarketingReviewer, UserFactory())
self._assign_role(self.course_run.course, PublisherUserRole.ProjectCoordinator, UserFactory())
self._assign_role(self.course_run.course, PublisherUserRole.Publisher, UserFactory())
......
......@@ -123,8 +123,21 @@ def send_email_for_send_for_review(course, user):
subject = _('Changes to {title} are ready for review').format(title=course.title) # pylint: disable=no-member
try:
recipient_user = course.marketing_reviewer
user_role = course.course_user_roles.get(user=user)
if user_role.role == PublisherUserRole.MarketingReviewer:
recipient_user = course.course_team_admin
page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': course.id})
send_course_workflow_email(course, user, subject, txt_template, html_template, page_path)
context = {
'course_name': course.title,
'sender_team': 'course team' if user_role.role == PublisherUserRole.CourseTeam else 'marketing team',
'page_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path
)
}
send_course_workflow_email(course, user, subject, txt_template, html_template, context, recipient_user)
except Exception: # pylint: disable=broad-except
logger.exception('Failed to send email notifications send for review of course %s', course.id)
......@@ -141,14 +154,26 @@ def send_email_for_mark_as_reviewed(course, user):
subject = _('Changes to {title} has been approved').format(title=course.title) # pylint: disable=no-member
try:
recipient_user = course.marketing_reviewer
user_role = course.course_user_roles.get(user=user)
if user_role.role == PublisherUserRole.MarketingReviewer:
recipient_user = course.course_team_admin
page_path = reverse('publisher:publisher_course_detail', kwargs={'pk': course.id})
send_course_workflow_email(course, user, subject, txt_template, html_template, page_path)
context = {
'course_name': course.title,
'sender_team': 'course team' if user_role.role == PublisherUserRole.CourseTeam else 'marketing team',
'page_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path
)
}
send_course_workflow_email(course, user, subject, txt_template, html_template, context, recipient_user)
except Exception: # pylint: disable=broad-except
logger.exception('Failed to send email notifications mark as reviewed of course %s', course.id)
def send_course_workflow_email(course, user, subject, txt_template, html_template, page_path, course_name=None,
run_number=None):
def send_course_workflow_email(course, user, subject, txt_template, html_template, context, recipient_user):
""" Send email for course workflow state change.
Arguments:
......@@ -157,31 +182,22 @@ def send_course_workflow_email(course, user, subject, txt_template, html_templat
subject (String): Email subject
txt_template: (String): Email text template path
html_template: (String): Email html template path
page_path: (URL): Detail page url
course_name: (String): Custom course name, by default None
run_number: (String): Course run number, by default None
context: (Dict): Email template context
recipient_user: (Object): User object
"""
recipient_user = course.marketing_reviewer
user_role = course.course_user_roles.get(user=user)
if user_role.role == PublisherUserRole.MarketingReviewer:
recipient_user = course.course_team_admin
if is_email_notification_enabled(recipient_user):
project_coordinator = course.project_coordinator
to_addresses = [recipient_user.email]
from_address = settings.PUBLISHER_FROM_EMAIL
context = {
context.update(
{
'recipient_name': recipient_user.full_name or recipient_user.username if recipient_user else '',
'sender_name': user.full_name or user.username,
'course_name': course_name if course_name else course.title,
'run_number': run_number,
'org_name': course.organizations.all().first().name,
'sender_team': 'course team' if user_role.role == PublisherUserRole.MarketingReviewer else 'marketing team',
'contact_us_email': project_coordinator.email if project_coordinator else '',
'page_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path
)
}
)
template = get_template(txt_template)
plain_content = template.render(context)
template = get_template(html_template)
......@@ -201,18 +217,31 @@ def send_email_for_send_for_review_course_run(course_run, user):
course-run (Object): CourseRun object
user (Object): User object
"""
course = course_run.course
course_key = CourseKey.from_string(course_run.lms_course_id)
txt_template = 'publisher/email/course_run/send_for_review.txt'
html_template = 'publisher/email/course_run/send_for_review.html'
subject = _('Review requested: {title} {run_number}').format( # pylint: disable=no-member
title=course_run.course.title,
title=course.title,
run_number=course_key.run)
try:
recipient_user = course.project_coordinator
user_role = course.course_user_roles.get(user=user)
if user_role.role == PublisherUserRole.ProjectCoordinator:
recipient_user = course.course_team_admin
page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id})
send_course_workflow_email(course_run.course, user, subject, txt_template, html_template, page_path,
run_number=course_key.run)
context = {
'course_name': course.title,
'run_number': course_key.run,
'sender_team': 'course team' if user_role.role == PublisherUserRole.CourseTeam else 'project coordinators',
'page_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path
)
}
send_course_workflow_email(course, user, subject, txt_template, html_template, context, recipient_user)
except Exception: # pylint: disable=broad-except
logger.exception('Failed to send email notifications send for review of course-run %s', course_run.id)
......@@ -221,29 +250,35 @@ def send_email_for_mark_as_reviewed_course_run(course_run, user):
""" Send email when course-run is marked as reviewed.
Arguments:
course-run (Object): CourseRun object
course_run (Object): CourseRun object
user (Object): User object
"""
txt_template = 'publisher/email/course_run/mark_as_reviewed.txt'
html_template = 'publisher/email/course_run/mark_as_reviewed.html'
course = course_run.course
course_key = CourseKey.from_string(course_run.lms_course_id)
subject = _('Review complete: {course_name} {run_number}').format( # pylint: disable=no-member
course_name=course_run.course.title,
course_name=course.title,
run_number=course_key.run
)
try:
page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id})
send_course_workflow_email(
course_run.course,
user,
subject,
txt_template,
html_template,
page_path,
run_number=course_key.run
recipient_user = course.project_coordinator
user_role = course.course_user_roles.get(user=user)
if user_role.role == PublisherUserRole.ProjectCoordinator:
recipient_user = course.course_team_admin
context = {
'course_name': course.title,
'run_number': course_key.run,
'sender_team': 'course team' if user_role.role == PublisherUserRole.CourseTeam else 'project coordinators',
'page_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path
)
}
send_course_workflow_email(course, user, subject, txt_template, html_template, context, recipient_user)
except Exception: # pylint: disable=broad-except
logger.exception('Failed to send email notifications for mark as reviewed of course-run %s', course_run.id)
......
......@@ -616,11 +616,11 @@ class CourseRunState(TimeStampedModel, ChangedByMixin):
self.draft()
elif state == CourseRunStateChoices.Review:
user_role = self.course_run.course.course_user_roles.get(user=user)
if user_role.role == PublisherUserRole.MarketingReviewer:
if user_role.role == PublisherUserRole.ProjectCoordinator:
self.owner_role = PublisherUserRole.CourseTeam
self.owner_role_modified = timezone.now()
elif user_role.role == PublisherUserRole.CourseTeam:
self.owner_role = PublisherUserRole.MarketingReviewer
self.owner_role = PublisherUserRole.ProjectCoordinator
self.owner_role_modified = timezone.now()
self.review()
......
......@@ -231,7 +231,7 @@ class CourseRunSendForReviewEmailTests(TestCase):
def test_email_sent_by_marketing_reviewer(self):
""" Verify that email works successfully for marketing user."""
factories.CourseUserRoleFactory(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=self.user
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=self.user
)
emails.send_email_for_send_for_review_course_run(self.course_run_state.course_run, self.user)
subject = 'Review requested: {title} {run_number}'.format(title=self.course, run_number=self.course_key.run)
......@@ -240,7 +240,7 @@ class CourseRunSendForReviewEmailTests(TestCase):
def test_email_sent_by_course_team(self):
""" Verify that email works successfully for course team user."""
factories.CourseUserRoleFactory(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=self.user
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=self.user
)
emails.send_email_for_send_for_review_course_run(self.course_run_state.course_run, self.user_2)
subject = 'Review requested: {title} {run_number}'.format(title=self.course, run_number=self.course_key.run)
......@@ -304,7 +304,7 @@ class CourseRunMarkAsReviewedEmailTests(TestCase):
def test_email_sent_by_marketing_reviewer(self):
""" Verify that email works successfully for marketing user."""
factories.CourseUserRoleFactory(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=self.user
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=self.user
)
emails.send_email_for_mark_as_reviewed_course_run(self.course_run_state.course_run, self.user)
self.assert_email_sent(self.user_2)
......@@ -312,7 +312,7 @@ class CourseRunMarkAsReviewedEmailTests(TestCase):
def test_email_sent_by_course_team(self):
""" Verify that email works successfully for course team user."""
factories.CourseUserRoleFactory(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=self.user
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=self.user
)
emails.send_email_for_mark_as_reviewed_course_run(self.course_run_state.course_run, self.user_2)
self.assert_email_sent(self.user)
......@@ -335,7 +335,7 @@ class CourseRunMarkAsReviewedEmailTests(TestCase):
def test_email_sent_to_publisher(self):
""" Verify that email works successfully."""
factories.CourseUserRoleFactory(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=self.user
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=self.user
)
emails.send_email_to_publisher(self.course_run_state.course_run, self.user)
self.assert_email_sent(self.user_3)
......
......@@ -888,7 +888,7 @@ class CourseRunDetailTests(TestCase):
new_user = UserFactory()
factories.CourseUserRoleFactory(
course=self.course, user=new_user, role=PublisherUserRole.MarketingReviewer
course=self.course, user=new_user, role=PublisherUserRole.ProjectCoordinator
)
response = self.client.get(self.page_url)
......@@ -907,12 +907,12 @@ class CourseRunDetailTests(TestCase):
def test_course_approval_widget_for_marketing_team(self):
"""
Verify that marketing User can't see the `Send for Review` button.
Verify that project coordinator can't see the `Send for Review` button.
"""
toggle_switch('publisher_approval_widget_feature', True)
factories.CourseUserRoleFactory(
course=self.course, user=self.user, role=PublisherUserRole.MarketingReviewer
course=self.course, user=self.user, role=PublisherUserRole.ProjectCoordinator
)
new_user = UserFactory()
......@@ -979,7 +979,7 @@ class CourseRunDetailTests(TestCase):
course=self.course, user=self.user, role=PublisherUserRole.CourseTeam
)
factories.CourseUserRoleFactory(
course=self.course, user=UserFactory(), role=PublisherUserRole.MarketingReviewer
course=self.course, user=UserFactory(), role=PublisherUserRole.ProjectCoordinator
)
response = self.client.get(self.page_url)
......@@ -995,7 +995,7 @@ class CourseRunDetailTests(TestCase):
Verify that user can see approval widget on course detail page with `Reviewed`.
"""
factories.CourseUserRoleFactory(
course=self.course, user=self.user, role=PublisherUserRole.MarketingReviewer
course=self.course, user=self.user, role=PublisherUserRole.ProjectCoordinator
)
factories.CourseUserRoleFactory(
......
......@@ -726,8 +726,10 @@ def get_course_role_widgets_data(user, course, state_object, change_state_url, p
""" Create role widgets list for course user roles. """
role_widgets = []
course_roles = course.course_user_roles
roles = [PublisherUserRole.CourseTeam, PublisherUserRole.ProjectCoordinator]
if parent_course:
course_roles = course_roles.filter(role__in=[PublisherUserRole.CourseTeam, PublisherUserRole.MarketingReviewer])
roles = [PublisherUserRole.CourseTeam, PublisherUserRole.MarketingReviewer]
course_roles = course_roles.filter(role__in=roles)
for course_role in course_roles.order_by('role'):
role_widget = {
......@@ -756,7 +758,7 @@ def get_course_role_widgets_data(user, course, state_object, change_state_url, p
if state_object.name == CourseStateChoices.Draft and not state_object.can_send_for_review():
role_widget['button_disabled'] = True
if course_role.role in [PublisherUserRole.CourseTeam, PublisherUserRole.MarketingReviewer]:
if course_role.role in roles:
if state_object.name == CourseStateChoices.Approved and course_role.role == state_object.approved_by_role:
history_record = state_object.history.filter(
name=CourseStateChoices.Approved
......
......@@ -409,6 +409,10 @@
@include margin-right(10px);
}
.ownership-label {
font-size: 13px;
}
}//approval-widget (END)
......
......@@ -43,7 +43,7 @@
<strong>{{ role_widget.heading }}</strong>
</span>
{% if role_widget.ownership %}
<span>{{ role_widget.ownership.days }} {% trans "day in ownership" %}</span>
<span class="ownership-label">{{ role_widget.ownership.days }} {% trans "day in ownership" %}</span>
{% endif %}
<div class="role-assignment-container">
<div id="userRoleContainer-{{ role_widget.course_role.role }}">
......
......@@ -8,7 +8,7 @@
{% endblocktrans %}
<p>
{% blocktrans with link_start='<a href="' link_middle='">' link_end='</a>' trimmed %}
The {{ sender_team }} for {{ course_name }} from {{ org_name }} has submitted the {{ link_start }}{{ page_url }}{{ link_middle }}{{ run_number }} course run{{ link_end }} for review. Visit the course run details page to approve or decline this course run.
The {{ sender_team }} for {{ course_name }} from {{ org_name }} has submitted the {{ link_start }}{{ page_url }}{{ link_middle }}{{ run_number }} course run{{ link_end }} for review. Visit the {{ link_start }}{{ page_url }}{{ link_middle }}course run details page{{ link_end }} to approve or decline this course run.
{% endblocktrans %}
</p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment