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
878eaa9f
Commit
878eaa9f
authored
Jul 21, 2014
by
Muhammad Shoaib
Committed by
Chris Dodge
Aug 05, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added django admin pages for Coupon Table
added the suggested changes by cdonge
parent
4333e539
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
3 deletions
+105
-3
lms/djangoapps/shoppingcart/admin.py
+45
-1
lms/djangoapps/shoppingcart/models.py
+21
-0
lms/djangoapps/shoppingcart/tests/test_views.py
+39
-2
No files found.
lms/djangoapps/shoppingcart/admin.py
View file @
878eaa9f
...
@@ -2,6 +2,50 @@
...
@@ -2,6 +2,50 @@
Allows django admin site to add PaidCourseRegistrationAnnotations
Allows django admin site to add PaidCourseRegistrationAnnotations
"""
"""
from
ratelimitbackend
import
admin
from
ratelimitbackend
import
admin
from
shoppingcart.models
import
PaidCourseRegistrationAnnotation
from
shoppingcart.models
import
PaidCourseRegistrationAnnotation
,
Coupon
class
SoftDeleteCouponAdmin
(
admin
.
ModelAdmin
):
"""
Admin for the Coupon table.
soft-delete on the coupons
"""
fields
=
(
'code'
,
'description'
,
'course_id'
,
'percentage_discount'
,
'created_by'
,
'created_at'
,
'is_active'
)
raw_id_fields
=
(
"created_by"
,)
readonly_fields
=
(
'created_at'
,)
actions
=
[
'really_delete_selected'
]
def
queryset
(
self
,
request
):
""" Returns a QuerySet of all model instances that can be edited by the
admin site. This is used by changelist_view. """
# Default: qs = self.model._default_manager.get_active_coupons_query_set()
# Queryset with all the coupons including the soft-deletes: qs = self.model._default_manager.get_query_set()
query_string
=
self
.
model
.
_default_manager
.
get_active_coupons_query_set
()
# pylint: disable=W0212
return
query_string
def
get_actions
(
self
,
request
):
actions
=
super
(
SoftDeleteCouponAdmin
,
self
)
.
get_actions
(
request
)
del
actions
[
'delete_selected'
]
return
actions
def
really_delete_selected
(
self
,
request
,
queryset
):
"""override the default behavior of selected delete method"""
for
obj
in
queryset
:
obj
.
is_active
=
False
obj
.
save
()
if
queryset
.
count
()
==
1
:
message_bit
=
"1 coupon entry was"
else
:
message_bit
=
"
%
s coupon entries were"
%
queryset
.
count
()
self
.
message_user
(
request
,
"
%
s successfully deleted."
%
message_bit
)
def
delete_model
(
self
,
request
,
obj
):
"""override the default behavior of single instance of model delete method"""
obj
.
is_active
=
False
obj
.
save
()
really_delete_selected
.
short_description
=
"Delete s selected entries"
admin
.
site
.
register
(
PaidCourseRegistrationAnnotation
)
admin
.
site
.
register
(
PaidCourseRegistrationAnnotation
)
admin
.
site
.
register
(
Coupon
,
SoftDeleteCouponAdmin
)
lms/djangoapps/shoppingcart/models.py
View file @
878eaa9f
...
@@ -337,6 +337,22 @@ class RegistrationCodeRedemption(models.Model):
...
@@ -337,6 +337,22 @@ class RegistrationCodeRedemption(models.Model):
redeemed_at
=
models
.
DateTimeField
(
default
=
datetime
.
now
(
pytz
.
utc
),
null
=
True
)
redeemed_at
=
models
.
DateTimeField
(
default
=
datetime
.
now
(
pytz
.
utc
),
null
=
True
)
class
SoftDeleteCouponManager
(
models
.
Manager
):
""" Use this manager to get objects that have a is_active=True """
def
get_active_coupons_query_set
(
self
):
"""
filter the is_active = True Coupons only
"""
return
super
(
SoftDeleteCouponManager
,
self
)
.
get_query_set
()
.
filter
(
is_active
=
True
)
def
get_query_set
(
self
):
"""
get all the coupon objects
"""
return
super
(
SoftDeleteCouponManager
,
self
)
.
get_query_set
()
class
Coupon
(
models
.
Model
):
class
Coupon
(
models
.
Model
):
"""
"""
This table contains coupon codes
This table contains coupon codes
...
@@ -350,6 +366,11 @@ class Coupon(models.Model):
...
@@ -350,6 +366,11 @@ class Coupon(models.Model):
created_at
=
models
.
DateTimeField
(
default
=
datetime
.
now
(
pytz
.
utc
))
created_at
=
models
.
DateTimeField
(
default
=
datetime
.
now
(
pytz
.
utc
))
is_active
=
models
.
BooleanField
(
default
=
True
)
is_active
=
models
.
BooleanField
(
default
=
True
)
def
__unicode__
(
self
):
return
"[Coupon] code: {} course: {}"
.
format
(
self
.
code
,
self
.
course_id
)
objects
=
SoftDeleteCouponManager
()
class
CouponRedemption
(
models
.
Model
):
class
CouponRedemption
(
models
.
Model
):
"""
"""
...
...
lms/djangoapps/shoppingcart/tests/test_views.py
View file @
878eaa9f
"""
"""
Tests for Shopping Cart views
Tests for Shopping Cart views
"""
"""
from
django.http
import
HttpRequest
from
urlparse
import
urlparse
from
urlparse
import
urlparse
from
django.conf
import
settings
from
django.conf
import
settings
...
@@ -8,18 +9,21 @@ from django.test import TestCase
...
@@ -8,18 +9,21 @@ from django.test import TestCase
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.contrib.auth.models
import
Group
from
django.contrib.admin.sites
import
AdminSite
from
django.contrib.auth.models
import
Group
,
User
from
django.contrib.messages.storage.fallback
import
FallbackStorage
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
from
shoppingcart.views
import
_can_download_report
,
_get_date_from_str
from
shoppingcart.views
import
_can_download_report
,
_get_date_from_str
from
shoppingcart.models
import
Order
,
CertificateItem
,
PaidCourseRegistration
,
Coupon
from
shoppingcart.models
import
Order
,
CertificateItem
,
PaidCourseRegistration
,
Coupon
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
,
AdminFactory
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
course_modes.models
import
CourseMode
from
course_modes.models
import
CourseMode
from
edxmako.shortcuts
import
render_to_response
from
edxmako.shortcuts
import
render_to_response
from
shoppingcart.processors
import
render_purchase_form_html
from
shoppingcart.processors
import
render_purchase_form_html
from
shoppingcart.admin
import
SoftDeleteCouponAdmin
from
mock
import
patch
,
Mock
from
mock
import
patch
,
Mock
from
shoppingcart.views
import
initialize_report
from
shoppingcart.views
import
initialize_report
from
decimal
import
Decimal
from
decimal
import
Decimal
...
@@ -143,6 +147,39 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
...
@@ -143,6 +147,39 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
self
.
assertEqual
(
resp
.
status_code
,
400
)
self
.
assertEqual
(
resp
.
status_code
,
400
)
self
.
assertIn
(
"Coupon '{0}' already used."
.
format
(
self
.
coupon_code
),
resp
.
content
)
self
.
assertIn
(
"Coupon '{0}' already used."
.
format
(
self
.
coupon_code
),
resp
.
content
)
def
test_soft_delete_coupon
(
self
):
# pylint: disable=E1101
self
.
add_coupon
(
self
.
course_key
,
True
)
coupon
=
Coupon
(
code
=
'TestCode'
,
description
=
'testing'
,
course_id
=
self
.
course_key
,
percentage_discount
=
12
,
created_by
=
self
.
user
,
is_active
=
True
)
coupon
.
save
()
self
.
assertEquals
(
coupon
.
__unicode__
(),
'[Coupon] code: TestCode course: MITx/999/Robot_Super_Course'
)
admin
=
User
.
objects
.
create_user
(
'Mark'
,
'admin+courses@edx.org'
,
'foo'
)
admin
.
is_staff
=
True
get_coupon
=
Coupon
.
objects
.
get
(
id
=
1
)
request
=
HttpRequest
()
request
.
user
=
admin
setattr
(
request
,
'session'
,
'session'
)
# pylint: disable=E1101
messages
=
FallbackStorage
(
request
)
# pylint: disable=E1101
setattr
(
request
,
'_messages'
,
messages
)
# pylint: disable=E1101
coupon_admin
=
SoftDeleteCouponAdmin
(
Coupon
,
AdminSite
())
test_query_set
=
coupon_admin
.
queryset
(
request
)
test_actions
=
coupon_admin
.
get_actions
(
request
)
self
.
assertTrue
(
'really_delete_selected'
in
test_actions
[
'really_delete_selected'
])
self
.
assertEqual
(
get_coupon
.
is_active
,
True
)
coupon_admin
.
really_delete_selected
(
request
,
test_query_set
)
# pylint: disable=E1101
for
coupon
in
test_query_set
:
self
.
assertEqual
(
coupon
.
is_active
,
False
)
coupon_admin
.
delete_model
(
request
,
get_coupon
)
# pylint: disable=E1101
self
.
assertEqual
(
get_coupon
.
is_active
,
False
)
coupon
=
Coupon
(
code
=
'TestCode123'
,
description
=
'testing123'
,
course_id
=
self
.
course_key
,
percentage_discount
=
22
,
created_by
=
self
.
user
,
is_active
=
True
)
coupon
.
save
()
test_query_set
=
coupon_admin
.
queryset
(
request
)
coupon_admin
.
really_delete_selected
(
request
,
test_query_set
)
# pylint: disable=E1101
for
coupon
in
test_query_set
:
self
.
assertEqual
(
coupon
.
is_active
,
False
)
@patch
(
'shoppingcart.views.log.debug'
)
@patch
(
'shoppingcart.views.log.debug'
)
def
test_non_existing_coupon_redemption_on_removing_item
(
self
,
debug_log
):
def
test_non_existing_coupon_redemption_on_removing_item
(
self
,
debug_log
):
...
...
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