Commit fca9ed9b by Waheed Ahmed

Add default role as course role upon new run creation if course role not exists.

ECOM-7853
parent bf44109b
......@@ -6,8 +6,10 @@ from django.db.models.functions import Lower
from django.http import HttpResponseForbidden, HttpResponseRedirect
from django.utils.decorators import method_decorator
from course_discovery.apps.core.models import User
from course_discovery.apps.course_metadata.models import Organization
from course_discovery.apps.publisher.models import Course, Seat
from course_discovery.apps.publisher.choices import PublisherUserRole
from course_discovery.apps.publisher.models import Course, CourseUserRole, Seat
from course_discovery.apps.publisher.utils import is_internal_user, is_publisher_admin, is_publisher_user
......@@ -155,3 +157,27 @@ def get_user_organizations(user):
).order_by(Lower('key'))
return organizations
def add_course_role(course, organization_extension, role):
default_role = organization_extension.organization.organization_user_roles.get(role=role)
CourseUserRole.add_course_roles(course=course, role=default_role.role, user=default_role.user)
def check_and_create_course_user_roles(course):
organization_extension = course.organization_extension
if not course.course_team_admin:
course_team_users = User.objects.filter(groups__name=organization_extension.group.name)
CourseUserRole.add_course_roles(
course=course, role=PublisherUserRole.CourseTeam, user=course_team_users.first()
)
if not course.project_coordinator:
add_course_role(course, organization_extension, PublisherUserRole.ProjectCoordinator)
if not course.publisher:
add_course_role(course, organization_extension, PublisherUserRole.Publisher)
if not course.marketing_reviewer:
add_course_role(course, organization_extension, PublisherUserRole.MarketingReviewer)
......@@ -277,6 +277,13 @@ class CreateCourseRunViewTests(TestCase):
self.course = self.course_run.course
factories.CourseStateFactory(course=self.course)
factories.CourseUserRoleFactory.create(course=self.course, role=PublisherUserRole.CourseTeam, user=self.user)
factories.CourseUserRoleFactory.create(course=self.course, role=PublisherUserRole.Publisher, user=UserFactory())
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=UserFactory()
)
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=UserFactory()
)
self.organization_extension = factories.OrganizationExtensionFactory()
self.course.organizations.add(self.organization_extension.organization)
self.user.groups.add(self.organization_extension.group)
......@@ -367,9 +374,6 @@ class CreateCourseRunViewTests(TestCase):
""" Verify that we can create a new course run with seat. """
new_user = factories.UserFactory()
new_user.groups.add(self.organization_extension.group)
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=factories.UserFactory()
)
self.assertEqual(self.course.course_team_admin, self.user)
......@@ -417,9 +421,6 @@ class CreateCourseRunViewTests(TestCase):
""" Verify that user cannot create a new course run without seat price. """
new_user = factories.UserFactory()
new_user.groups.add(self.organization_extension.group)
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=factories.UserFactory()
)
self.assertEqual(self.course.course_team_admin, self.user)
......@@ -542,6 +543,22 @@ class CreateCourseRunViewTests(TestCase):
self.assertEqual(new_seat.price, price)
self.assertEqual(new_seat.credit_price, credit_price)
def test_canot_create_course_run_without_roles(self):
"""
Verify that user can create a new course run with credit seat.
"""
course = factories.CourseFactory()
organization_extension = factories.OrganizationExtensionFactory()
course.organizations.add(organization_extension.organization)
self.user.groups.add(organization_extension.group)
response = self.client.post(
reverse('publisher:publisher_course_runs_new', kwargs={'parent_course_id': course.id}),
{}
)
self.assertContains(response, 'Your organization does not have default roles', status_code=400)
@ddt.ddt
class CourseRunDetailTests(TestCase):
......@@ -1212,6 +1229,32 @@ class CourseRunDetailTests(TestCase):
# Verify that user cannot see edit button if he has no role for course.
self.assert_can_edit_permission(can_edit=False)
def test_create_course_user_roles_if_not_exist(self):
"""
Verify that course user roles created if default roles exist on viewing detail page.
"""
self.user.groups.add(self.organization_extension.group)
default_roles = [
PublisherUserRole.MarketingReviewer, PublisherUserRole.ProjectCoordinator, PublisherUserRole.Publisher
]
self.assertEqual(self.course.course_user_roles.filter(role__in=default_roles).count(), 0)
factories.OrganizationUserRoleFactory(
organization=self.organization_extension.organization, role=PublisherUserRole.MarketingReviewer
)
factories.OrganizationUserRoleFactory(
organization=self.organization_extension.organization, role=PublisherUserRole.ProjectCoordinator
)
factories.OrganizationUserRoleFactory(
organization=self.organization_extension.organization, role=PublisherUserRole.Publisher
)
self.client.get(self.page_url)
expected_count = self.course.course_user_roles.filter(course=self.course, role__in=default_roles).count()
self.assertEqual(len(default_roles), expected_count)
# pylint: disable=attribute-defined-outside-init
@ddt.ddt
......@@ -2015,6 +2058,32 @@ class CourseDetailViewTests(TestCase):
self.client.post(reverse('publisher:publisher_courses_edit', args=[self.course.id]), post_data)
def test_create_course_user_roles_if_not_exist(self):
"""
Verify that course user roles created if default roles exist on viewing detail page.
"""
self._assign_user_permission()
default_roles = [
PublisherUserRole.MarketingReviewer, PublisherUserRole.ProjectCoordinator, PublisherUserRole.Publisher
]
self.assertEqual(self.course.course_user_roles.filter(role__in=default_roles).count(), 0)
factories.OrganizationUserRoleFactory(
organization=self.organization_extension.organization, role=PublisherUserRole.MarketingReviewer
)
factories.OrganizationUserRoleFactory(
organization=self.organization_extension.organization, role=PublisherUserRole.ProjectCoordinator
)
factories.OrganizationUserRoleFactory(
organization=self.organization_extension.organization, role=PublisherUserRole.Publisher
)
self.client.get(self.detail_page_url)
expected_count = self.course.course_user_roles.filter(course=self.course, role__in=default_roles).count()
self.assertEqual(len(default_roles), expected_count)
@ddt.ddt
class CourseEditViewTests(TestCase):
......@@ -2924,6 +2993,14 @@ class CreateRunFromDashboardViewTests(TestCase):
self.course = factories.CourseFactory()
factories.CourseStateFactory(course=self.course)
factories.CourseUserRoleFactory.create(course=self.course, role=PublisherUserRole.CourseTeam, user=self.user)
factories.CourseUserRoleFactory.create(course=self.course, role=PublisherUserRole.Publisher, user=UserFactory())
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=UserFactory()
)
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.MarketingReviewer, user=UserFactory()
)
self.organization_extension = factories.OrganizationExtensionFactory()
self.course.organizations.add(self.organization_extension.organization)
self.user.groups.add(self.organization_extension.group)
......@@ -2981,9 +3058,6 @@ class CreateRunFromDashboardViewTests(TestCase):
self.assertEqual(self.course.course_runs.count(), 0)
new_user = factories.UserFactory()
new_user.groups.add(self.organization_extension.group)
factories.CourseUserRoleFactory.create(
course=self.course, role=PublisherUserRole.ProjectCoordinator, user=factories.UserFactory()
)
self.assertEqual(self.course.course_team_admin, self.user)
......
......@@ -50,6 +50,13 @@ STATE_BUTTONS = {
CourseStateChoices.Review: {'text': _('Mark as Reviewed'), 'value': CourseStateChoices.Approved}
}
DEFAULT_ROLES = [
PublisherUserRole.MarketingReviewer, PublisherUserRole.ProjectCoordinator, PublisherUserRole.Publisher
]
COURSE_ROLES = [PublisherUserRole.CourseTeam]
COURSE_ROLES.extend(DEFAULT_ROLES)
class Dashboard(mixins.LoginRequiredMixin, ListView):
""" Create Course View."""
......@@ -147,6 +154,12 @@ class CourseRunDetailView(mixins.LoginRequiredMixin, mixins.PublisherPermissionM
user = self.request.user
course_run = CourseRunWrapper(self.get_object())
course = course_run.course
organization = course.organization_extension.organization
if organization.organization_user_roles.filter(role__in=DEFAULT_ROLES).count() == len(DEFAULT_ROLES):
mixins.check_and_create_course_user_roles(course)
context['object'] = course_run
context['comment_object'] = course_run
......@@ -418,6 +431,11 @@ class CourseDetailView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMixi
user = self.request.user
course = self.object
organization = course.organization_extension.organization
if organization.organization_user_roles.filter(role__in=DEFAULT_ROLES).count() == len(DEFAULT_ROLES):
mixins.check_and_create_course_user_roles(course)
context['can_edit'] = mixins.check_course_organization_permission(
user, course, OrganizationExtension.EDIT_COURSE
) and has_role_for_course(course, user)
......@@ -559,10 +577,11 @@ class CreateCourseRunView(mixins.LoginRequiredMixin, CreateView):
self.request.POST['start'] = parse_datetime_field(self.request.POST.get('start'))
self.request.POST['end'] = parse_datetime_field(self.request.POST.get('end'))
run_form = self.run_form(request.POST)
seat_form = self.seat_form(request.POST)
if parent_course.course_user_roles.filter(role__in=COURSE_ROLES).count() == len(COURSE_ROLES):
if run_form.is_valid() and seat_form.is_valid():
try:
with transaction.atomic():
......@@ -589,6 +608,15 @@ class CreateCourseRunView(mixins.LoginRequiredMixin, CreateView):
else:
messages.error(request, _('Please fill all required fields.'))
else:
messages.error(
request,
_(
"Your organization does not have default roles to review/approve this course-run. "
"Please contact your partner manager to create default roles."
)
)
context = self.get_context_data()
context.update(
{
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-05 12:49+0500\n"
"POT-Creation-Date: 2017-06-05 14:41+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: apps/api/filters.py
#, python-brace-format
......@@ -967,6 +967,12 @@ msgid "There was an error saving course run, {error}"
msgstr ""
#: apps/publisher/views.py
msgid ""
"Your organization does not have default roles to review/approve this course-"
"run. Please contact your partner manager to create default roles."
msgstr ""
#: apps/publisher/views.py
msgid "Course run updated successfully."
msgstr ""
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-05 12:49+0500\n"
"POT-Creation-Date: 2017-06-05 14:41+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: static/js/catalogs-change-form.js
msgid "Preview"
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-05 12:49+0500\n"
"POT-Creation-Date: 2017-06-05 14:41+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps/api/filters.py
......@@ -1134,6 +1134,20 @@ msgstr ""
"¢σηѕє¢тєтυя #"
#: apps/publisher/views.py
msgid ""
"Your organization does not have default roles to review/approve this course-"
"run. Please contact your partner manager to create default roles."
msgstr ""
"Ýöür örgänïzätïön döés nöt hävé défäült rölés tö révïéw/äpprövé thïs çöürsé-"
"rün. Pléäsé çöntäçt ýöür pärtnér mänägér tö çréäté défäült rölés. Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ єѕт #"
#: apps/publisher/views.py
msgid "Course run updated successfully."
msgstr ""
"Çöürsé rün üpdätéd süççéssfüllý. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
......
......@@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-05 12:49+0500\n"
"POT-Creation-Date: 2017-06-05 14:41+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/js/catalogs-change-form.js
......
......@@ -5,7 +5,7 @@
<div class="clearfix"></div>
<div class="margin-top20">
<div>
<h5 class="hd-5 emphasized course-runs-heading">{% trans "COURSE RUNS" %}</h5>
<a href="{% url 'publisher:publisher_course_runs_new' parent_course_id=object.id %}" class="btn btn-brand btn-small btn-courserun-add">
{% trans "ADD RUN" %}
......
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