Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
course-discovery
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
course-discovery
Commits
dfe38973
Commit
dfe38973
authored
May 25, 2018
by
Sanford Student
Committed by
sanfordstudent
Jun 06, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use LMS date for course start/end
parent
28f54cfa
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
132 additions
and
33 deletions
+132
-33
course_discovery/apps/api/tests/test_serializers.py
+1
-0
course_discovery/apps/core/api_client/lms.py
+43
-0
course_discovery/apps/core/views.py
+2
-0
course_discovery/apps/publisher/api/tests/test_serializers.py
+2
-1
course_discovery/apps/publisher/api/tests/test_views.py
+2
-1
course_discovery/apps/publisher/api/v1/tests/test_views.py
+7
-4
course_discovery/apps/publisher/api/v1/views.py
+2
-2
course_discovery/apps/publisher/models.py
+29
-5
course_discovery/apps/publisher/tests/test_models.py
+8
-6
course_discovery/apps/publisher/tests/test_views.py
+9
-9
course_discovery/apps/publisher/tests/utils.py
+22
-0
course_discovery/apps/publisher/views.py
+5
-5
No files found.
course_discovery/apps/api/tests/test_serializers.py
View file @
dfe38973
...
...
@@ -335,6 +335,7 @@ class CourseRunWithProgramsSerializerTests(TestCase):
"""
ProgramFactory
(
courses
=
[
self
.
course_run
.
course
],
status
=
ProgramStatus
.
Deleted
)
serializer
=
CourseRunWithProgramsSerializer
(
self
.
course_run
,
context
=
self
.
serializer_context
)
self
.
assertEqual
(
serializer
.
data
[
'programs'
],
[])
def
test_include_deleted_programs
(
self
):
...
...
course_discovery/apps/core/api_client/lms.py
View file @
dfe38973
...
...
@@ -87,3 +87,46 @@ class LMSAPIClient(object):
exception
.
__class__
.
__name__
,
user
.
username
)
return
api_access_request
def
get_course_details
(
self
,
course_key
):
"""
Get details for a course.
Arguments:
course_key (string): LMS identifier for the course.
Returns:
Body consists of the following fields:
* effort: A textual description of the weekly hours of effort expected
in the course.
* end: Date the course ends, in ISO 8601 notation
* enrollment_end: Date enrollment ends, in ISO 8601 notation
* enrollment_start: Date enrollment begins, in ISO 8601 notation
* id: A unique identifier of the course; a serialized representation
of the opaque key identifying the course.
* media: An object that contains named media items. Included here:
* course_image: An image to show for the course. Represented
as an object with the following fields:
* uri: The location of the image
* name: Name of the course
* number: Catalog number of the course
* org: Name of the organization that owns the course
* overview: A possibly verbose HTML textual description of the course.
Note: this field is only included in the Course Detail view, not
the Course List view.
* short_description: A textual description of the course
* start: Date the course begins, in ISO 8601 notation
* start_display: Readably formatted start of the course
* start_type: Hint describing how `start_display` is set. One of:
* `"string"`: manually set by the course author
* `"timestamp"`: generated from the `start` timestamp
* `"empty"`: no start date is specified
* pacing: Course pacing. Possible values: instructor, self
"""
resource
=
'/api/courses/v1/courses/{}'
.
format
(
course_key
)
try
:
return
getattr
(
self
.
client
,
resource
)
.
get
()
except
(
SlumberBaseException
,
ConnectionError
,
Timeout
,
KeyError
)
as
exception
:
logger
.
exception
(
'
%
s: Failed to fetch CourseDetails from LMS for course [
%
s].'
,
exception
.
__class__
.
__name__
,
course_key
)
course_discovery/apps/core/views.py
View file @
dfe38973
...
...
@@ -8,7 +8,9 @@ from django.db import DatabaseError, connection, transaction
from
django.http
import
Http404
,
JsonResponse
from
django.shortcuts
import
redirect
from
django.views.generic
import
View
from
course_discovery.apps.core.constants
import
Status
try
:
import
newrelic.agent
except
ImportError
:
# pragma: no cover
...
...
course_discovery/apps/publisher/api/tests/test_serializers.py
View file @
dfe38973
...
...
@@ -21,6 +21,7 @@ from course_discovery.apps.publisher.tests.factories import (
CourseFactory
,
CourseRunFactory
,
CourseRunStateFactory
,
CourseStateFactory
,
CourseUserRoleFactory
,
OrganizationExtensionFactory
,
SeatFactory
)
from
course_discovery.apps.publisher.tests.utils
import
MockedStartEndDateTestCase
class
CourseUserRoleSerializerTests
(
SiteMixin
,
TestCase
):
...
...
@@ -292,7 +293,7 @@ class CourseStateSerializerTests(SiteMixin, TestCase):
serializer
.
update
(
self
.
course_state
,
data
)
class
CourseRunStateSerializerTests
(
SiteMixin
,
TestCase
):
class
CourseRunStateSerializerTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
serializer_class
=
CourseRunStateSerializer
def
setUp
(
self
):
...
...
course_discovery/apps/publisher/api/tests/test_views.py
View file @
dfe38973
...
...
@@ -26,6 +26,7 @@ from course_discovery.apps.publisher.models import (
Course
,
CourseRun
,
CourseRunState
,
CourseState
,
OrganizationExtension
,
Seat
)
from
course_discovery.apps.publisher.tests
import
JSON_CONTENT_TYPE
,
factories
from
course_discovery.apps.publisher.tests.utils
import
MockedStartEndDateTestCase
@ddt.ddt
...
...
@@ -588,7 +589,7 @@ class ChangeCourseStateViewTests(SiteMixin, TestCase):
self
.
_assert_email_sent
(
course_team_user
,
subject
)
class
ChangeCourseRunStateViewTests
(
SiteMixin
,
TestCase
):
class
ChangeCourseRunStateViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
def
setUp
(
self
):
super
(
ChangeCourseRunStateViewTests
,
self
)
.
setUp
()
...
...
course_discovery/apps/publisher/api/v1/tests/test_views.py
View file @
dfe38973
...
...
@@ -121,7 +121,7 @@ class CourseRunViewSetTests(APITestCase):
log
.
check
((
LOGGER_NAME
,
'INFO'
,
'Published course run with id: [{}] lms_course_id: [{}], user: [{}], date: [{}]'
.
format
(
publisher_course_run
.
id
,
publisher_course_run
.
lms_course_id
,
self
.
user
,
date
.
today
())))
assert
len
(
responses
.
calls
)
==
3
assert
len
(
responses
.
calls
)
==
5
expected
=
{
'discovery'
:
CourseRunViewSet
.
PUBLICATION_SUCCESS_STATUS
,
'ecommerce'
:
CourseRunViewSet
.
PUBLICATION_SUCCESS_STATUS
,
...
...
@@ -130,7 +130,7 @@ class CourseRunViewSetTests(APITestCase):
assert
response
.
data
==
expected
# Verify the correct deadlines were sent to the E-Commerce API
ecommerce_body
=
json
.
loads
(
responses
.
calls
[
2
]
.
request
.
body
)
ecommerce_body
=
json
.
loads
(
responses
.
calls
[
4
]
.
request
.
body
)
expected
=
[
serialize_seat_for_ecommerce_api
(
audit_seat
),
serialize_seat_for_ecommerce_api
(
professional_seat
),
...
...
@@ -289,13 +289,16 @@ class CourseRunViewSetTests(APITestCase):
root
=
partner
.
studio_url
.
strip
(
'/'
),
key
=
publisher_course_run
.
lms_course_id
)
responses
.
add
(
responses
.
PATCH
,
url
,
json
=
expected_error
,
status
=
500
)
self
.
_mock_ecommerce_api
(
publisher_course_run
)
url
=
reverse
(
'publisher:api:v1:course_run-publish'
,
kwargs
=
{
'pk'
:
publisher_course_run
.
pk
})
response
=
self
.
client
.
post
(
url
,
{})
assert
response
.
status_code
==
502
assert
len
(
responses
.
calls
)
==
2
assert
len
(
responses
.
calls
)
==
4
expected
=
{
'discovery'
:
CourseRunViewSet
.
PUBLICATION_SUCCESS_STATUS
,
'ecommerce'
:
CourseRunViewSet
.
PUBLICATION_SUCCESS_STATUS
,
...
...
@@ -317,7 +320,7 @@ class CourseRunViewSetTests(APITestCase):
url
=
reverse
(
'publisher:api:v1:course_run-publish'
,
kwargs
=
{
'pk'
:
publisher_course_run
.
pk
})
response
=
self
.
client
.
post
(
url
,
{})
assert
response
.
status_code
==
502
assert
len
(
responses
.
calls
)
==
3
assert
len
(
responses
.
calls
)
==
5
expected
=
{
'discovery'
:
CourseRunViewSet
.
PUBLICATION_SUCCESS_STATUS
,
'ecommerce'
:
'FAILED: '
+
json
.
dumps
(
expected_error
),
...
...
course_discovery/apps/publisher/api/v1/views.py
View file @
dfe38973
...
...
@@ -95,7 +95,7 @@ class CourseRunViewSet(viewsets.GenericViewSet):
'id'
:
course_run
.
lms_course_id
,
'uuid'
:
str
(
discovery_course
.
uuid
),
'name'
:
course_run
.
title_override
or
course_run
.
course
.
title
,
'verification_deadline'
:
serialize_datetime
(
course_run
.
end
),
'verification_deadline'
:
serialize_datetime
(
course_run
.
lms_
end
),
}
# NOTE: We only order here to aid testing. The E-Commerce API does NOT care about ordering.
...
...
@@ -146,7 +146,7 @@ class CourseRunViewSet(viewsets.GenericViewSet):
defaults
=
{
'start'
:
course_run
.
start
,
'end'
:
course_run
.
end
,
'end'
:
course_run
.
lms_
end
,
'pacing_type'
:
course_run
.
pacing_type
,
'title_override'
:
course_run
.
title_override
,
'min_effort'
:
course_run
.
min_effort
,
...
...
course_discovery/apps/publisher/models.py
View file @
dfe38973
...
...
@@ -2,6 +2,7 @@ import datetime
import
logging
from
urllib.parse
import
urljoin
import
pytz
import
waffle
from
django.conf
import
settings
from
django.contrib.auth.models
import
Group
...
...
@@ -18,6 +19,7 @@ from sortedm2m.fields import SortedManyToManyField
from
stdimage.models
import
StdImageField
from
taggit.managers
import
TaggableManager
from
course_discovery.apps.core.api_client.lms
import
LMSAPIClient
from
course_discovery.apps.core.models
import
Currency
,
User
from
course_discovery.apps.course_metadata.choices
import
CourseRunPacing
from
course_discovery.apps.course_metadata.models
import
Course
as
DiscoveryCourse
...
...
@@ -28,7 +30,9 @@ from course_discovery.apps.publisher import emails
from
course_discovery.apps.publisher.choices
import
(
CourseRunStateChoices
,
CourseStateChoices
,
InternalUserRole
,
PublisherUserRole
)
from
course_discovery.apps.publisher.utils
import
is_email_notification_enabled
,
is_internal_user
,
is_publisher_admin
from
course_discovery.apps.publisher.utils
import
(
is_email_notification_enabled
,
is_internal_user
,
is_publisher_admin
,
parse_datetime_field
)
from
course_discovery.apps.publisher.validators
import
ImageMultiSizeValidator
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -355,13 +359,33 @@ class CourseRun(TimeStampedModel, ChangedByMixin):
history
=
HistoricalRecords
()
def
__str__
(
self
):
return
'{course}: {
start_date}'
.
format
(
course
=
self
.
course
.
title
,
start_date
=
self
.
start
)
return
'{course}: {
lms_course_id}'
.
format
(
course
=
self
.
course
.
title
,
lms_course_id
=
self
.
lms_course_id
)
@property
def
post_back_url
(
self
):
return
reverse
(
'publisher:publisher_course_runs_edit'
,
kwargs
=
{
'pk'
:
self
.
id
})
@property
def
lms_start
(
self
):
if
self
.
course
.
partner
and
self
.
course
.
partner
.
site
:
lms
=
LMSAPIClient
(
self
.
course
.
partner
.
site
)
details
=
lms
.
get_course_details
(
self
.
lms_course_id
)
if
details
and
details
[
'start'
]:
return
pytz
.
utc
.
localize
(
parse_datetime_field
(
details
[
'start'
]))
return
self
.
start
@property
def
lms_end
(
self
):
if
self
.
course
.
partner
and
self
.
course
.
partner
.
site
:
lms
=
LMSAPIClient
(
self
.
course
.
partner
.
site
)
details
=
lms
.
get_course_details
(
self
.
lms_course_id
)
if
details
and
details
[
'end'
]:
return
pytz
.
utc
.
localize
(
parse_datetime_field
(
details
[
'end'
]))
return
self
.
end
@property
def
created_by
(
self
):
history_user
=
self
.
history
.
order_by
(
'history_date'
)
.
first
()
.
history_user
# pylint: disable=no-member
if
history_user
:
...
...
@@ -497,7 +521,7 @@ class Seat(TimeStampedModel, ChangedByMixin):
if
self
.
upgrade_deadline
:
return
self
.
upgrade_deadline
deadline
=
self
.
course_run
.
end
-
datetime
.
timedelta
(
days
=
settings
.
PUBLISHER_UPGRADE_DEADLINE_DAYS
)
deadline
=
self
.
course_run
.
lms_
end
-
datetime
.
timedelta
(
days
=
settings
.
PUBLISHER_UPGRADE_DEADLINE_DAYS
)
deadline
=
deadline
.
replace
(
hour
=
23
,
minute
=
59
,
second
=
59
,
microsecond
=
99999
)
return
deadline
...
...
@@ -800,8 +824,8 @@ class CourseRunState(TimeStampedModel, ChangedByMixin):
"""
course_run
=
self
.
course_run
return
all
([
course_run
.
course
.
course_state
.
is_approved
,
course_run
.
has_valid_seats
,
course_run
.
start
,
course_run
.
end
,
course_run
.
pacing_type
,
course_run
.
has_valid_staff
,
course_run
.
is_valid_micromasters
,
course_run
.
course
.
course_state
.
is_approved
,
course_run
.
has_valid_seats
,
course_run
.
lms_start
,
course_run
.
lms_end
,
course_run
.
pacing_type
,
course_run
.
has_valid_staff
,
course_run
.
is_valid_micromasters
,
course_run
.
is_valid_professional_certificate
,
course_run
.
is_valid_xseries
,
course_run
.
language
,
course_run
.
transcript_languages
.
all
(),
course_run
.
lms_course_id
,
course_run
.
min_effort
,
course_run
.
video_language
,
course_run
.
length
...
...
course_discovery/apps/publisher/tests/test_models.py
View file @
dfe38973
...
...
@@ -20,21 +20,22 @@ from course_discovery.apps.publisher.models import (
Course
,
CourseUserRole
,
OrganizationExtension
,
OrganizationUserRole
,
Seat
)
from
course_discovery.apps.publisher.tests
import
factories
from
course_discovery.apps.publisher.tests.utils
import
MockedStartEndDateTestCase
@ddt.ddt
class
CourseRunTests
(
TestCase
):
class
CourseRunTests
(
MockedStartEndDate
TestCase
):
@classmethod
def
setUpClass
(
cls
):
super
(
CourseRunTests
,
cls
)
.
setUpClass
()
cls
.
course_run
=
factories
.
CourseRunFactory
()
def
test_str
(
self
):
""" Verify casting an instance to a string returns a string containing the course title and
start date
. """
""" Verify casting an instance to a string returns a string containing the course title and
LMS ID
. """
self
.
assertEqual
(
str
(
self
.
course_run
),
'{title}: {
date
}'
.
format
(
title
=
self
.
course_run
.
course
.
title
,
date
=
self
.
course_run
.
start
'{title}: {
lms_course_id
}'
.
format
(
title
=
self
.
course_run
.
course
.
title
,
lms_course_id
=
self
.
course_run
.
lms_course_id
)
)
...
...
@@ -368,7 +369,7 @@ class CourseTests(TestCase):
@pytest.mark.django_db
class
TestSeatModel
:
class
TestSeatModel
()
:
def
test_str
(
self
):
seat
=
factories
.
SeatFactory
()
assert
str
(
seat
)
==
'{course}: {type}'
.
format
(
course
=
seat
.
course_run
.
course
.
title
,
type
=
seat
.
type
)
...
...
@@ -383,6 +384,7 @@ class TestSeatModel:
settings
.
PUBLISHER_UPGRADE_DEADLINE_DAYS
=
random
.
randint
(
1
,
21
)
now
=
datetime
.
datetime
.
utcnow
()
seat
=
factories
.
SeatFactory
(
type
=
Seat
.
VERIFIED
,
upgrade_deadline
=
None
,
course_run__end
=
now
)
expected
=
now
-
datetime
.
timedelta
(
days
=
settings
.
PUBLISHER_UPGRADE_DEADLINE_DAYS
)
expected
=
expected
.
replace
(
hour
=
23
,
minute
=
59
,
second
=
59
,
microsecond
=
99999
)
assert
seat
.
calculated_upgrade_deadline
==
expected
...
...
@@ -626,7 +628,7 @@ class CourseStateTests(TestCase):
@ddt.ddt
class
CourseRunStateTests
(
TestCase
)
:
class
CourseRunStateTests
:
""" Tests for the publisher `CourseRunState` model. """
@classmethod
...
...
course_discovery/apps/publisher/tests/test_views.py
View file @
dfe38973
...
...
@@ -43,7 +43,7 @@ from course_discovery.apps.publisher.models import (
Course
,
CourseEntitlement
,
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
from
course_discovery.apps.publisher.tests.utils
import
MockedStartEndDateTestCase
,
create_non_staff_user_and_login
from
course_discovery.apps.publisher.utils
import
is_email_notification_enabled
from
course_discovery.apps.publisher.views
import
logger
as
publisher_views_logger
from
course_discovery.apps.publisher.views
import
(
...
...
@@ -55,7 +55,7 @@ from course_discovery.apps.publisher_comments.tests.factories import CommentFact
@ddt.ddt
class
CreateCourseViewTests
(
SiteMixin
,
TestCase
):
class
CreateCourseViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
""" Tests for the publisher `CreateCourseView`. """
def
setUp
(
self
):
...
...
@@ -359,7 +359,7 @@ class CreateCourseViewTests(SiteMixin, TestCase):
@ddt.ddt
class
CreateCourseRunViewTests
(
SiteMixin
,
TestCase
):
class
CreateCourseRunViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
""" Tests for the publisher `CreateCourseRunView`. """
def
setUp
(
self
):
...
...
@@ -840,7 +840,7 @@ class CreateCourseRunViewTests(SiteMixin, TestCase):
@ddt.ddt
class
CourseRunDetailTests
(
SiteMixin
,
TestCase
):
class
CourseRunDetailTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
""" Tests for the course-run detail view. """
def
setUp
(
self
):
...
...
@@ -1185,7 +1185,7 @@ class CourseRunDetailTests(SiteMixin, TestCase):
self
.
assertContains
(
response
,
'{type}: {start}'
.
format
(
type
=
course_run
.
get_pacing_type_display
(),
start
=
course_run
.
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
start
=
course_run
.
lms_
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
)
)
...
...
@@ -1534,7 +1534,7 @@ class CourseRunDetailTests(SiteMixin, TestCase):
# pylint: disable=attribute-defined-outside-init
@ddt.ddt
class
CourseRunListViewTests
(
SiteMixin
,
TestCase
):
class
CourseRunListViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
def
setUp
(
self
):
super
(
CourseRunListViewTests
,
self
)
.
setUp
()
Site
.
objects
.
exclude
(
id
=
self
.
site
.
id
)
.
delete
()
...
...
@@ -2671,7 +2671,7 @@ class CourseDetailViewTests(TestCase):
@ddt.ddt
class
CourseEditViewTests
(
SiteMixin
,
TestCase
):
class
CourseEditViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
""" Tests for the course edit view. """
def
setUp
(
self
):
...
...
@@ -3357,7 +3357,7 @@ class CourseEditViewTests(SiteMixin, TestCase):
@ddt.ddt
class
CourseRunEditViewTests
(
SiteMixin
,
TestCase
):
class
CourseRunEditViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
""" Tests for the course run edit view. """
def
setUp
(
self
):
...
...
@@ -4075,7 +4075,7 @@ class CourseRevisionViewTests(SiteMixin, TestCase):
@ddt.ddt
class
CreateRunFromDashboardViewTests
(
SiteMixin
,
TestCase
):
class
CreateRunFromDashboardViewTests
(
SiteMixin
,
MockedStartEndDate
TestCase
):
""" Tests for the publisher `CreateRunFromDashboardView`. """
def
setUp
(
self
):
...
...
course_discovery/apps/publisher/tests/utils.py
View file @
dfe38973
import
datetime
import
mock
from
django.test
import
TestCase
from
course_discovery.apps.core.tests.factories
import
USER_PASSWORD
,
UserFactory
from
course_discovery.apps.publisher.tests
import
factories
class
MockedStartEndDateTestCase
(
TestCase
):
def
setUp
(
self
):
super
(
MockedStartEndDateTestCase
,
self
)
.
setUp
()
start_date_patcher
=
mock
.
patch
(
'course_discovery.apps.publisher.models.CourseRun.lms_start'
,
new_callable
=
mock
.
PropertyMock
)
self
.
addCleanup
(
start_date_patcher
.
stop
)
self
.
start_date_mock
=
start_date_patcher
.
start
()
self
.
start_date_mock
.
return_value
=
datetime
.
datetime
.
utcnow
()
end_date_patcher
=
mock
.
patch
(
'course_discovery.apps.publisher.models.CourseRun.lms_end'
,
new_callable
=
mock
.
PropertyMock
)
self
.
addCleanup
(
end_date_patcher
.
stop
)
self
.
end_date_mock
=
end_date_patcher
.
start
()
self
.
end_date_mock
.
return_value
=
datetime
.
datetime
.
utcnow
()
def
create_non_staff_user_and_login
(
test_class
):
""" Create non staff user and login and return user and group. """
non_staff_user
=
UserFactory
()
...
...
course_discovery/apps/publisher/views.py
View file @
dfe38973
...
...
@@ -195,7 +195,7 @@ class CourseRunDetailView(mixins.LoginRequiredMixin, mixins.PublisherPermissionM
if
history_object
:
context
[
'publish_date'
]
=
history_object
.
modified
start_date
=
course_run
.
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
if
course_run
.
start
else
None
start_date
=
course_run
.
lms_start
.
strftime
(
"
%
B
%
d,
%
Y"
)
if
course_run
.
lms_
start
else
None
context
[
'breadcrumbs'
]
=
make_bread_crumbs
(
[
(
reverse
(
'publisher:publisher_courses'
),
_
(
'Courses'
)),
...
...
@@ -430,7 +430,7 @@ class CourseEditView(mixins.PublisherPermissionMixin, UpdateView):
published_runs
=
set
()
for
course_run
in
self
.
_get_active_course_runs
(
course
):
if
course_run
.
course_run_state
.
is_published
:
start_date
=
course_run
.
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
if
course_run
.
start
else
None
start_date
=
course_run
.
lms_start
.
strftime
(
"
%
B
%
d,
%
Y"
)
if
course_run
.
lms_
start
else
None
published_runs
.
add
(
'{type} - {start}'
.
format
(
type
=
course_run
.
get_pacing_type_display
(),
start
=
start_date
...
...
@@ -460,12 +460,12 @@ class CourseEditView(mixins.PublisherPermissionMixin, UpdateView):
if
not
type_is_valid
:
misconfigured_seat_type_runs
.
add
(
'{type} - {start}'
.
format
(
type
=
course_run
.
get_pacing_type_display
(),
start
=
course_run
.
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
start
=
course_run
.
lms_
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
))
if
not
price_is_valid
:
misconfigured_price_runs
.
add
(
'{type} - {start}'
.
format
(
type
=
course_run
.
get_pacing_type_display
(),
start
=
course_run
.
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
start
=
course_run
.
lms_
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
))
return
misconfigured_price_runs
,
misconfigured_seat_type_runs
...
...
@@ -1005,7 +1005,7 @@ class CourseRunEditView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMix
course_run_seat
=
self
.
get_latest_course_run_seat
(
course_run
)
context
[
'seat_form'
]
=
self
.
seat_form
(
instance
=
course_run_seat
)
start_date
=
course_run
.
start
.
strftime
(
"
%
B
%
d,
%
Y"
)
if
course_run
.
start
else
None
start_date
=
course_run
.
lms_start
.
strftime
(
"
%
B
%
d,
%
Y"
)
if
course_run
.
lms_
start
else
None
context
[
'breadcrumbs'
]
=
make_bread_crumbs
(
[
(
reverse
(
'publisher:publisher_courses'
),
'Courses'
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment