Commit ae66ce1b by Waheed Ahmed

Added credit seat type and credit price.

ECOM-7835
parent a6121728
......@@ -354,15 +354,12 @@ class SeatForm(BaseCourseForm):
if seat.type in [Seat.HONOR, Seat.AUDIT]:
seat.price = 0.00
seat.upgrade_deadline = None
seat.credit_provider = ''
seat.credit_hours = None
self.reset_credit_to_default(seat)
if seat.type == Seat.VERIFIED:
seat.credit_provider = ''
seat.credit_hours = None
self.reset_credit_to_default(seat)
if seat.type in [Seat.PROFESSIONAL, Seat.NO_ID_PROFESSIONAL]:
seat.upgrade_deadline = None
seat.credit_provider = ''
seat.credit_hours = None
self.reset_credit_to_default(seat)
if course_run:
seat.course_run = course_run
......@@ -377,13 +374,22 @@ class SeatForm(BaseCourseForm):
def clean(self):
price = self.cleaned_data.get('price')
credit_price = self.cleaned_data.get('credit_price')
seat_type = self.cleaned_data.get('type')
if seat_type in [Seat.PROFESSIONAL, Seat.VERIFIED] and not price:
if seat_type in [Seat.PROFESSIONAL, Seat.VERIFIED, Seat.CREDIT] and not price:
self.add_error('price', _('Only audit seat can be without price.'))
if seat_type == Seat.CREDIT and not credit_price:
self.add_error('credit_price', _('Only audit seat can be without price.'))
return self.cleaned_data
def reset_credit_to_default(self, seat):
seat.credit_provider = ''
seat.credit_hours = None
seat.credit_price = 0.00
class CustomSeatForm(SeatForm):
""" Course Seat Form. """
......@@ -403,13 +409,15 @@ class CustomSeatForm(SeatForm):
(Seat.AUDIT, _('Audit Only')),
(Seat.VERIFIED, _('Verified Certificate')),
(Seat.PROFESSIONAL, _('Professional Education')),
(Seat.CREDIT, _('Credit')),
]
type = forms.ChoiceField(choices=TYPE_CHOICES, required=False, label=_('Seat Type'))
price = forms.DecimalField(max_digits=6, decimal_places=2, required=False, initial=0.00)
credit_price = forms.DecimalField(max_digits=6, decimal_places=2, required=False, initial=0.00)
class Meta(SeatForm.Meta):
fields = ('price', 'type')
fields = ('price', 'type', 'credit_price')
class BaseUserAdminForm(forms.ModelForm):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-05-29 10:02
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('publisher', '0051_auto_20170525_1049'),
]
operations = [
migrations.AddField(
model_name='historicalseat',
name='credit_price',
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10),
),
migrations.AddField(
model_name='seat',
name='credit_price',
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10),
),
]
......@@ -364,6 +364,7 @@ class Seat(TimeStampedModel, ChangedByMixin):
upgrade_deadline = models.DateTimeField(null=True, blank=True)
credit_provider = models.CharField(max_length=255, null=True, blank=True)
credit_hours = models.IntegerField(null=True, blank=True)
credit_price = models.DecimalField(**PRICE_FIELD_CONFIG)
history = HistoricalRecords()
......@@ -375,7 +376,11 @@ class Seat(TimeStampedModel, ChangedByMixin):
"""
Check that seat is valid or not.
"""
return self.type == self.AUDIT or self.type in [self.VERIFIED, self.PROFESSIONAL] and self.price > 0
return (
self.type == self.AUDIT or
(self.type in [self.VERIFIED, self.PROFESSIONAL] and self.price > 0) or
(self.type == self.CREDIT and self.credit_price > 0)
)
class UserAttributes(TimeStampedModel):
......
......@@ -66,6 +66,7 @@ class SeatFactory(factory.DjangoModelFactory):
currency = factory.Iterator(Currency.objects.all())
upgrade_deadline = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC))
course_run = factory.SubFactory(CourseRunFactory)
credit_price = FuzzyDecimal(0.0, 650.0)
class Meta:
model = Seat
......
......@@ -484,6 +484,64 @@ class CreateCourseRunViewTests(TestCase):
)
self.assertContains(response, expected_seat_price)
def test_credit_type_without_price(self):
""" Verify that without credit price course-run cannot be created with credit seat type. """
post_data = self.course_run_dict
seat = factories.SeatFactory(course_run=self.course_run, type=Seat.AUDIT, price=0, credit_price=0)
post_data.update(**model_to_dict(seat))
post_data.update(
{
'type': Seat.CREDIT,
'price': 450
}
)
self._pop_valuse_from_dict(post_data, ['id', 'course', 'course_run', 'lms_course_id'])
assign_perm(
OrganizationExtension.VIEW_COURSE_RUN, self.organization_extension.group, self.organization_extension
)
response = self.client.post(
reverse('publisher:publisher_course_runs_new', kwargs={'parent_course_id': self.course.id}),
post_data
)
self.assertEqual(response.status_code, 400)
def test_create_course_run_with_credit_seat(self):
""" Verify that user can create a new course run with credit seat. """
price = 450
credit_price = 350
post_data = self.course_run_dict
seat = factories.SeatFactory(course_run=self.course_run, type=Seat.AUDIT, price=0, credit_price=0)
post_data.update(**model_to_dict(seat))
post_data.update(
{
'type': Seat.CREDIT,
'price': price,
'credit_price': credit_price
}
)
self._pop_valuse_from_dict(post_data, ['id', 'course', 'course_run', 'lms_course_id'])
assign_perm(
OrganizationExtension.VIEW_COURSE_RUN, self.organization_extension.group, self.organization_extension
)
response = self.client.post(
reverse('publisher:publisher_course_runs_new', kwargs={'parent_course_id': self.course.id}),
post_data
)
new_seat = Seat.objects.get(type=post_data['type'])
self.assertRedirects(
response,
expected_url=reverse('publisher:publisher_course_run_detail', kwargs={'pk': new_seat.course_run.id}),
status_code=302,
target_status_code=200
)
# Verify that new seat and new course run are unique
self.assertEqual(new_seat.type, Seat.CREDIT)
self.assertEqual(new_seat.price, price)
self.assertEqual(new_seat.credit_price, credit_price)
@ddt.ddt
class CourseRunDetailTests(TestCase):
......@@ -647,7 +705,7 @@ class CourseRunDetailTests(TestCase):
values = [
self.wrapped_course_run.title, self.wrapped_course_run.lms_course_id,
self.wrapped_course_run.verified_seat_price,
self.wrapped_course_run.seat_price,
self.wrapped_course_run.min_effort,
self.wrapped_course_run.pacing_type, self.wrapped_course_run.persons,
self.wrapped_course_run.max_effort, self.wrapped_course_run.language.name,
......
......@@ -82,13 +82,21 @@ class CourseRunWrapperTests(TestCase):
wrapped_course_run = CourseRunWrapper(course_run)
self.assertEqual(wrapped_course_run.organization_key, organization.key)
def test_verified_seat_price(self):
""" Verify that the wrapper return the verified seat price. """
self.assertEqual(self.wrapped_course_run.verified_seat_price, None)
def test_seat_price(self):
""" Verify that the wrapper return the seat price. """
self.assertEqual(self.wrapped_course_run.seat_price, None)
seat = factories.SeatFactory(type=Seat.VERIFIED, course_run=self.course_run)
wrapped_course_run = CourseRunWrapper(self.course_run)
self.assertEqual(wrapped_course_run.verified_seat_price, seat.price)
self.assertEqual(wrapped_course_run.seat_price, seat.price)
def test_credit_seat_price(self):
""" Verify that the wrapper return the credit seat price. """
self.assertEqual(self.wrapped_course_run.credit_seat_price, None)
seat = factories.SeatFactory(type=Seat.CREDIT, course_run=self.course_run)
wrapped_course_run = CourseRunWrapper(self.course_run)
self.assertEqual(wrapped_course_run.credit_seat_price, seat.credit_price)
def test_credit_seat(self):
""" Verify that the wrapper return the credit seat. """
......
......@@ -52,13 +52,20 @@ class CourseRunWrapper(BaseWrapper):
return ', '.join([person.full_name for person in self.wrapped_obj.staff.all()])
@property
def verified_seat_price(self):
seat = self.wrapped_obj.seats.filter(type=Seat.VERIFIED).first()
def seat_price(self):
seat = self.wrapped_obj.seats.filter(type__in=[Seat.VERIFIED, Seat.PROFESSIONAL, Seat.CREDIT]).first()
if not seat:
return None
return seat.price
@property
def credit_seat_price(self):
seat = self.wrapped_obj.seats.filter(type=Seat.CREDIT).first()
if not seat:
return None
return seat.credit_price
@property
def verified_seat_expiry(self):
seat = self.wrapped_obj.seats.filter(type=Seat.VERIFIED).first()
if not seat:
......@@ -114,7 +121,7 @@ class CourseRunWrapper(BaseWrapper):
seats_types = [seat.type for seat in self.wrapped_obj.seats.all()]
if [Seat.AUDIT] == seats_types:
return Seat.AUDIT
if Seat.CREDIT in seats_types and Seat.VERIFIED in seats_types:
if Seat.CREDIT in seats_types:
return Seat.CREDIT
if Seat.VERIFIED in seats_types:
return Seat.VERIFIED
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-05-29 14:22+0500\n"
"POT-Creation-Date: 2017-05-29 16:50+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"
......@@ -373,7 +373,8 @@ msgstr ""
msgid "Professional"
msgstr ""
#: apps/course_metadata/models.py apps/publisher/models.py
#: apps/course_metadata/models.py apps/publisher/forms.py
#: apps/publisher/models.py
msgid "Credit"
msgstr ""
......@@ -2200,6 +2201,10 @@ msgid "Certificate Price"
msgstr ""
#: templates/publisher/course_run_detail/_all.html
msgid "Credit Price"
msgstr ""
#: templates/publisher/course_run_detail/_all.html
msgid "Course Staff"
msgstr ""
......@@ -2446,6 +2451,10 @@ msgid "Course $ (minimum)"
msgstr ""
#: templates/publisher/course_run_detail/_salesforce.html
msgid "Credit $ (minimum)"
msgstr ""
#: templates/publisher/course_run_detail/_salesforce.html
msgid "Self Paced?"
msgstr ""
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-05-29 14:22+0500\n"
"POT-Creation-Date: 2017-05-29 16:50+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"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-05-29 14:22+0500\n"
"POT-Creation-Date: 2017-05-29 16:50+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"
......@@ -458,7 +458,8 @@ msgstr "Vérïfïéd Ⱡ'σяєм ιρѕυм ∂#"
msgid "Professional"
msgstr "Pröféssïönäl Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#: apps/course_metadata/models.py apps/publisher/models.py
#: apps/course_metadata/models.py apps/publisher/forms.py
#: apps/publisher/models.py
msgid "Credit"
msgstr "Çrédït Ⱡ'σяєм ιρѕυ#"
......@@ -2641,6 +2642,10 @@ msgid "Certificate Price"
msgstr "Çértïfïçäté Prïçé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмє#"
#: templates/publisher/course_run_detail/_all.html
msgid "Credit Price"
msgstr "Çrédït Prïçé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#: templates/publisher/course_run_detail/_all.html
msgid "Course Staff"
msgstr "Çöürsé Stäff Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
......@@ -2900,6 +2905,10 @@ msgid "Course $ (minimum)"
msgstr "Çöürsé $ (mïnïmüm) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
#: templates/publisher/course_run_detail/_salesforce.html
msgid "Credit $ (minimum)"
msgstr "Çrédït $ (mïnïmüm) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
#: templates/publisher/course_run_detail/_salesforce.html
msgid "Self Paced?"
msgstr "Sélf Päçéd? Ⱡ'σяєм ιρѕυм ∂σłσя #"
......
......@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-05-29 14:22+0500\n"
"POT-Creation-Date: 2017-05-29 16:50+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"
......
$(document).on('change', '#id_type', function (e) {
var $seatBlock = $("#SeatPriceBlock"),
$creditPrice = $("#creditPrice"),
selectedSeatType = this.value;
if (selectedSeatType === 'audit' || selectedSeatType === '') {
$seatBlock.hide();
} else{
$seatBlock.show();
if (selectedSeatType === 'credit') {
$creditPrice.show();
} else {
$creditPrice.hide();
}
}
});
......@@ -121,9 +121,13 @@
<label class="field-label ">{{ seat_form.type.label_tag }}
</label> {{ seat_form.type }}
</div>
<div id="SeatPriceBlock" class="col col-6 {% if not seat_form.price.value %}hidden{% endif %}">
<div id="SeatPriceBlock" class="col col-6 {% if seat_form.type.value == 'audit' or not seat_form.price.value %}hidden{% endif %}">
<label class="field-label ">{{ seat_form.price.label_tag }}</label>
{{ seat_form.price }}
<div class="{% if seat_form.type.value != 'credit' or not seat_form.credit_price.value %}hidden{% endif %}" id="creditPrice">
<label class="field-label">{{ seat_form.credit_price.label }}</label>
{{ seat_form.credit_price }}
</div>
</div>
</div>
{% if seat_form.price.errors %}
......
......@@ -167,9 +167,13 @@
<label class="field-label ">{{ seat_form.type.label_tag }}
</label> {{ seat_form.type }}
</div>
<div id="SeatPriceBlock" class="col col-6 {% if not seat_form.price.value %}hidden{% endif %}">
<div id="SeatPriceBlock" class="col col-6 {% if seat_form.type.value == 'audit' or not seat_form.price.value %}hidden{% endif %}">
<label class="field-label ">{{ seat_form.price.label_tag }}</label>
{{ seat_form.price }}
<div class="{% if seat_form.type.value != 'credit' or not seat_form.credit_price.value %}hidden{% endif %}" id="creditPrice">
<label class="field-label">{{ seat_form.credit_price.label }}</label>
{{ seat_form.credit_price }}
</div>
</div>
</div>
{% if seat_form.price.errors %}
......
......@@ -36,13 +36,24 @@
<div>{{ object.course_type }}</div>
</div>
{% if object.verified_seat_price %}
{% if object.seat_price %}
<div class="info-item">
<div class="heading">
{% trans "Certificate Price" %}
</div>
<div>
${{ object.verified_seat_price }}
${{ object.seat_price }}
</div>
</div>
{% endif %}
{% if object.credit_seat_price %}
<div class="info-item">
<div class="heading">
{% trans "Credit Price" %}
</div>
<div>
${{ object.credit_seat_price }}
</div>
</div>
{% endif %}
......
......@@ -176,7 +176,18 @@
{% include "publisher/course_run_detail/_clipboard.html" %}
</div>
<div class="copy">
{% with object.verified_seat_price as field %}
{% with object.seat_price as field %}
{% include "publisher/_render_optional_field.html" %}
{% endwith %}
</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Credit $ (minimum)" %}
{% include "publisher/course_run_detail/_clipboard.html" %}
</div>
<div class="copy">
{% with object.credit_seat_price as field %}
{% include "publisher/_render_optional_field.html" %}
{% endwith %}
</div>
......
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