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
4ef6ee98
Commit
4ef6ee98
authored
May 25, 2018
by
Sanford Student
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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
...
...
@@ -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 @
4ef6ee98
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 @
4ef6ee98
...
...
@@ -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