Commit 6d608269 by Michael Terry Committed by Michael Terry

Revert 977de4f2

Let's guard entitlement-creation support behind a waffle flag before
releasing it into the wild. So back it out now and we'll reintroduce
it after we have a flag.
parent 977de4f2
......@@ -17,8 +17,8 @@ from course_discovery.apps.ietf_language_tags.models import LanguageTag
from course_discovery.apps.publisher.choices import CourseRunStateChoices, PublisherUserRole
from course_discovery.apps.publisher.mixins import LanguageModelSelect2Multiple, get_user_organizations
from course_discovery.apps.publisher.models import (
Course, CourseEntitlement, CourseRun, CourseRunState, CourseState, CourseUserRole, OrganizationExtension,
OrganizationUserRole, PublisherUser, Seat, User
Course, CourseRun, CourseRunState, CourseState, CourseUserRole, OrganizationExtension, OrganizationUserRole,
PublisherUser, Seat, User
)
from course_discovery.apps.publisher.utils import VALID_CHARS_IN_COURSE_NUM_AND_ORG_KEY, is_internal_user
from course_discovery.apps.publisher.validators import validate_text_count
......@@ -442,31 +442,6 @@ class SeatForm(BaseForm):
seat.credit_price = 0.00
class CourseEntitlementForm(BaseForm):
MODE_CHOICES = [
('', _('Audit or credit track')),
(CourseEntitlement.VERIFIED, _('Verified')),
(CourseEntitlement.PROFESSIONAL, _('Professional education')),
]
mode = forms.ChoiceField(choices=MODE_CHOICES, required=False, label=_('Enrollment Track'))
price = forms.DecimalField(max_digits=6, decimal_places=2, required=False, initial=0.00)
class Meta:
fields = ('mode', 'price')
model = CourseEntitlement
def clean(self):
cleaned_data = super().clean()
mode = cleaned_data.get('mode')
price = cleaned_data.get('price')
if mode and (price is None or price <= 0):
raise ValidationError({'price': ''}) # mimics required field behavior (red border only, no error string)
return cleaned_data
class BaseUserAdminForm(forms.ModelForm):
"""This form will be use for type ahead search in django-admin."""
......
......@@ -128,25 +128,6 @@
{% endif %}
</div>
</div>
<div class="field-title">{% trans "CERTIFICATE TYPE AND PRICE" %}</span></div>
<div class="row">
<div class="col col-6 help-text">
{% trans "If the course offers a verified or professional education certificate, select the certificate type and enter the price for the certificate." %}
</div>
<div class="col col-6">
<div class="row">
<div class="col col-6">
<label class="field-label ">{{ entitlement_form.mode.label_tag }}</label>
{{ entitlement_form.mode }}
</div>
<div id="SeatPriceBlock" class="col col-6 {% if not entitlement_form.mode.value %}hidden{% endif %}">
<label class="field-label ">{{ entitlement_form.price.label_tag }} <span class="required">*</span></label>
{{ entitlement_form.price }}
</div>
</div>
</div>
</div>
</fieldset>
</div>
</div>
......
......@@ -12,10 +12,9 @@ from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory
from course_discovery.apps.publisher.choices import CourseRunStateChoices, PublisherUserRole
from course_discovery.apps.publisher.forms import (
CourseEntitlementForm, CourseForm, CourseRunForm, CourseRunStateAdminForm, CourseStateAdminForm,
PublisherUserCreationForm, SeatForm
CourseForm, CourseRunForm, CourseRunStateAdminForm, CourseStateAdminForm, PublisherUserCreationForm, SeatForm
)
from course_discovery.apps.publisher.models import CourseEntitlement, Seat
from course_discovery.apps.publisher.models import Seat
from course_discovery.apps.publisher.tests.factories import (
CourseFactory, CourseUserRoleFactory, OrganizationExtensionFactory, SeatFactory
)
......@@ -345,49 +344,6 @@ class PublisherCustomCourseFormTests(TestCase):
assert course.title == 'áçã'
@ddt.ddt
class PublisherCourseEntitlementFormTests(TestCase):
@ddt.data(
(CourseEntitlement.VERIFIED, None),
(CourseEntitlement.PROFESSIONAL, None),
(CourseEntitlement.PROFESSIONAL, 0),
(CourseEntitlement.PROFESSIONAL, -1),
)
@ddt.unpack
def test_invalid_price(self, mode, price):
"""
Verify that clean raises an error if the price is invalid for the course type
"""
entitlement_form = CourseEntitlementForm()
entitlement_form.cleaned_data = {'mode': mode}
if price is not None:
entitlement_form.cleaned_data['price'] = price
with self.assertRaises(ValidationError):
entitlement_form.clean()
@ddt.data(
(None, None),
(None, 0),
(None, 50),
(CourseEntitlement.VERIFIED, 50),
(CourseEntitlement.PROFESSIONAL, 50),
)
@ddt.unpack
def test_valid_price(self, mode, price):
"""
Verify that clean works fine for valid price/type combos
"""
entitlement_form = CourseEntitlementForm()
entitlement_form.cleaned_data = {}
if mode is not None:
entitlement_form.cleaned_data['mode'] = mode
if price is not None:
entitlement_form.cleaned_data['price'] = price
self.assertEqual(entitlement_form.clean(), entitlement_form.cleaned_data)
@pytest.mark.django_db
class TestSeatForm:
@override_switch('publisher_create_audit_seats_for_verified_course_runs', active=True)
......
......@@ -37,7 +37,7 @@ from course_discovery.apps.publisher.constants import (
ADMIN_GROUP_NAME, INTERNAL_USER_GROUP_NAME, PROJECT_COORDINATOR_GROUP_NAME, REVIEWER_GROUP_NAME
)
from course_discovery.apps.publisher.models import (
Course, CourseEntitlement, CourseRun, CourseRunState, CourseState, OrganizationExtension, Seat
Course, CourseRun, CourseRunState, CourseState, OrganizationExtension, Seat
)
from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher.tests.utils import create_non_staff_user_and_login
......@@ -282,57 +282,6 @@ class CreateCourseViewTests(SiteMixin, TestCase):
target_status_code=200
)
def _make_course(self, data=None):
initial_data = {'title': 'Test Course', 'number': 'test1', 'image': ''}
if data:
initial_data.update(**data)
course_dict = self._post_data(initial_data, self.course)
response = self.client.post(reverse('publisher:publisher_courses_new'), course_dict)
self.assertRedirects(
response,
expected_url=reverse('publisher:publisher_course_detail', kwargs={'pk': Course.objects.first().id}),
status_code=302,
target_status_code=200
)
return Course.objects.get(number=course_dict['number'])
@ddt.data(CourseEntitlement.VERIFIED, CourseEntitlement.PROFESSIONAL)
def test_create_entitlement(self, mode):
"""
Verify that we create an entitlement for appropriate types (happy path)
"""
data = {'mode': mode, 'price': 50}
course = self._make_course(data)
self.assertEqual(1, CourseEntitlement.objects.all().count())
self.assertEqual(1, course.entitlements.all().count())
self.assertEqual(Course.ENTITLEMENT_VERSION, course.version)
entitlement = course.entitlements.first()
self.assertEqual(course, entitlement.course)
self.assertEqual(mode, entitlement.mode)
self.assertEqual(50, entitlement.price)
def test_seat_version(self):
"""
Verify that when we create a normal seat, we set version
"""
course = self._make_course()
self.assertEqual(0, CourseEntitlement.objects.all().count())
self.assertEqual(Course.SEAT_VERSION, course.version)
@ddt.data(0, -1, None)
def test_invalid_entitlement_price(self, price):
"""
Verify that when we check price validity when making an entitlement
"""
data = {'title': 'Test2', 'number': 'testX234', 'mode': CourseEntitlement.VERIFIED}
if price is not None:
data['price'] = price
course_dict = self._post_data(data, self.course)
response = self.client.post(reverse('publisher:publisher_courses_new'), course_dict)
self.assertEqual(response.status_code, 400)
class CreateCourseRunViewTests(SiteMixin, TestCase):
""" Tests for the publisher `CreateCourseRunView`. """
......
......@@ -29,8 +29,8 @@ from course_discovery.apps.publisher import emails, mixins, serializers
from course_discovery.apps.publisher.choices import CourseRunStateChoices, CourseStateChoices, PublisherUserRole
from course_discovery.apps.publisher.dataloader.create_courses import process_course
from course_discovery.apps.publisher.emails import send_email_for_published_course_run_editing
from course_discovery.apps.publisher.forms import (AdminImportCourseForm, CourseEntitlementForm, CourseForm,
CourseRunForm, CourseSearchForm, SeatForm)
from course_discovery.apps.publisher.forms import (AdminImportCourseForm, CourseForm, CourseRunForm, CourseSearchForm,
SeatForm)
from course_discovery.apps.publisher.models import (PAID_SEATS, Course, CourseRun, CourseRunState, CourseState,
CourseUserRole, OrganizationExtension, Seat, UserAttributes)
from course_discovery.apps.publisher.utils import (get_internal_users, has_role_for_course, is_internal_user,
......@@ -237,7 +237,6 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
""" Create Course View."""
model = Course
course_form = CourseForm
entitlement_form = CourseEntitlementForm
template_name = 'publisher/add_course_form.html'
success_url = 'publisher:publisher_course_detail'
......@@ -250,7 +249,6 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
def get_context_data(self):
return {
'course_form': self.course_form(user=self.request.user),
'entitlement_form': self.entitlement_form(),
'publisher_hide_features_for_pilot': waffle.switch_is_active('publisher_hide_features_for_pilot'),
'publisher_add_instructor_feature': waffle.switch_is_active('publisher_add_instructor_feature'),
}
......@@ -270,26 +268,15 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
course_form = self.course_form(
request.POST, request.FILES, user=user, organization=organization
)
entitlement_form = self.entitlement_form(request.POST)
if course_form.is_valid() and entitlement_form.is_valid():
if course_form.is_valid():
try:
with transaction.atomic():
course = course_form.save(commit=False)
if entitlement_form['mode'].value():
course.version = Course.ENTITLEMENT_VERSION
else:
course.version = Course.SEAT_VERSION
course.changed_by = user
course.save()
# commit false does not save m2m object. Keyword field is m2m.
course_form.save_m2m()
# Now create entitlement if we need to
if course.version == Course.ENTITLEMENT_VERSION:
entitlement = entitlement_form.save(commit=False)
entitlement.course = course
entitlement.save()
organization_extension = get_object_or_404(
OrganizationExtension, organization=course_form.data['organization']
)
......@@ -340,7 +327,6 @@ class CreateCourseView(mixins.LoginRequiredMixin, mixins.PublisherUserRequiredMi
ctx.update(
{
'course_form': course_form,
'entitlement_form': entitlement_form,
}
)
return render(request, self.template_name, ctx, status=400)
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-01-29 14:45+0000\n"
"POT-Creation-Date: 2018-01-30 16:13+0000\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"
......@@ -831,10 +831,6 @@ msgid "Only audit seat can be without price."
msgstr ""
#: apps/publisher/forms.py
msgid "Audit or credit track"
msgstr ""
#: apps/publisher/forms.py
msgid "This field is required."
msgstr ""
......@@ -1392,20 +1388,6 @@ msgid "BIO1.1x; BIO1.2x etc."
msgstr ""
#: apps/publisher/templates/publisher/add_course_form.html
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid "CERTIFICATE TYPE AND PRICE"
msgstr ""
#: apps/publisher/templates/publisher/add_course_form.html
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid ""
"If the course offers a verified or professional education certificate, "
"select the certificate type and enter the price for the certificate."
msgstr ""
#: apps/publisher/templates/publisher/add_course_form.html
msgid "I want to add a run to this course at this time"
msgstr ""
......@@ -1492,6 +1474,18 @@ msgid ""
msgstr ""
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid "CERTIFICATE TYPE AND PRICE"
msgstr ""
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid ""
"If the course offers a verified or professional education certificate, "
"select the certificate type and enter the price for the certificate."
msgstr ""
#: apps/publisher/templates/publisher/add_courserun_form.html
msgid "Create New Course Run"
msgstr ""
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-01-29 14:45+0000\n"
"POT-Creation-Date: 2018-01-30 16:13+0000\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"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-01-29 14:45+0000\n"
"POT-Creation-Date: 2018-01-30 16:13+0000\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"
......@@ -1000,10 +1000,6 @@ msgstr ""
"¢σηѕє¢тєтυ#"
#: apps/publisher/forms.py
msgid "Audit or credit track"
msgstr "Àüdït ör çrédït träçk Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
#: apps/publisher/forms.py
msgid "This field is required."
msgstr "Thïs fïéld ïs réqüïréd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
......@@ -1615,28 +1611,6 @@ msgid "BIO1.1x; BIO1.2x etc."
msgstr "BÌÖ1.1x; BÌÖ1.2x étç. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
#: apps/publisher/templates/publisher/add_course_form.html
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid "CERTIFICATE TYPE AND PRICE"
msgstr "ÇÉRTÌFÌÇÀTÉ TÝPÉ ÀND PRÌÇÉ Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
#: apps/publisher/templates/publisher/add_course_form.html
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid ""
"If the course offers a verified or professional education certificate, "
"select the certificate type and enter the price for the certificate."
msgstr ""
"Ìf thé çöürsé öfférs ä vérïfïéd ör pröféssïönäl édüçätïön çértïfïçäté, "
"séléçt thé çértïfïçäté týpé änd éntér thé prïçé för thé çértïfïçäté. Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ єѕт łα#"
#: apps/publisher/templates/publisher/add_course_form.html
msgid "I want to add a run to this course at this time"
msgstr ""
"Ì wänt tö ädd ä rün tö thïs çöürsé ät thïs tïmé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,"
......@@ -1761,6 +1735,26 @@ msgstr ""
"ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢α#"
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid "CERTIFICATE TYPE AND PRICE"
msgstr "ÇÉRTÌFÌÇÀTÉ TÝPÉ ÀND PRÌÇÉ Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
#: apps/publisher/templates/publisher/add_courserun_form.html
#: apps/publisher/templates/publisher/course_run/edit_run_form.html
msgid ""
"If the course offers a verified or professional education certificate, "
"select the certificate type and enter the price for the certificate."
msgstr ""
"Ìf thé çöürsé öfférs ä vérïfïéd ör pröféssïönäl édüçätïön çértïfïçäté, "
"séléçt thé çértïfïçäté týpé änd éntér thé prïçé för thé çértïfïçäté. Ⱡ'σяєм "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ єѕт łα#"
#: apps/publisher/templates/publisher/add_courserun_form.html
msgid "Create New Course Run"
msgstr "Çréäté Néw Çöürsé Rün Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-01-29 14:45+0000\n"
"POT-Creation-Date: 2018-01-30 16:13+0000\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"
......
$(document).on('change', '#id_type, #id_mode', function (e) {
$(document).on('change', '#id_type', function (e) {
var $seatBlock = $("#SeatPriceBlock"),
$creditPrice = $("#creditPrice"),
selectedSeatType = this.value;
......
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