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
b6474304
Commit
b6474304
authored
Sep 10, 2014
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5122 from edx/will/ecom-218
Change shopping cart status once sent to Cybersource (ECOM-218)
parents
541419e3
a9c73d24
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
87 additions
and
4 deletions
+87
-4
lms/djangoapps/shoppingcart/models.py
+34
-0
lms/djangoapps/shoppingcart/tests/test_models.py
+32
-0
lms/djangoapps/verify_student/tests/test_views.py
+12
-4
lms/djangoapps/verify_student/views.py
+9
-0
No files found.
lms/djangoapps/shoppingcart/models.py
View file @
b6474304
...
...
@@ -40,8 +40,18 @@ from microsite_configuration import microsite
log
=
logging
.
getLogger
(
"shoppingcart"
)
ORDER_STATUSES
=
(
# The user is selecting what he/she wants to purchase.
(
'cart'
,
'cart'
),
# The user has been sent to the external payment processor.
# At this point, the order should NOT be modified.
# If the user returns to the payment flow, he/she will start a new order.
(
'paying'
,
'paying'
),
# The user has successfully purchased the items in the order.
(
'purchased'
,
'purchased'
),
# The user's order has been refunded.
(
'refunded'
,
'refunded'
),
)
...
...
@@ -129,6 +139,22 @@ class Order(models.Model):
"""
self
.
orderitem_set
.
all
()
.
delete
()
@transaction.commit_on_success
def
start_purchase
(
self
):
"""
Start the purchase process. This will set the order status to "paying",
at which point it should no longer be modified.
Future calls to `Order.get_cart_for_user()` will filter out orders with
status "paying", effectively creating a new (empty) cart.
"""
if
self
.
status
==
'cart'
:
self
.
status
=
'paying'
self
.
save
()
for
item
in
OrderItem
.
objects
.
filter
(
order
=
self
)
.
select_subclasses
():
item
.
start_purchase
()
def
purchase
(
self
,
first
=
''
,
last
=
''
,
street1
=
''
,
street2
=
''
,
city
=
''
,
state
=
''
,
postalcode
=
''
,
country
=
''
,
ccnum
=
''
,
cardtype
=
''
,
processor_reply_dump
=
''
):
"""
...
...
@@ -269,6 +295,14 @@ class OrderItem(models.Model):
self
.
fulfilled_time
=
datetime
.
now
(
pytz
.
utc
)
self
.
save
()
def
start_purchase
(
self
):
"""
Start the purchase process. This will set the order item status to "paying",
at which point it should no longer be modified.
"""
self
.
status
=
'paying'
self
.
save
()
def
purchased_callback
(
self
):
"""
This is called on each inventory item in the shopping cart when the
...
...
lms/djangoapps/shoppingcart/tests/test_models.py
View file @
b6474304
...
...
@@ -102,6 +102,38 @@ class OrderTest(ModuleStoreTestCase):
self
.
assertEquals
(
cart
.
orderitem_set
.
count
(),
len
(
course_costs
))
self
.
assertEquals
(
cart
.
total_cost
,
sum
(
cost
for
_course
,
cost
in
course_costs
))
def
test_start_purchase
(
self
):
# Start the purchase, which will mark the cart as "paying"
cart
=
Order
.
get_cart_for_user
(
user
=
self
.
user
)
CertificateItem
.
add_to_order
(
cart
,
self
.
course_key
,
self
.
cost
,
'honor'
,
currency
=
'usd'
)
cart
.
start_purchase
()
self
.
assertEqual
(
cart
.
status
,
'paying'
)
for
item
in
cart
.
orderitem_set
.
all
():
self
.
assertEqual
(
item
.
status
,
'paying'
)
# Starting the purchase should be idempotent
cart
.
start_purchase
()
self
.
assertEqual
(
cart
.
status
,
'paying'
)
for
item
in
cart
.
orderitem_set
.
all
():
self
.
assertEqual
(
item
.
status
,
'paying'
)
# If we retrieve the cart for the user, we should get a different order
next_cart
=
Order
.
get_cart_for_user
(
user
=
self
.
user
)
self
.
assertNotEqual
(
cart
,
next_cart
)
self
.
assertEqual
(
next_cart
.
status
,
'cart'
)
# Complete the first purchase
cart
.
purchase
()
self
.
assertEqual
(
cart
.
status
,
'purchased'
)
for
item
in
cart
.
orderitem_set
.
all
():
self
.
assertEqual
(
item
.
status
,
'purchased'
)
# Starting the purchase again should be a no-op
cart
.
start_purchase
()
self
.
assertEqual
(
cart
.
status
,
'purchased'
)
for
item
in
cart
.
orderitem_set
.
all
():
self
.
assertEqual
(
item
.
status
,
'purchased'
)
def
test_purchase
(
self
):
# This test is for testing the subclassing functionality of OrderItem, but in
# order to do this, we end up testing the specific functionality of
...
...
lms/djangoapps/verify_student/tests/test_views.py
View file @
b6474304
...
...
@@ -31,8 +31,8 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from
student.tests.factories
import
UserFactory
from
student.models
import
CourseEnrollment
from
course_modes.tests.factories
import
CourseModeFactory
from
courseware.tests.tests
import
TEST_DATA_MONGO_MODULESTORE
from
course_modes.models
import
CourseMode
from
shoppingcart.models
import
Order
,
CertificateItem
from
verify_student.views
import
render_to_response
from
verify_student.models
import
SoftwareSecurePhotoVerification
from
reverification.tests.factories
import
MidcourseReverificationWindowFactory
...
...
@@ -66,8 +66,8 @@ class StartView(TestCase):
self
.
assertHttpForbidden
(
self
.
client
.
get
(
self
.
start_url
()))
@override_settings
(
MODULESTORE
=
TEST_DATA_MONGO_MODULESTORE
)
class
TestCreateOrderView
(
TestCase
):
@override_settings
(
MODULESTORE
=
MODULESTORE_CONFIG
)
class
TestCreateOrderView
(
ModuleStore
TestCase
):
"""
Tests for the create_order view of verified course registration process
"""
...
...
@@ -75,7 +75,7 @@ class TestCreateOrderView(TestCase):
self
.
user
=
UserFactory
.
create
(
username
=
"rusty"
,
password
=
"test"
)
self
.
client
.
login
(
username
=
"rusty"
,
password
=
"test"
)
self
.
course_id
=
'Robot/999/Test_Course'
CourseFactory
.
create
(
org
=
'Robot'
,
number
=
'999'
,
display_name
=
'Test Course'
)
self
.
course
=
CourseFactory
.
create
(
org
=
'Robot'
,
number
=
'999'
,
display_name
=
'Test Course'
)
verified_mode
=
CourseMode
(
course_id
=
SlashSeparatedCourseKey
(
"Robot"
,
"999"
,
'Test_Course'
),
mode_slug
=
"verified"
,
...
...
@@ -156,6 +156,14 @@ class TestCreateOrderView(TestCase):
self
.
assertTrue
(
json_response
.
get
(
'success'
))
self
.
assertIsNotNone
(
json_response
.
get
(
'orderNumber'
))
# Verify that the order exists and is configured correctly
order
=
Order
.
objects
.
get
(
user
=
self
.
user
)
self
.
assertEqual
(
order
.
status
,
'paying'
)
item
=
CertificateItem
.
objects
.
get
(
order
=
order
)
self
.
assertEqual
(
item
.
status
,
'paying'
)
self
.
assertEqual
(
item
.
course_id
,
self
.
course
.
id
)
self
.
assertEqual
(
item
.
mode
,
'verified'
)
@override_settings
(
MODULESTORE
=
MODULESTORE_CONFIG
)
class
TestVerifyView
(
ModuleStoreTestCase
):
...
...
lms/djangoapps/verify_student/views.py
View file @
b6474304
...
...
@@ -227,6 +227,15 @@ def create_order(request):
enrollment_mode
=
current_mode
.
slug
CertificateItem
.
add_to_order
(
cart
,
course_id
,
amount
,
enrollment_mode
)
# Change the order's status so that we don't accidentally modify it later.
# We need to do this to ensure that the parameters we send to the payment system
# match what we store in the database.
# (Ordinarily we would do this client-side when the user submits the form, but since
# the JavaScript on this page does that immediately, we make the change here instead.
# This avoids a second AJAX call and some additional complication of the JavaScript.)
# If a user later re-enters the verification / payment flow, she will create a new order.
cart
.
start_purchase
()
callback_url
=
request
.
build_absolute_uri
(
reverse
(
"shoppingcart.views.postpay_callback"
)
)
...
...
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