Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
6a3d5eb0
Commit
6a3d5eb0
authored
Jun 26, 2014
by
Usman Khalid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Do not refund student if a certificate entry already exists for them.
LMS-2920
parent
d118fb8c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
61 additions
and
2 deletions
+61
-2
common/djangoapps/student/models.py
+8
-1
common/djangoapps/student/tests/tests.py
+23
-0
lms/djangoapps/certificates/models.py
+14
-1
lms/djangoapps/certificates/tests/__init__.py
+0
-0
lms/djangoapps/certificates/tests/factories.py
+16
-0
No files found.
common/djangoapps/student/models.py
View file @
6a3d5eb0
...
...
@@ -36,13 +36,15 @@ from importlib import import_module
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
course_modes.models
import
CourseMode
import
lms.lib.comment_client
as
cc
from
util.query
import
use_read_replica_if_available
from
xmodule_django.models
import
CourseKeyField
,
NoneToEmptyManager
from
opaque_keys.edx.keys
import
CourseKey
from
functools
import
total_ordering
from
certificates.models
import
GeneratedCertificate
from
course_modes.models
import
CourseMode
unenroll_done
=
Signal
(
providing_args
=
[
"course_enrollment"
])
log
=
logging
.
getLogger
(
__name__
)
AUDIT_LOG
=
logging
.
getLogger
(
"audit"
)
...
...
@@ -953,6 +955,11 @@ class CourseEnrollment(models.Model):
# (side-effects are bad)
if
getattr
(
self
,
'can_refund'
,
None
)
is
not
None
:
return
True
# If the student has already been given a certificate they should not be refunded
if
GeneratedCertificate
.
certificate_for_student
(
self
.
user
,
self
.
course_id
)
is
not
None
:
return
False
course_mode
=
CourseMode
.
mode_for_course
(
self
.
course_id
,
'verified'
)
if
course_mode
is
None
:
return
False
...
...
common/djangoapps/student/tests/tests.py
View file @
6a3d5eb0
...
...
@@ -30,6 +30,8 @@ from student.views import (process_survey_link, _cert_info,
change_enrollment
,
complete_course_mode_info
)
from
student.tests.factories
import
UserFactory
,
CourseModeFactory
from
certificates.models
import
CertificateStatuses
from
certificates.tests.factories
import
GeneratedCertificateFactory
import
shoppingcart
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -216,6 +218,7 @@ class DashboardTest(TestCase):
self
.
assertFalse
(
course_mode_info
[
'show_upsell'
])
self
.
assertIsNone
(
course_mode_info
[
'days_for_upsell'
])
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
def
test_refundable
(
self
):
verified_mode
=
CourseModeFactory
.
create
(
course_id
=
self
.
course
.
id
,
...
...
@@ -231,6 +234,26 @@ class DashboardTest(TestCase):
verified_mode
.
save
()
self
.
assertFalse
(
enrollment
.
refundable
())
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
def
test_refundable_when_certificate_exists
(
self
):
verified_mode
=
CourseModeFactory
.
create
(
course_id
=
self
.
course
.
id
,
mode_slug
=
'verified'
,
mode_display_name
=
'Verified'
,
expiration_datetime
=
datetime
.
now
(
pytz
.
UTC
)
+
timedelta
(
days
=
1
)
)
enrollment
=
CourseEnrollment
.
enroll
(
self
.
user
,
self
.
course
.
id
,
mode
=
'verified'
)
self
.
assertTrue
(
enrollment
.
refundable
())
generated_certificate
=
GeneratedCertificateFactory
.
create
(
user
=
self
.
user
,
course_id
=
self
.
course
.
id
,
status
=
CertificateStatuses
.
downloadable
,
mode
=
'verified'
)
self
.
assertFalse
(
enrollment
.
refundable
())
class
EnrollInCourseTest
(
TestCase
):
...
...
lms/djangoapps/certificates/models.py
View file @
6a3d5eb0
...
...
@@ -80,6 +80,8 @@ class CertificateWhitelist(models.Model):
whitelist
=
models
.
BooleanField
(
default
=
0
)
MODES
=
Choices
(
'verified'
,
'honor'
,
'audit'
)
class
GeneratedCertificate
(
models
.
Model
):
user
=
models
.
ForeignKey
(
User
)
course_id
=
CourseKeyField
(
max_length
=
255
,
blank
=
True
,
default
=
None
)
...
...
@@ -90,7 +92,6 @@ class GeneratedCertificate(models.Model):
key
=
models
.
CharField
(
max_length
=
32
,
blank
=
True
,
default
=
''
)
distinction
=
models
.
BooleanField
(
default
=
False
)
status
=
models
.
CharField
(
max_length
=
32
,
default
=
'unavailable'
)
MODES
=
Choices
(
'verified'
,
'honor'
,
'audit'
)
mode
=
models
.
CharField
(
max_length
=
32
,
choices
=
MODES
,
default
=
MODES
.
honor
)
name
=
models
.
CharField
(
blank
=
True
,
max_length
=
255
)
created_date
=
models
.
DateTimeField
(
...
...
@@ -102,6 +103,18 @@ class GeneratedCertificate(models.Model):
class
Meta
:
unique_together
=
((
'user'
,
'course_id'
),)
@classmethod
def
certificate_for_student
(
cls
,
student
,
course_id
):
"""
This returns the certificate for a student for a particular course
or None if no such certificate exits.
"""
try
:
return
cls
.
objects
.
get
(
user
=
student
,
course_id
=
course_id
)
except
cls
.
DoesNotExist
:
pass
return
None
def
certificate_status_for_student
(
student
,
course_id
):
'''
...
...
lms/djangoapps/certificates/tests/__init__.py
0 → 100644
View file @
6a3d5eb0
lms/djangoapps/certificates/tests/factories.py
0 → 100644
View file @
6a3d5eb0
from
factory.django
import
DjangoModelFactory
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
certificates.models
import
GeneratedCertificate
,
CertificateStatuses
,
MODES
# Factories don't have __init__ methods, and are self documenting
# pylint: disable=W0232
class
GeneratedCertificateFactory
(
DjangoModelFactory
):
FACTORY_FOR
=
GeneratedCertificate
course_id
=
None
status
=
CertificateStatuses
.
unavailable
mode
=
MODES
.
honor
name
=
''
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