Commit 1eb3f3bf by Waheed Ahmed

Created tab and fields for Sales Force.

ECOM-5110
parent de23f0dc
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('publisher', '0007_auto_20160905_1020'),
]
operations = [
migrations.AddField(
model_name='course',
name='verification_deadline',
field=models.DateTimeField(null=True, verbose_name='Verification deadline', help_text='Last date/time on which verification for this product can be submitted.', blank=True),
),
migrations.AddField(
model_name='historicalcourse',
name='verification_deadline',
field=models.DateTimeField(null=True, verbose_name='Verification deadline', help_text='Last date/time on which verification for this product can be submitted.', blank=True),
),
]
......@@ -95,6 +95,12 @@ class Course(TimeStampedModel, ChangedByMixin):
syllabus = models.TextField(default=None, null=True, blank=True)
prerequisites = models.TextField(default=None, null=True, blank=True)
learner_testimonial = models.CharField(max_length=50, null=True, blank=True)
verification_deadline = models.DateTimeField(
null=True,
blank=True,
verbose_name=_("Verification deadline"),
help_text=_('Last date/time on which verification for this product can be submitted.')
)
primary_subject = models.ForeignKey(
Subject, default=None, null=True, blank=True, related_name='publisher_courses_primary'
......
......@@ -49,6 +49,7 @@ class CreateUpdateCourseViewTests(TestCase):
# Create unique course number
course_number = '{}.1.456'.format(self.course.number)
course_dict = model_to_dict(self.course)
course_dict.pop('verification_deadline')
course_dict['number'] = course_number
response = self.client.post(reverse('publisher:publisher_courses_new'), course_dict)
......@@ -69,6 +70,7 @@ class CreateUpdateCourseViewTests(TestCase):
def test_update_course_with_staff(self):
""" Verify that staff user can update an existing course. """
course_dict = model_to_dict(self.course)
course_dict.pop('verification_deadline')
updated_course_title = 'Updated {}'.format(self.course.title)
course_dict['title'] = updated_course_title
self.assertNotEqual(self.course.title, updated_course_title)
......@@ -126,6 +128,7 @@ class CreateUpdateCourseViewTests(TestCase):
non_staff_user, group = create_non_staff_user_and_login(self)
course_dict = model_to_dict(self.course)
course_dict.pop('verification_deadline')
updated_course_title = 'Updated {}'.format(self.course.title)
course_dict['title'] = updated_course_title
self.assertNotEqual(self.course.title, updated_course_title)
......
# pylint: disable=no-member
from datetime import datetime, timedelta
from unittest import mock
from django.test import TestCase
import ddt
from course_discovery.apps.course_metadata.choices import CourseRunPacing
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory
from course_discovery.apps.publisher.models import Seat, State
from course_discovery.apps.publisher.tests import factories
......@@ -19,11 +20,9 @@ class CourseRunWrapperTests(TestCase):
super(CourseRunWrapperTests, self).setUp()
self.course_run = factories.CourseRunFactory()
self.course = self.course_run.course
organization_1 = OrganizationFactory()
organization_2 = OrganizationFactory()
organization = OrganizationFactory()
self.course.organizations.add(organization_1)
self.course.organizations.add(organization_2)
self.course.organizations.add(organization)
self.course.save()
self.wrapped_course_run = CourseRunWrapper(self.course_run)
......@@ -34,6 +33,8 @@ class CourseRunWrapperTests(TestCase):
def test_partner(self):
""" Verify that the wrapper can return partner values. """
organization = OrganizationFactory()
self.course.organizations.add(organization)
partner = "/".join([org.key for org in self.course_run.course.organizations.all()])
self.assertEqual(self.wrapped_course_run.partner, partner)
......@@ -101,3 +102,47 @@ class CourseRunWrapperTests(TestCase):
def test_workflow_state(self):
""" Verify that the wrapper can return workflow state. """
self.assertEqual(self.wrapped_course_run.workflow_state, State.DRAFT.title())
def test_organization_name(self):
""" Verify that the wrapper return the organization name. """
course = factories.CourseFactory()
course_run = factories.CourseRunFactory(course=course)
wrapped_course_run = CourseRunWrapper(course_run)
self.assertEqual(wrapped_course_run.organization_name, None)
organization = OrganizationFactory()
course.organizations.add(organization)
wrapped_course_run = CourseRunWrapper(course_run)
self.assertEqual(wrapped_course_run.organization_name, organization.name)
def test_is_authored_in_studio(self):
""" Verify that the wrapper return the is_authored_in_studio. """
self.assertFalse(self.wrapped_course_run.is_authored_in_studio)
self.course_run.lms_course_id = 'test/course/id'
self.course_run.save()
self.assertTrue(self.wrapped_course_run.is_authored_in_studio)
def test_is_multiple_partner_course(self):
""" Verify that the wrapper return the is_multiple_partner_course. """
self.assertFalse(self.wrapped_course_run.is_multiple_partner_course)
organization = OrganizationFactory()
self.course.organizations.add(organization)
self.assertTrue(self.wrapped_course_run.is_multiple_partner_course)
def test_is_self_paced(self):
""" Verify that the wrapper return the is_self_paced. """
self.course_run.pacing_type = CourseRunPacing.Instructor
self.course_run.save()
self.assertFalse(self.wrapped_course_run.is_self_paced)
self.course_run.pacing_type = CourseRunPacing.Self
self.course_run.save()
self.assertTrue(self.wrapped_course_run.is_self_paced)
def test_mdc_submission_due_date(self):
""" Verify that the wrapper return the mdc_submission_due_date. """
current_date = datetime.today()
expected_date = current_date - timedelta(days=10)
self.course_run.start = current_date
self.course_run.save()
self.assertEqual(self.wrapped_course_run.mdc_submission_due_date, expected_date)
"""Publisher Wrapper Classes"""
from datetime import timedelta
from django.utils.translation import ugettext_lazy as _
from course_discovery.apps.course_metadata.choices import CourseRunPacing
from course_discovery.apps.publisher.models import Seat, State
CHANGE_STATE_BUTTON_VALUES = {
......@@ -51,14 +55,21 @@ class CourseRunWrapper(BaseWrapper):
@property
def persons(self):
return ', '.join([person.name for person in self.wrapped_obj.staff.all()])
return ', '.join([person.full_name for person in self.wrapped_obj.staff.all()])
@property
def verified_seat_price(self):
seats = [seat for seat in self.wrapped_obj.seats.all() if seat.type == Seat.VERIFIED]
if not seats:
seat = self.wrapped_obj.seats.filter(type=Seat.VERIFIED).first()
if not seat:
return None
return seat.price
@property
def verified_seat_expiry(self):
seat = self.wrapped_obj.seats.filter(type=Seat.VERIFIED).first()
if not seat:
return None
return seats[0].price
return seat.upgrade_deadline
@property
def number(self):
......@@ -119,10 +130,10 @@ class CourseRunWrapper(BaseWrapper):
@property
def organization_key(self):
organizations = self.wrapped_obj.course.organizations.all()
if not organizations:
organization = self.wrapped_obj.course.organizations.first()
if not organization:
return None
return organizations[0].key
return organization.key
@property
def workflow_state(self):
......@@ -131,3 +142,43 @@ class CourseRunWrapper(BaseWrapper):
@property
def change_state_button(self):
return CHANGE_STATE_BUTTON_VALUES.get(self.wrapped_obj.state.name)
@property
def organization_name(self):
organization = self.wrapped_obj.course.organizations.first()
if not organization:
return None
return organization.name
@property
def is_authored_in_studio(self):
if self.wrapped_obj.lms_course_id:
return True
return False
@property
def is_multiple_partner_course(self):
organizations_count = self.wrapped_obj.course.organizations.all().count()
if organizations_count > 1:
return True
return False
@property
def is_self_paced(self):
if self.wrapped_obj.pacing_type == CourseRunPacing.Self:
return True
return False
@property
def mdc_submission_due_date(self):
if self.wrapped_obj.start:
return self.wrapped_obj.start - timedelta(days=10)
return None
@property
def verification_deadline(self):
return self.wrapped_obj.course.verification_deadline
......@@ -18,6 +18,11 @@
margin: auto;
overflow: auto;
.tabs {
width: 100%;
display: inline-block;
}
.actions {
margin-top: 30px;
}
......
......@@ -12,6 +12,7 @@
<button data-tab="#tab-2">{% trans "STUDIO" %}</button>
<button data-tab="#tab-3">{% trans "CAT" %}</button>
<button data-tab="#tab-4">{% trans "DRUPAL" %}</button>
<button data-tab="#tab-5">{% trans "Salesforce" %}</button>
</div>
</nav>
......@@ -48,7 +49,7 @@
</div>
</div>
<div class="tab">
<div class="tabs">
<div id="tab-1" class="tab-content active">
{% include 'publisher/course_run_detail/_all.html' %}
</div>
......@@ -61,6 +62,9 @@
<div id="tab-4" class="tab-content">
{% include 'publisher/course_run_detail/_drupal.html' %}
</div>
<div id="tab-5" class="tab-content">
{% include 'publisher/course_run_detail/_salesforce.html' %}
</div>
</div>
<div class="actions">
......
{% load i18n %}
{% block content %}
<div class="course-information">
<h3 class="hd-3 emphasized">{% trans "Course" %}</h3>
<hr>
<div class="info-item">
<div class="heading">
{% trans "Title" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.title }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Number" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.number }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Account" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.organization_name }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Authored in Studio?" %}
</div>
<div class="copy">{{ object.is_authored_in_studio }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Multiple Partner Course?" %}
</div>
<div class="copy">{{ object.is_multiple_partner_course }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Course Level" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.level_type }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Subject Area" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.course.primary_subject.name }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Language: Course Text" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.language.name }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Language: Transcripts" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.video_languages }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Language: Video" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.language.name }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Language: Video" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.language.name }}</div>
</div>
<h3 class="hd-3 emphasized">{% trans "Course Run" %}</h3>
<hr>
<div class="info-item">
<div class="heading">
{% trans "New or Rerun?" %}
</div>
<div class="copy">{{ object.is_re_run }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Platform" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ platform_name }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Faculty" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.persons }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Course Run Display Name" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.title }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Course Run Number" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.number }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "edX Course Run ID" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.lms_course_id }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Certificate Type" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.course_type }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Course $ (minimum)" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.verified_seat_price }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Self Paced?" %}
</div>
<div class="copy">{{ object.is_self_paced }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "MDC Submission Due Date" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.mdc_submission_due_date }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Verified Conversion Date" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.verification_deadline }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Start Date" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.start }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "End Date" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.end }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Verified Registration Expiration Date" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.verified_seat_expiry }}</div>
</div>
<div class="info-item">
<div class="heading">
{% trans "Certificate Issued Date" %}
{% include "publisher/course_run_detail/clipboard.html" %}
</div>
<div class="copy">{{ object.certificate_generation }}</div>
</div>
</div>
{% endblock %}
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