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
820cc4aa
Commit
820cc4aa
authored
Feb 04, 2015
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6784 from edx/will/invoice-refactor-squashed
Invoice data model refactor
parents
6266dcf1
22af2b75
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1091 additions
and
101 deletions
+1091
-101
common/djangoapps/student/tests/tests.py
+7
-1
common/djangoapps/student/views.py
+2
-2
lms/djangoapps/instructor/tests/test_api.py
+99
-29
lms/djangoapps/instructor/views/api.py
+63
-17
lms/djangoapps/instructor_analytics/basic.py
+12
-9
lms/djangoapps/instructor_analytics/tests/test_basic.py
+17
-5
lms/djangoapps/shoppingcart/admin.py
+129
-4
lms/djangoapps/shoppingcart/migrations/0025_update_invoice_models.py
+311
-0
lms/djangoapps/shoppingcart/migrations/0026_migrate_invoices.py
+270
-0
lms/djangoapps/shoppingcart/models.py
+156
-9
lms/djangoapps/shoppingcart/tests/test_views.py
+1
-1
lms/static/sass/course/instructor/_instructor_2.scss
+1
-1
lms/templates/instructor/instructor_dashboard_2/e-commerce.html
+19
-19
lms/templates/instructor/instructor_dashboard_2/generate_registarion_codes_modal.html
+4
-4
No files found.
common/djangoapps/student/tests/tests.py
View file @
820cc4aa
...
...
@@ -299,8 +299,14 @@ class DashboardTest(ModuleStoreTestCase):
recipient_name
=
'Testw_1'
,
recipient_email
=
'test2@test.com'
,
internal_reference
=
"A"
,
course_id
=
self
.
course
.
id
,
is_valid
=
False
)
invoice_item
=
shoppingcart
.
models
.
CourseRegistrationCodeInvoiceItem
.
objects
.
create
(
invoice
=
sale_invoice_1
,
qty
=
1
,
unit_price
=
1234.32
,
course_id
=
self
.
course
.
id
)
course_reg_code
=
shoppingcart
.
models
.
CourseRegistrationCode
(
code
=
"abcde"
,
course_id
=
self
.
course
.
id
,
created_by
=
self
.
user
,
invoice
=
sale_invoice_1
,
mode_slug
=
'honor'
code
=
"abcde"
,
course_id
=
self
.
course
.
id
,
created_by
=
self
.
user
,
invoice
=
sale_invoice_1
,
invoice_item
=
invoice_item
,
mode_slug
=
'honor'
)
course_reg_code
.
save
()
...
...
common/djangoapps/student/views.py
View file @
820cc4aa
...
...
@@ -465,8 +465,8 @@ def is_course_blocked(request, redeemed_registration_codes, course_key):
# registration codes may be generated via Bulk Purchase Scenario
# we have to check only for the invoice generated registration codes
# that their invoice is valid or not
if
redeemed_registration
.
invoice
:
if
not
getattr
(
redeemed_registration
.
invoice
,
'is_valid'
):
if
redeemed_registration
.
invoice
_item
:
if
not
getattr
(
redeemed_registration
.
invoice
_item
.
invoice
,
'is_valid'
):
blocked
=
True
# disabling email notifications for unpaid registration courses
Optout
.
objects
.
get_or_create
(
user
=
request
.
user
,
course_id
=
course_key
)
...
...
lms/djangoapps/instructor/tests/test_api.py
View file @
820cc4aa
...
...
@@ -39,7 +39,7 @@ from django_comment_common.utils import seed_permissions_roles
from
microsite_configuration
import
microsite
from
shoppingcart.models
import
(
RegistrationCodeRedemption
,
Order
,
CouponRedemption
,
PaidCourseRegistration
,
Coupon
,
Invoice
,
CourseRegistrationCode
PaidCourseRegistration
,
Coupon
,
Invoice
,
CourseRegistrationCode
,
CourseRegistrationCodeInvoiceItem
)
from
shoppingcart.pdf
import
PDFInvoice
from
student.models
import
(
...
...
@@ -1713,6 +1713,12 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
recipient_name
=
'Testw'
,
recipient_email
=
'test1@test.com'
,
customer_reference_number
=
'2Fwe23S'
,
internal_reference
=
"A"
,
course_id
=
self
.
course
.
id
,
is_valid
=
True
)
self
.
invoice_item
=
CourseRegistrationCodeInvoiceItem
.
objects
.
create
(
invoice
=
self
.
sale_invoice_1
,
qty
=
1
,
unit_price
=
1234.32
,
course_id
=
self
.
course
.
id
)
self
.
students
=
[
UserFactory
()
for
_
in
xrange
(
6
)]
for
student
in
self
.
students
:
...
...
@@ -1724,8 +1730,12 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
"""
for
i
in
range
(
2
):
course_registration_code
=
CourseRegistrationCode
(
code
=
'sale_invoice{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
mode_slug
=
'honor'
code
=
'sale_invoice{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
invoice_item
=
self
.
invoice_item
,
mode_slug
=
'honor'
)
course_registration_code
.
save
()
...
...
@@ -1745,7 +1755,7 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
data
[
'event_type'
]
=
"re_validate"
self
.
assert_request_status_code
(
200
,
url
,
method
=
"POST"
,
data
=
data
)
# Now re_validate the same act
o
ve invoice number and expect an Bad request
# Now re_validate the same act
i
ve invoice number and expect an Bad request
response
=
self
.
assert_request_status_code
(
400
,
url
,
method
=
"POST"
,
data
=
data
)
self
.
assertIn
(
"This invoice is already active."
,
response
.
content
)
...
...
@@ -1844,12 +1854,19 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
"""
for
i
in
range
(
2
):
course_registration_code
=
CourseRegistrationCode
(
code
=
'sale_invoice{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
mode_slug
=
'honor'
code
=
'sale_invoice{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
invoice_item
=
self
.
invoice_item
,
mode_slug
=
'honor'
)
course_registration_code
.
save
()
url
=
reverse
(
'get_sale_records'
,
kwargs
=
{
'course_id'
:
self
.
course
.
id
.
to_deprecated_string
()})
url
=
reverse
(
'get_sale_records'
,
kwargs
=
{
'course_id'
:
self
.
course
.
id
.
to_deprecated_string
()}
)
response
=
self
.
client
.
get
(
url
+
'/csv'
,
{})
self
.
assertEqual
(
response
[
'Content-Type'
],
'text/csv'
)
...
...
@@ -1859,8 +1876,12 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
"""
for
i
in
range
(
5
):
course_registration_code
=
CourseRegistrationCode
(
code
=
'sale_invoice{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
mode_slug
=
'honor'
code
=
'sale_invoice{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
invoice_item
=
self
.
invoice_item
,
mode_slug
=
'honor'
)
course_registration_code
.
save
()
...
...
@@ -1870,7 +1891,13 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
self
.
assertIn
(
'sale'
,
res_json
)
for
res
in
res_json
[
'sale'
]:
self
.
validate_sale_records_response
(
res
,
course_registration_code
,
self
.
sale_invoice_1
,
0
)
self
.
validate_sale_records_response
(
res
,
course_registration_code
,
self
.
sale_invoice_1
,
0
,
invoice_item
=
self
.
invoice_item
)
def
test_get_sale_records_features_with_multiple_invoices
(
self
):
"""
...
...
@@ -1878,8 +1905,12 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
"""
for
i
in
range
(
5
):
course_registration_code
=
CourseRegistrationCode
(
code
=
'qwerty{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
mode_slug
=
'honor'
code
=
'qwerty{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
self
.
sale_invoice_1
,
invoice_item
=
self
.
invoice_item
,
mode_slug
=
'honor'
)
course_registration_code
.
save
()
...
...
@@ -1890,10 +1921,17 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
internal_reference
=
"B"
,
course_id
=
self
.
course
.
id
)
invoice_item_2
=
CourseRegistrationCodeInvoiceItem
.
objects
.
create
(
invoice
=
sale_invoice_2
,
qty
=
1
,
unit_price
=
1234.32
,
course_id
=
self
.
course
.
id
)
for
i
in
range
(
5
):
course_registration_code
=
CourseRegistrationCode
(
code
=
'xyzmn{}'
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
sale_invoice_2
,
mode_slug
=
'honor'
created_by
=
self
.
instructor
,
invoice
=
sale_invoice_2
,
invoice_item
=
invoice_item_2
,
mode_slug
=
'honor'
)
course_registration_code
.
save
()
...
...
@@ -1902,10 +1940,22 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
res_json
=
json
.
loads
(
response
.
content
)
self
.
assertIn
(
'sale'
,
res_json
)
self
.
validate_sale_records_response
(
res_json
[
'sale'
][
0
],
course_registration_code
,
self
.
sale_invoice_1
,
0
)
self
.
validate_sale_records_response
(
res_json
[
'sale'
][
1
],
course_registration_code
,
sale_invoice_2
,
0
)
self
.
validate_sale_records_response
(
res_json
[
'sale'
][
0
],
course_registration_code
,
self
.
sale_invoice_1
,
0
,
invoice_item
=
self
.
invoice_item
)
self
.
validate_sale_records_response
(
res_json
[
'sale'
][
1
],
course_registration_code
,
sale_invoice_2
,
0
,
invoice_item
=
invoice_item_2
)
def
validate_sale_records_response
(
self
,
res
,
course_registration_code
,
invoice
,
used_codes
):
def
validate_sale_records_response
(
self
,
res
,
course_registration_code
,
invoice
,
used_codes
,
invoice_item
):
"""
validate sale records attribute values with the response object
"""
...
...
@@ -1919,7 +1969,7 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
self
.
assertEqual
(
res
[
'customer_reference_number'
],
invoice
.
customer_reference_number
)
self
.
assertEqual
(
res
[
'invoice_number'
],
invoice
.
id
)
self
.
assertEqual
(
res
[
'created_by'
],
course_registration_code
.
created_by
.
username
)
self
.
assertEqual
(
res
[
'course_id'
],
invoice
.
course_id
.
to_deprecated_string
())
self
.
assertEqual
(
res
[
'course_id'
],
invoice
_item
.
course_id
.
to_deprecated_string
())
self
.
assertEqual
(
res
[
'total_used_codes'
],
used_codes
)
self
.
assertEqual
(
res
[
'total_codes'
],
5
)
...
...
@@ -3011,7 +3061,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
12
,
'company_name'
:
'Test Group'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3043,7 +3093,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
5
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
121.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
121.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
'True'
...
...
@@ -3065,7 +3115,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
5
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
121.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
121.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
'True'
...
...
@@ -3107,7 +3157,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
15
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3129,7 +3179,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
15
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3165,7 +3215,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
coupon
.
save
()
data
=
{
'total_registration_codes'
:
3
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3189,7 +3239,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
2
,
'company_name'
:
'Test Group'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3225,7 +3275,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
9
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'company_contact_email'
:
'Test@company.com'
,
'recipient_name'
:
'Test123'
,
'
unit
_price'
:
122.45
,
'company_contact_email'
:
'Test@company.com'
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3276,7 +3326,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
9
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3315,7 +3365,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
9
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3342,7 +3392,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
)
data
=
{
'total_registration_codes'
:
9
,
'company_name'
:
'Group Alpha'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
@@ -3361,7 +3411,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
5.5
,
'company_name'
:
'Group Invoice'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
True
...
...
@@ -3379,6 +3429,26 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
body
=
response
.
content
.
replace
(
'
\r
'
,
''
)
self
.
assertTrue
(
body
.
startswith
(
EXPECTED_CSV_HEADER
))
def
test_with_invalid_unit_price
(
self
):
"""
Test to generate a response of all the course registration codes
"""
generate_code_url
=
reverse
(
'generate_registration_codes'
,
kwargs
=
{
'course_id'
:
self
.
course
.
id
.
to_deprecated_string
()}
)
data
=
{
'total_registration_codes'
:
10
,
'company_name'
:
'Group Invoice'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'unit_price'
:
'invalid'
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
True
}
response
=
self
.
client
.
post
(
generate_code_url
,
data
,
**
{
'HTTP_HOST'
:
'localhost'
})
self
.
assertEqual
(
response
.
status_code
,
400
,
response
.
content
)
self
.
assertIn
(
'Could not parse amount as'
,
response
.
content
)
def
test_get_historical_coupon_codes
(
self
):
"""
Test to download a response of all the active coupon codes
...
...
lms/djangoapps/instructor/views/api.py
View file @
820cc4aa
...
...
@@ -27,6 +27,7 @@ import string # pylint: disable=deprecated-module
import
random
import
unicodecsv
import
urllib
import
decimal
from
student
import
auth
from
student.roles
import
CourseSalesAdminRole
from
util.file
import
store_uploaded_file
,
course_and_time_based_filename_generator
,
FileValidationException
,
UniversalNewlineIterator
...
...
@@ -49,7 +50,14 @@ from django_comment_common.models import (
)
from
edxmako.shortcuts
import
render_to_response
,
render_to_string
from
courseware.models
import
StudentModule
from
shoppingcart.models
import
Coupon
,
CourseRegistrationCode
,
RegistrationCodeRedemption
,
Invoice
,
CourseMode
from
shoppingcart.models
import
(
Coupon
,
CourseRegistrationCode
,
RegistrationCodeRedemption
,
Invoice
,
CourseMode
,
CourseRegistrationCodeInvoiceItem
,
)
from
student.models
import
CourseEnrollment
,
unique_id_for_user
,
anonymous_id_for_user
import
instructor_task.api
from
instructor_task.api_helper
import
AlreadyRunningError
...
...
@@ -885,9 +893,13 @@ def sale_validation(request, course_id):
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
try
:
obj_invoice
=
Invoice
.
objects
.
select_related
(
'is_valid'
)
.
get
(
id
=
invoice_number
,
course_id
=
course_id
)
except
Invoice
.
DoesNotExist
:
return
HttpResponseNotFound
(
_
(
"Invoice number '{0}' does not exist."
)
.
format
(
invoice_number
))
obj_invoice
=
CourseRegistrationCodeInvoiceItem
.
objects
.
select_related
(
'invoice'
)
.
get
(
invoice_id
=
invoice_number
,
course_id
=
course_id
)
obj_invoice
=
obj_invoice
.
invoice
except
CourseRegistrationCodeInvoiceItem
.
DoesNotExist
:
# Check for old type invoices
return
HttpResponseNotFound
(
_
(
"Invoice number '{0}' does not exist."
.
format
(
invoice_number
)))
if
event_type
==
"invalidate"
:
return
invalidate_invoice
(
obj_invoice
)
...
...
@@ -1053,7 +1065,7 @@ def get_coupon_codes(request, course_id): # pylint: disable=unused-argument
return
instructor_analytics
.
csvs
.
create_csv_response
(
'Coupons.csv'
,
header
,
data_rows
)
def
save_registration_code
(
user
,
course_id
,
mode_slug
,
invoice
=
None
,
order
=
None
):
def
save_registration_code
(
user
,
course_id
,
mode_slug
,
invoice
=
None
,
order
=
None
,
invoice_item
=
None
):
"""
recursive function that generate a new code every time and saves in the Course Registration Table
if validation check passes
...
...
@@ -1064,6 +1076,7 @@ def save_registration_code(user, course_id, mode_slug, invoice=None, order=None)
mode_slug (str): The Course Mode Slug associated with any enrollment made by these codes.
invoice (Invoice): (Optional) The associated invoice for this code.
order (Order): (Optional) The associated order for this code.
invoice_item (CourseRegistrationCodeInvoiceItem) : (Optional) The associated CourseRegistrationCodeInvoiceItem
Returns:
The newly created CourseRegistrationCode.
...
...
@@ -1074,7 +1087,9 @@ def save_registration_code(user, course_id, mode_slug, invoice=None, order=None)
# check if the generated code is in the Coupon Table
matching_coupons
=
Coupon
.
objects
.
filter
(
code
=
code
,
is_active
=
True
)
if
matching_coupons
:
return
save_registration_code
(
user
,
course_id
,
invoice
,
order
)
return
save_registration_code
(
user
,
course_id
,
mode_slug
,
invoice
=
invoice
,
order
=
order
,
invoice_item
=
invoice_item
)
course_registration
=
CourseRegistrationCode
(
code
=
code
,
...
...
@@ -1082,13 +1097,16 @@ def save_registration_code(user, course_id, mode_slug, invoice=None, order=None)
created_by
=
user
,
invoice
=
invoice
,
order
=
order
,
mode_slug
=
mode_slug
mode_slug
=
mode_slug
,
invoice_item
=
invoice_item
)
try
:
course_registration
.
save
()
return
course_registration
except
IntegrityError
:
return
save_registration_code
(
user
,
course_id
,
invoice
,
order
)
return
save_registration_code
(
user
,
course_id
,
mode_slug
,
invoice
=
invoice
,
order
=
order
,
invoice_item
=
invoice_item
)
def
registration_codes_csv
(
file_name
,
codes_list
,
csv_type
=
None
):
...
...
@@ -1130,11 +1148,13 @@ def get_registration_codes(request, course_id): # pylint: disable=unused-argume
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
#filter all the course registration codes
registration_codes
=
CourseRegistrationCode
.
objects
.
filter
(
course_id
=
course_id
)
.
order_by
(
'invoice__company_name'
)
registration_codes
=
CourseRegistrationCode
.
objects
.
filter
(
course_id
=
course_id
)
.
order_by
(
'invoice_item__invoice__company_name'
)
company_name
=
request
.
POST
[
'download_company_name'
]
if
company_name
:
registration_codes
=
registration_codes
.
filter
(
invoice__company_name
=
company_name
)
registration_codes
=
registration_codes
.
filter
(
invoice_
item__invoice_
_company_name
=
company_name
)
csv_type
=
'download'
return
registration_codes_csv
(
"Registration_Codes.csv"
,
registration_codes
,
csv_type
)
...
...
@@ -1160,7 +1180,21 @@ def generate_registration_codes(request, course_id):
company_name
=
request
.
POST
[
'company_name'
]
company_contact_name
=
request
.
POST
[
'company_contact_name'
]
company_contact_email
=
request
.
POST
[
'company_contact_email'
]
sale_price
=
request
.
POST
[
'sale_price'
]
unit_price
=
request
.
POST
[
'unit_price'
]
try
:
unit_price
=
(
decimal
.
Decimal
(
unit_price
)
)
.
quantize
(
decimal
.
Decimal
(
'.01'
),
rounding
=
decimal
.
ROUND_DOWN
)
except
decimal
.
InvalidOperation
:
return
HttpResponse
(
status
=
400
,
content
=
_
(
u"Could not parse amount as a decimal"
)
)
recipient_name
=
request
.
POST
[
'recipient_name'
]
recipient_email
=
request
.
POST
[
'recipient_email'
]
address_line_1
=
request
.
POST
[
'address_line_1'
]
...
...
@@ -1177,6 +1211,7 @@ def generate_registration_codes(request, course_id):
recipient_list
.
append
(
request
.
user
.
email
)
invoice_copy
=
True
sale_price
=
unit_price
*
course_code_number
UserPreference
.
set_preference
(
request
.
user
,
INVOICE_KEY
,
invoice_copy
)
sale_invoice
=
Invoice
.
objects
.
create
(
total_amount
=
sale_price
,
...
...
@@ -1197,6 +1232,13 @@ def generate_registration_codes(request, course_id):
customer_reference_number
=
customer_reference_number
)
invoice_item
=
CourseRegistrationCodeInvoiceItem
.
objects
.
create
(
invoice
=
sale_invoice
,
qty
=
course_code_number
,
unit_price
=
unit_price
,
course_id
=
course_id
)
course
=
get_course_by_id
(
course_id
,
depth
=
0
)
paid_modes
=
CourseMode
.
paid_modes_for_course
(
course_id
)
...
...
@@ -1217,7 +1259,7 @@ def generate_registration_codes(request, course_id):
registration_codes
=
[]
for
__
in
range
(
course_code_number
):
# pylint: disable=redefined-outer-name
generated_registration_code
=
save_registration_code
(
request
.
user
,
course_id
,
course_mode
.
slug
,
sale_invoice
,
order
=
None
request
.
user
,
course_id
,
course_mode
.
slug
,
invoice
=
sale_invoice
,
order
=
None
,
invoice_item
=
invoice_item
)
registration_codes
.
append
(
generated_registration_code
)
...
...
@@ -1309,13 +1351,17 @@ def active_registration_codes(request, course_id): # pylint: disable=unused-arg
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
# find all the registration codes in this course
registration_codes_list
=
CourseRegistrationCode
.
objects
.
filter
(
course_id
=
course_id
)
.
order_by
(
'invoice__company_name'
)
registration_codes_list
=
CourseRegistrationCode
.
objects
.
filter
(
course_id
=
course_id
)
.
order_by
(
'invoice_item__invoice__company_name'
)
company_name
=
request
.
POST
[
'active_company_name'
]
if
company_name
:
registration_codes_list
=
registration_codes_list
.
filter
(
invoice__company_name
=
company_name
)
registration_codes_list
=
registration_codes_list
.
filter
(
invoice_
item__invoice_
_company_name
=
company_name
)
# find the redeemed registration codes if any exist in the db
code_redemption_set
=
RegistrationCodeRedemption
.
objects
.
select_related
(
'registration_code'
)
.
filter
(
registration_code__course_id
=
course_id
)
code_redemption_set
=
RegistrationCodeRedemption
.
objects
.
select_related
(
'registration_code'
,
'registration_code__invoice_item__invoice'
)
.
filter
(
registration_code__course_id
=
course_id
)
if
code_redemption_set
.
exists
():
redeemed_registration_codes
=
[
code
.
registration_code
.
code
for
code
in
code_redemption_set
]
# exclude the redeemed registration codes from the registration codes list and you will get
...
...
@@ -1346,11 +1392,11 @@ def spent_registration_codes(request, course_id): # pylint: disable=unused-argu
# you will get a list of all the spent(Redeemed) Registration Codes
spent_codes_list
=
CourseRegistrationCode
.
objects
.
filter
(
course_id
=
course_id
,
code__in
=
redeemed_registration_codes
)
.
order_by
(
'invoice_
_company_nam
e'
)
)
.
order_by
(
'invoice_
item__invoice__company_name'
)
.
select_related
(
'invoice_item__invoic
e'
)
company_name
=
request
.
POST
[
'spent_company_name'
]
if
company_name
:
spent_codes_list
=
spent_codes_list
.
filter
(
invoice__company_name
=
company_name
)
# pylint: disable=maybe-no-member
spent_codes_list
=
spent_codes_list
.
filter
(
invoice_
item__invoice_
_company_name
=
company_name
)
# pylint: disable=maybe-no-member
csv_type
=
'spent'
return
registration_codes_csv
(
"Spent_Registration_Codes.csv"
,
spent_codes_list
,
csv_type
)
...
...
lms/djangoapps/instructor_analytics/basic.py
View file @
820cc4aa
...
...
@@ -6,7 +6,7 @@ Serve miscellaneous course and student data
import
json
from
shoppingcart.models
import
(
PaidCourseRegistration
,
CouponRedemption
,
Invoice
,
CourseRegCodeItem
,
OrderTypes
,
RegistrationCodeRedemption
,
CourseRegistrationCode
OrderTypes
,
RegistrationCodeRedemption
,
CourseRegistrationCode
,
CourseRegistrationCodeInvoiceItem
)
from
django.db.models
import
Q
from
django.conf
import
settings
...
...
@@ -110,22 +110,25 @@ def sale_record_features(course_id, features):
{'company_name': 'group_C', 'total_codes': '3', total_amount:'total_amount3 in decimal'.}
]
"""
sales
=
Invoice
.
objects
.
filter
(
course_id
=
course_id
)
sales
=
CourseRegistrationCodeInvoiceItem
.
objects
.
select_related
(
'invoice'
)
.
filter
(
course_id
=
course_id
)
def
sale_records_info
(
sale
,
features
):
""" convert sales records to dictionary """
"""
Convert sales records to dictionary
"""
invoice
=
sale
.
invoice
sale_features
=
[
x
for
x
in
SALE_FEATURES
if
x
in
features
]
course_reg_features
=
[
x
for
x
in
COURSE_REGISTRATION_FEATURES
if
x
in
features
]
# Extracting sale information
sale_dict
=
dict
((
feature
,
getattr
(
sal
e
,
feature
))
sale_dict
=
dict
((
feature
,
getattr
(
invoic
e
,
feature
))
for
feature
in
sale_features
)
total_used_codes
=
RegistrationCodeRedemption
.
objects
.
filter
(
registration_code__in
=
sale
.
courseregistrationcode_set
.
all
()
)
.
count
()
sale_dict
.
update
({
"invoice_number"
:
getattr
(
sal
e
,
'id'
)})
sale_dict
.
update
({
"invoice_number"
:
getattr
(
invoic
e
,
'id'
)})
sale_dict
.
update
({
"total_codes"
:
sale
.
courseregistrationcode_set
.
all
()
.
count
()})
sale_dict
.
update
({
'total_used_codes'
:
total_used_codes
})
...
...
@@ -261,11 +264,11 @@ def course_registration_features(features, registration_codes, csv_type):
course_registration_dict
=
dict
((
feature
,
getattr
(
registration_code
,
feature
))
for
feature
in
registration_features
)
course_registration_dict
[
'company_name'
]
=
None
if
registration_code
.
invoice
:
course_registration_dict
[
'company_name'
]
=
getattr
(
registration_code
.
invoice
,
'company_name'
)
if
registration_code
.
invoice
_item
:
course_registration_dict
[
'company_name'
]
=
getattr
(
registration_code
.
invoice
_item
.
invoice
,
'company_name'
)
course_registration_dict
[
'redeemed_by'
]
=
None
if
registration_code
.
invoice
:
sale_invoice
=
Invoice
.
objects
.
get
(
id
=
registration_code
.
invoice_id
)
if
registration_code
.
invoice
_item
:
sale_invoice
=
registration_code
.
invoice_item
.
invoice
course_registration_dict
[
'invoice_id'
]
=
sale_invoice
.
id
course_registration_dict
[
'purchaser'
]
=
sale_invoice
.
recipient_name
course_registration_dict
[
'customer_reference_number'
]
=
sale_invoice
.
customer_reference_number
...
...
lms/djangoapps/instructor_analytics/tests/test_basic.py
View file @
820cc4aa
...
...
@@ -11,7 +11,7 @@ from student.tests.factories import UserFactory, CourseModeFactory
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
shoppingcart.models
import
(
CourseRegistrationCode
,
RegistrationCodeRedemption
,
Order
,
Invoice
,
Coupon
,
CourseRegCodeItem
,
CouponRedemption
Invoice
,
Coupon
,
CourseRegCodeItem
,
CouponRedemption
,
CourseRegistrationCodeInvoiceItem
)
from
course_modes.models
import
CourseMode
from
instructor_analytics.basic
import
(
...
...
@@ -147,10 +147,16 @@ class TestCourseSaleRecordsAnalyticsBasic(ModuleStoreTestCase):
company_contact_email
=
'test@company.com'
,
recipient_name
=
'Testw_1'
,
recipient_email
=
'test2@test.com'
,
customer_reference_number
=
'2Fwe23S'
,
internal_reference
=
"ABC"
,
course_id
=
self
.
course
.
id
)
invoice_item
=
CourseRegistrationCodeInvoiceItem
.
objects
.
create
(
invoice
=
sale_invoice
,
qty
=
1
,
unit_price
=
1234.32
,
course_id
=
self
.
course
.
id
)
for
i
in
range
(
5
):
course_code
=
CourseRegistrationCode
(
code
=
"test_code{}"
.
format
(
i
),
course_id
=
self
.
course
.
id
.
to_deprecated_string
(),
created_by
=
self
.
instructor
,
invoice
=
sale_invoice
,
mode_slug
=
'honor'
created_by
=
self
.
instructor
,
invoice
=
sale_invoice
,
invoice_item
=
invoice_item
,
mode_slug
=
'honor'
)
course_code
.
save
()
...
...
@@ -272,7 +278,7 @@ class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase):
kwargs
=
{
'course_id'
:
self
.
course
.
id
.
to_deprecated_string
()})
data
=
{
'total_registration_codes'
:
12
,
'company_name'
:
'Test Group'
,
'
sale
_price'
:
122.45
,
'total_registration_codes'
:
12
,
'company_name'
:
'Test Group'
,
'
unit
_price'
:
122.45
,
'company_contact_name'
:
'TestName'
,
'company_contact_email'
:
'test@company.com'
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
...
...
@@ -306,11 +312,17 @@ class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase):
)
self
.
assertIn
(
course_registration
[
'company_name'
],
[
getattr
(
registration_code
.
invoice
,
'company_name'
)
for
registration_code
in
registration_codes
]
[
getattr
(
registration_code
.
invoice_item
.
invoice
,
'company_name'
)
for
registration_code
in
registration_codes
]
)
self
.
assertIn
(
course_registration
[
'invoice_id'
],
[
registration_code
.
invoice_id
for
registration_code
in
registration_codes
]
[
registration_code
.
invoice_item
.
invoice_id
for
registration_code
in
registration_codes
]
)
def
test_coupon_codes_features
(
self
):
...
...
lms/djangoapps/shoppingcart/admin.py
View file @
820cc4aa
"""
Allows django admin site to add PaidCourseRegistrationAnnotations
"""
"""Django admin interface for the shopping cart models. """
from
ratelimitbackend
import
admin
from
shoppingcart.models
import
(
PaidCourseRegistrationAnnotation
,
Coupon
,
DonationConfiguration
PaidCourseRegistrationAnnotation
,
Coupon
,
DonationConfiguration
,
Invoice
,
CourseRegistrationCodeInvoiceItem
,
InvoiceTransaction
)
...
...
@@ -49,6 +52,128 @@ class SoftDeleteCouponAdmin(admin.ModelAdmin):
really_delete_selected
.
short_description
=
"Delete s selected entries"
class
CourseRegistrationCodeInvoiceItemInline
(
admin
.
StackedInline
):
"""Admin for course registration code invoice items.
Displayed inline within the invoice admin UI.
"""
model
=
CourseRegistrationCodeInvoiceItem
extra
=
0
can_delete
=
False
readonly_fields
=
(
'qty'
,
'unit_price'
,
'currency'
,
'course_id'
,
)
def
has_add_permission
(
self
,
request
):
return
False
class
InvoiceTransactionInline
(
admin
.
StackedInline
):
"""Admin for invoice transactions.
Displayed inline within the invoice admin UI.
"""
model
=
InvoiceTransaction
extra
=
0
readonly_fields
=
(
'created'
,
'modified'
,
'created_by'
,
'last_modified_by'
)
class
InvoiceAdmin
(
admin
.
ModelAdmin
):
"""Admin for invoices.
This is intended for the internal finance team
to be able to view and update invoice information,
including payments and refunds.
"""
date_hierarchy
=
'created'
can_delete
=
False
readonly_fields
=
(
'created'
,
'modified'
)
search_fields
=
(
'internal_reference'
,
'customer_reference_number'
,
'company_name'
,
)
fieldsets
=
(
(
None
,
{
'fields'
:
(
'internal_reference'
,
'customer_reference_number'
,
'created'
,
'modified'
,
)
}
),
(
'Billing Information'
,
{
'fields'
:
(
'company_name'
,
'company_contact_name'
,
'company_contact_email'
,
'recipient_name'
,
'recipient_email'
,
'address_line_1'
,
'address_line_2'
,
'address_line_3'
,
'city'
,
'state'
,
'zip'
,
'country'
)
}
)
)
readonly_fields
=
(
'internal_reference'
,
'customer_reference_number'
,
'created'
,
'modified'
,
'company_name'
,
'company_contact_name'
,
'company_contact_email'
,
'recipient_name'
,
'recipient_email'
,
'address_line_1'
,
'address_line_2'
,
'address_line_3'
,
'city'
,
'state'
,
'zip'
,
'country'
)
inlines
=
[
CourseRegistrationCodeInvoiceItemInline
,
InvoiceTransactionInline
]
def
save_formset
(
self
,
request
,
form
,
formset
,
change
):
"""Save the user who created and modified invoice transactions. """
instances
=
formset
.
save
(
commit
=
False
)
for
instance
in
instances
:
if
isinstance
(
instance
,
InvoiceTransaction
):
if
not
hasattr
(
instance
,
'created_by'
):
instance
.
created_by
=
request
.
user
instance
.
last_modified_by
=
request
.
user
instance
.
save
()
def
has_add_permission
(
self
,
request
):
return
False
def
has_delete_permission
(
self
,
request
,
obj
=
None
):
return
False
admin
.
site
.
register
(
PaidCourseRegistrationAnnotation
)
admin
.
site
.
register
(
Coupon
,
SoftDeleteCouponAdmin
)
admin
.
site
.
register
(
DonationConfiguration
)
admin
.
site
.
register
(
Invoice
,
InvoiceAdmin
)
lms/djangoapps/shoppingcart/migrations/0025_update_invoice_models.py
0 → 100644
View file @
820cc4aa
# -*- coding: utf-8 -*-
import
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding model 'InvoiceTransaction'
db
.
create_table
(
'shoppingcart_invoicetransaction'
,
(
(
'id'
,
self
.
gf
(
'django.db.models.fields.AutoField'
)(
primary_key
=
True
)),
(
'created'
,
self
.
gf
(
'model_utils.fields.AutoCreatedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'modified'
,
self
.
gf
(
'model_utils.fields.AutoLastModifiedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'invoice'
,
self
.
gf
(
'django.db.models.fields.related.ForeignKey'
)(
to
=
orm
[
'shoppingcart.Invoice'
])),
(
'amount'
,
self
.
gf
(
'django.db.models.fields.DecimalField'
)(
default
=
0.0
,
max_digits
=
30
,
decimal_places
=
2
)),
(
'currency'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
'usd'
,
max_length
=
8
)),
(
'comments'
,
self
.
gf
(
'django.db.models.fields.TextField'
)(
null
=
True
)),
(
'status'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
'started'
,
max_length
=
32
)),
(
'created_by'
,
self
.
gf
(
'django.db.models.fields.related.ForeignKey'
)(
to
=
orm
[
'auth.User'
])),
(
'last_modified_by'
,
self
.
gf
(
'django.db.models.fields.related.ForeignKey'
)(
related_name
=
'last_modified_by_user'
,
to
=
orm
[
'auth.User'
])),
))
db
.
send_create_signal
(
'shoppingcart'
,
[
'InvoiceTransaction'
])
# Adding model 'InvoiceItem'
db
.
create_table
(
'shoppingcart_invoiceitem'
,
(
(
'id'
,
self
.
gf
(
'django.db.models.fields.AutoField'
)(
primary_key
=
True
)),
(
'created'
,
self
.
gf
(
'model_utils.fields.AutoCreatedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'modified'
,
self
.
gf
(
'model_utils.fields.AutoLastModifiedField'
)(
default
=
datetime
.
datetime
.
now
)),
(
'invoice'
,
self
.
gf
(
'django.db.models.fields.related.ForeignKey'
)(
to
=
orm
[
'shoppingcart.Invoice'
])),
(
'qty'
,
self
.
gf
(
'django.db.models.fields.IntegerField'
)(
default
=
1
)),
(
'unit_price'
,
self
.
gf
(
'django.db.models.fields.DecimalField'
)(
default
=
0.0
,
max_digits
=
30
,
decimal_places
=
2
)),
(
'currency'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
'usd'
,
max_length
=
8
)),
))
db
.
send_create_signal
(
'shoppingcart'
,
[
'InvoiceItem'
])
# Adding model 'CourseRegistrationCodeInvoiceItem'
db
.
create_table
(
'shoppingcart_courseregistrationcodeinvoiceitem'
,
(
(
'invoiceitem_ptr'
,
self
.
gf
(
'django.db.models.fields.related.OneToOneField'
)(
to
=
orm
[
'shoppingcart.InvoiceItem'
],
unique
=
True
,
primary_key
=
True
)),
(
'course_id'
,
self
.
gf
(
'xmodule_django.models.CourseKeyField'
)(
max_length
=
128
,
db_index
=
True
)),
))
db
.
send_create_signal
(
'shoppingcart'
,
[
'CourseRegistrationCodeInvoiceItem'
])
# Adding field 'CourseRegistrationCode.invoice_item'
db
.
add_column
(
'shoppingcart_courseregistrationcode'
,
'invoice_item'
,
self
.
gf
(
'django.db.models.fields.related.ForeignKey'
)(
to
=
orm
[
'shoppingcart.CourseRegistrationCodeInvoiceItem'
],
null
=
True
),
keep_default
=
True
)
# Adding field 'Invoice.created'
db
.
add_column
(
'shoppingcart_invoice'
,
'created'
,
self
.
gf
(
'model_utils.fields.AutoCreatedField'
)(
default
=
datetime
.
datetime
.
now
),
keep_default
=
True
)
# Adding field 'Invoice.modified'
db
.
add_column
(
'shoppingcart_invoice'
,
'modified'
,
self
.
gf
(
'model_utils.fields.AutoLastModifiedField'
)(
default
=
datetime
.
datetime
.
now
),
keep_default
=
True
)
def
backwards
(
self
,
orm
):
# Deleting model 'InvoiceTransaction'
db
.
delete_table
(
'shoppingcart_invoicetransaction'
)
# Deleting model 'InvoiceItem'
db
.
delete_table
(
'shoppingcart_invoiceitem'
)
# Deleting model 'CourseRegistrationCodeInvoiceItem'
db
.
delete_table
(
'shoppingcart_courseregistrationcodeinvoiceitem'
)
# Deleting field 'CourseRegistrationCode.invoice_item'
db
.
delete_column
(
'shoppingcart_courseregistrationcode'
,
'invoice_item_id'
)
# Deleting field 'Invoice.created'
db
.
delete_column
(
'shoppingcart_invoice'
,
'created'
)
# Deleting field 'Invoice.modified'
db
.
delete_column
(
'shoppingcart_invoice'
,
'modified'
)
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
'shoppingcart.certificateitem'
:
{
'Meta'
:
{
'object_name'
:
'CertificateItem'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_enrollment'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['student.CourseEnrollment']"
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.SlugField'
,
[],
{
'max_length'
:
'50'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.coupon'
:
{
'Meta'
:
{
'object_name'
:
'Coupon'
},
'code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime(2015, 1, 27, 0, 0)'
}),
'created_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'expiration_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'percentage_discount'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'0'
})
},
'shoppingcart.couponredemption'
:
{
'Meta'
:
{
'object_name'
:
'CouponRedemption'
},
'coupon'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Coupon']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Order']"
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'shoppingcart.courseregcodeitem'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegCodeItem'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.SlugField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'50'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.courseregcodeitemannotation'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegCodeItemAnnotation'
},
'annotation'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'shoppingcart.courseregistrationcode'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegistrationCode'
},
'code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime(2015, 1, 27, 0, 0)'
}),
'created_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'created_by_user'"
,
'to'
:
"orm['auth.User']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'invoice'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Invoice']"
,
'null'
:
'True'
}),
'invoice_item'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.CourseRegistrationCodeInvoiceItem']"
,
'null'
:
'True'
}),
'mode_slug'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'purchase_order'"
,
'null'
:
'True'
,
'to'
:
"orm['shoppingcart.Order']"
})
},
'shoppingcart.courseregistrationcodeinvoiceitem'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegistrationCodeInvoiceItem'
,
'_ormbases'
:
[
'shoppingcart.InvoiceItem'
]},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'invoiceitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.InvoiceItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.donation'
:
{
'Meta'
:
{
'object_name'
:
'Donation'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'donation_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'general'"
,
'max_length'
:
'32'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.donationconfiguration'
:
{
'Meta'
:
{
'object_name'
:
'DonationConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'shoppingcart.invoice'
:
{
'Meta'
:
{
'object_name'
:
'Invoice'
},
'address_line_1'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'address_line_2'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'address_line_3'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'city'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
}),
'company_contact_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'company_contact_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'company_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'country'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'customer_reference_number'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'63'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'internal_reference'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'is_valid'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'recipient_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'recipient_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
}),
'total_amount'
:
(
'django.db.models.fields.FloatField'
,
[],
{}),
'zip'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'15'
,
'null'
:
'True'
})
},
'shoppingcart.invoiceitem'
:
{
'Meta'
:
{
'object_name'
:
'InvoiceItem'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'invoice'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Invoice']"
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'qty'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'1'
}),
'unit_price'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
})
},
'shoppingcart.invoicetransaction'
:
{
'Meta'
:
{
'object_name'
:
'InvoiceTransaction'
},
'amount'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'comments'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'created_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'invoice'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Invoice']"
}),
'last_modified_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'last_modified_by_user'"
,
'to'
:
"orm['auth.User']"
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'started'"
,
'max_length'
:
'32'
})
},
'shoppingcart.order'
:
{
'Meta'
:
{
'object_name'
:
'Order'
},
'bill_to_cardtype'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
,
'blank'
:
'True'
}),
'bill_to_ccnum'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'8'
,
'blank'
:
'True'
}),
'bill_to_city'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_country'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_first'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_last'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_postalcode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'16'
,
'blank'
:
'True'
}),
'bill_to_state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'8'
,
'blank'
:
'True'
}),
'bill_to_street1'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
,
'blank'
:
'True'
}),
'bill_to_street2'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
,
'blank'
:
'True'
}),
'company_contact_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'company_contact_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'company_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'customer_reference_number'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'63'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'order_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'personal'"
,
'max_length'
:
'32'
}),
'processor_reply_dump'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'purchase_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'recipient_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'recipient_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'refunded_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'cart'"
,
'max_length'
:
'32'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'shoppingcart.orderitem'
:
{
'Meta'
:
{
'object_name'
:
'OrderItem'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'fulfilled_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'line_desc'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'Misc. Item'"
,
'max_length'
:
'1024'
}),
'list_price'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'null'
:
'True'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Order']"
}),
'qty'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'1'
}),
'refund_requested_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'db_index'
:
'True'
}),
'report_comments'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"''"
}),
'service_fee'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'cart'"
,
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'unit_cost'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'shoppingcart.paidcourseregistration'
:
{
'Meta'
:
{
'object_name'
:
'PaidCourseRegistration'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_enrollment'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['student.CourseEnrollment']"
,
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.SlugField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'50'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.paidcourseregistrationannotation'
:
{
'Meta'
:
{
'object_name'
:
'PaidCourseRegistrationAnnotation'
},
'annotation'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'shoppingcart.registrationcoderedemption'
:
{
'Meta'
:
{
'object_name'
:
'RegistrationCodeRedemption'
},
'course_enrollment'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['student.CourseEnrollment']"
,
'null'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Order']"
,
'null'
:
'True'
}),
'redeemed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime(2015, 1, 27, 0, 0)'
,
'null'
:
'True'
}),
'redeemed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'registration_code'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.CourseRegistrationCode']"
})
},
'student.courseenrollment'
:
{
'Meta'
:
{
'ordering'
:
"('user', 'course_id')"
,
'unique_together'
:
"(('user', 'course_id'),)"
,
'object_name'
:
'CourseEnrollment'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'null'
:
'True'
,
'db_index'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'100'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
}
}
complete_apps
=
[
'shoppingcart'
]
\ No newline at end of file
lms/djangoapps/shoppingcart/migrations/0026_migrate_invoices.py
0 → 100644
View file @
820cc4aa
# -*- coding: utf-8 -*-
import
datetime
from
south.db
import
db
from
south.v2
import
DataMigration
from
django.db
import
models
from
decimal
import
Decimal
,
ROUND_DOWN
class
Migration
(
DataMigration
):
def
forwards
(
self
,
orm
):
# Select all the invoices and number of registration codes(as qty) associated with every invoice
invoices
=
orm
.
Invoice
.
objects
.
extra
(
select
=
{
'qty'
:
'SELECT COUNT(*) FROM shoppingcart_courseregistrationcode '
'WHERE shoppingcart_courseregistrationcode.invoice_id = shoppingcart_invoice.id'
}
)
.
all
()
for
invoice
in
invoices
:
invoice_item
=
self
.
_create_invoice_item
(
invoice
,
orm
)
orm
.
CourseRegistrationCode
.
objects
.
filter
(
invoice
=
invoice
)
.
update
(
invoice_item
=
invoice_item
)
def
backwards
(
self
,
orm
):
"""
We don't need the backward migration because the data is already there in old models and
schema rollback will automatically remove this new data.
"""
pass
@staticmethod
def
_create_invoice_item
(
invoice
,
orm
):
unit_price
=
((
Decimal
(
invoice
.
total_amount
))
/
invoice
.
qty
)
.
quantize
(
Decimal
(
'.01'
),
rounding
=
ROUND_DOWN
)
invoice_item
=
orm
.
CourseRegistrationCodeInvoiceItem
.
objects
.
create
(
invoice
=
invoice
,
qty
=
invoice
.
qty
,
unit_price
=
unit_price
,
course_id
=
invoice
.
course_id
)
return
invoice_item
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
'shoppingcart.certificateitem'
:
{
'Meta'
:
{
'object_name'
:
'CertificateItem'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_enrollment'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['student.CourseEnrollment']"
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.SlugField'
,
[],
{
'max_length'
:
'50'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.coupon'
:
{
'Meta'
:
{
'object_name'
:
'Coupon'
},
'code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime(2015, 1, 27, 0, 0)'
}),
'created_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'description'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'expiration_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'percentage_discount'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'0'
})
},
'shoppingcart.couponredemption'
:
{
'Meta'
:
{
'object_name'
:
'CouponRedemption'
},
'coupon'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Coupon']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Order']"
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'shoppingcart.courseregcodeitem'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegCodeItem'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.SlugField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'50'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.courseregcodeitemannotation'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegCodeItemAnnotation'
},
'annotation'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'shoppingcart.courseregistrationcode'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegistrationCode'
},
'code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime(2015, 1, 27, 0, 0)'
}),
'created_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'created_by_user'"
,
'to'
:
"orm['auth.User']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'invoice'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Invoice']"
,
'null'
:
'True'
}),
'invoice_item'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.CourseRegistrationCodeInvoiceItem']"
,
'null'
:
'True'
}),
'mode_slug'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'purchase_order'"
,
'null'
:
'True'
,
'to'
:
"orm['shoppingcart.Order']"
})
},
'shoppingcart.courseregistrationcodeinvoiceitem'
:
{
'Meta'
:
{
'object_name'
:
'CourseRegistrationCodeInvoiceItem'
,
'_ormbases'
:
[
'shoppingcart.InvoiceItem'
]},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'invoiceitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.InvoiceItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.donation'
:
{
'Meta'
:
{
'object_name'
:
'Donation'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'donation_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'general'"
,
'max_length'
:
'32'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.donationconfiguration'
:
{
'Meta'
:
{
'object_name'
:
'DonationConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'shoppingcart.invoice'
:
{
'Meta'
:
{
'object_name'
:
'Invoice'
},
'address_line_1'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'address_line_2'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'address_line_3'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'city'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
}),
'company_contact_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'company_contact_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'company_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'country'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'customer_reference_number'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'63'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'internal_reference'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'is_valid'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'recipient_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'recipient_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
}),
'total_amount'
:
(
'django.db.models.fields.FloatField'
,
[],
{}),
'zip'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'15'
,
'null'
:
'True'
})
},
'shoppingcart.invoiceitem'
:
{
'Meta'
:
{
'object_name'
:
'InvoiceItem'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'invoice'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Invoice']"
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'qty'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'1'
}),
'unit_price'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
})
},
'shoppingcart.invoicetransaction'
:
{
'Meta'
:
{
'object_name'
:
'InvoiceTransaction'
},
'amount'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'comments'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'created_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'invoice'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Invoice']"
}),
'last_modified_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'last_modified_by_user'"
,
'to'
:
"orm['auth.User']"
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'started'"
,
'max_length'
:
'32'
})
},
'shoppingcart.order'
:
{
'Meta'
:
{
'object_name'
:
'Order'
},
'bill_to_cardtype'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
,
'blank'
:
'True'
}),
'bill_to_ccnum'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'8'
,
'blank'
:
'True'
}),
'bill_to_city'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_country'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_first'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_last'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'blank'
:
'True'
}),
'bill_to_postalcode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'16'
,
'blank'
:
'True'
}),
'bill_to_state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'8'
,
'blank'
:
'True'
}),
'bill_to_street1'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
,
'blank'
:
'True'
}),
'bill_to_street2'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
,
'blank'
:
'True'
}),
'company_contact_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'company_contact_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'company_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'customer_reference_number'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'63'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'order_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'personal'"
,
'max_length'
:
'32'
}),
'processor_reply_dump'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'purchase_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'recipient_email'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'recipient_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'refunded_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'cart'"
,
'max_length'
:
'32'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'shoppingcart.orderitem'
:
{
'Meta'
:
{
'object_name'
:
'OrderItem'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'currency'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'usd'"
,
'max_length'
:
'8'
}),
'fulfilled_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'line_desc'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'Misc. Item'"
,
'max_length'
:
'1024'
}),
'list_price'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'null'
:
'True'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Order']"
}),
'qty'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'1'
}),
'refund_requested_time'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'db_index'
:
'True'
}),
'report_comments'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"''"
}),
'service_fee'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'cart'"
,
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'unit_cost'
:
(
'django.db.models.fields.DecimalField'
,
[],
{
'default'
:
'0.0'
,
'max_digits'
:
'30'
,
'decimal_places'
:
'2'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'shoppingcart.paidcourseregistration'
:
{
'Meta'
:
{
'object_name'
:
'PaidCourseRegistration'
,
'_ormbases'
:
[
'shoppingcart.OrderItem'
]},
'course_enrollment'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['student.CourseEnrollment']"
,
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.SlugField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'50'
}),
'orderitem_ptr'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
"orm['shoppingcart.OrderItem']"
,
'unique'
:
'True'
,
'primary_key'
:
'True'
})
},
'shoppingcart.paidcourseregistrationannotation'
:
{
'Meta'
:
{
'object_name'
:
'PaidCourseRegistrationAnnotation'
},
'annotation'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'128'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'shoppingcart.registrationcoderedemption'
:
{
'Meta'
:
{
'object_name'
:
'RegistrationCodeRedemption'
},
'course_enrollment'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['student.CourseEnrollment']"
,
'null'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'order'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.Order']"
,
'null'
:
'True'
}),
'redeemed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime(2015, 1, 27, 0, 0)'
,
'null'
:
'True'
}),
'redeemed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'registration_code'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['shoppingcart.CourseRegistrationCode']"
})
},
'student.courseenrollment'
:
{
'Meta'
:
{
'ordering'
:
"('user', 'course_id')"
,
'unique_together'
:
"(('user', 'course_id'),)"
,
'object_name'
:
'CourseEnrollment'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'null'
:
'True'
,
'db_index'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'mode'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'honor'"
,
'max_length'
:
'100'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
}
}
complete_apps
=
[
'shoppingcart'
]
symmetrical
=
True
lms/djangoapps/shoppingcart/models.py
View file @
820cc4aa
...
...
@@ -18,7 +18,7 @@ from django.conf import settings
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.mail
import
send_mail
from
django.contrib.auth.models
import
User
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
,
ugettext_lazy
from
django.db
import
transaction
from
django.db.models
import
Sum
from
django.core.urlresolvers
import
reverse
...
...
@@ -773,7 +773,7 @@ class OrderItem(TimeStampedModel):
self
.
save
()
class
Invoice
(
models
.
Model
):
class
Invoice
(
TimeStamped
Model
):
"""
This table capture all the information needed to support "invoicing"
which is when a user wants to purchase Registration Codes,
...
...
@@ -785,16 +785,39 @@ class Invoice(models.Model):
recipient_name
=
models
.
CharField
(
max_length
=
255
)
recipient_email
=
models
.
CharField
(
max_length
=
255
)
address_line_1
=
models
.
CharField
(
max_length
=
255
)
address_line_2
=
models
.
CharField
(
max_length
=
255
,
null
=
True
)
address_line_3
=
models
.
CharField
(
max_length
=
255
,
null
=
True
)
address_line_2
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
)
address_line_3
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
)
city
=
models
.
CharField
(
max_length
=
255
,
null
=
True
)
state
=
models
.
CharField
(
max_length
=
255
,
null
=
True
)
zip
=
models
.
CharField
(
max_length
=
15
,
null
=
True
)
country
=
models
.
CharField
(
max_length
=
64
,
null
=
True
)
course_id
=
CourseKeyField
(
max_length
=
255
,
db_index
=
True
)
# This field has been deprecated.
# The total amount can now be calculated as the sum
# of each invoice item associated with the invoice.
# For backwards compatibility, this field is maintained
# and written to during invoice creation.
total_amount
=
models
.
FloatField
()
internal_reference
=
models
.
CharField
(
max_length
=
255
,
null
=
True
)
customer_reference_number
=
models
.
CharField
(
max_length
=
63
,
null
=
True
)
# This field has been deprecated in order to support
# invoices for items that are not course-related.
# Although this field is still maintained for backwards
# compatibility, you should use CourseRegistrationCodeInvoiceItem
# to look up the course ID for purchased redeem codes.
course_id
=
CourseKeyField
(
max_length
=
255
,
db_index
=
True
)
internal_reference
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
,
help_text
=
ugettext_lazy
(
"Internal reference code for this invoice."
)
)
customer_reference_number
=
models
.
CharField
(
max_length
=
63
,
null
=
True
,
blank
=
True
,
help_text
=
ugettext_lazy
(
"Customer's reference code for this invoice."
)
)
is_valid
=
models
.
BooleanField
(
default
=
True
)
def
generate_pdf_invoice
(
self
,
course
,
course_price
,
quantity
,
sale_price
):
...
...
@@ -824,6 +847,125 @@ class Invoice(models.Model):
return
pdf_buffer
def
__unicode__
(
self
):
label
=
(
unicode
(
self
.
internal_reference
)
if
self
.
internal_reference
else
u"No label"
)
created
=
(
self
.
created
.
strftime
(
"
%
Y-
%
m-
%
d"
)
# pylint: disable=no-member
if
self
.
created
else
u"No date"
)
return
u"{label} ({date_created})"
.
format
(
label
=
label
,
date_created
=
created
)
INVOICE_TRANSACTION_STATUSES
=
(
# A payment/refund is in process, but money has not yet been transferred
(
'started'
,
'started'
),
# A payment/refund has completed successfully
# This should be set ONLY once money has been successfully exchanged.
(
'completed'
,
'completed'
),
# A payment/refund was promised, but was cancelled before
# money had been transferred. An example would be
# cancelling a refund check before the recipient has
# a chance to deposit it.
(
'cancelled'
,
'cancelled'
)
)
class
InvoiceTransaction
(
TimeStampedModel
):
"""Record payment and refund information for invoices.
There are two expected use cases:
1) We send an invoice to someone, and they send us a check.
We then manually create an invoice transaction to represent
the payment.
2) We send an invoice to someone, and they pay us. Later, we
need to issue a refund for the payment. We manually
create a transaction with a negative amount to represent
the refund.
"""
invoice
=
models
.
ForeignKey
(
Invoice
)
amount
=
models
.
DecimalField
(
default
=
0.0
,
decimal_places
=
2
,
max_digits
=
30
,
help_text
=
ugettext_lazy
(
"The amount of the transaction. Use positive amounts for payments"
" and negative amounts for refunds."
)
)
currency
=
models
.
CharField
(
default
=
"usd"
,
max_length
=
8
,
help_text
=
ugettext_lazy
(
"Lower-case ISO currency codes"
)
)
comments
=
models
.
TextField
(
null
=
True
,
blank
=
True
,
help_text
=
ugettext_lazy
(
"Optional: provide additional information for this transaction"
)
)
status
=
models
.
CharField
(
max_length
=
32
,
default
=
'started'
,
choices
=
INVOICE_TRANSACTION_STATUSES
,
help_text
=
ugettext_lazy
(
"The status of the payment or refund. "
"'started' means that payment is expected, but money has not yet been transferred. "
"'completed' means that the payment or refund was received. "
"'cancelled' means that payment or refund was expected, but was cancelled before money was transferred. "
)
)
created_by
=
models
.
ForeignKey
(
User
)
last_modified_by
=
models
.
ForeignKey
(
User
,
related_name
=
'last_modified_by_user'
)
class
InvoiceItem
(
TimeStampedModel
):
"""
This is the basic interface for invoice items.
Each invoice item represents a "line" in the invoice.
For example, in an invoice for course registration codes,
there might be an invoice item representing 10 registration
codes for the DemoX course.
"""
objects
=
InheritanceManager
()
invoice
=
models
.
ForeignKey
(
Invoice
,
db_index
=
True
)
qty
=
models
.
IntegerField
(
default
=
1
,
help_text
=
ugettext_lazy
(
"The number of items sold."
)
)
unit_price
=
models
.
DecimalField
(
default
=
0.0
,
decimal_places
=
2
,
max_digits
=
30
,
help_text
=
ugettext_lazy
(
"The price per item sold, including discounts."
)
)
currency
=
models
.
CharField
(
default
=
"usd"
,
max_length
=
8
,
help_text
=
ugettext_lazy
(
"Lower-case ISO currency codes"
)
)
class
CourseRegistrationCodeInvoiceItem
(
InvoiceItem
):
"""
This is an invoice item that represents a payment for
a course registration.
"""
course_id
=
CourseKeyField
(
max_length
=
128
,
db_index
=
True
)
class
CourseRegistrationCode
(
models
.
Model
):
"""
...
...
@@ -835,9 +977,14 @@ class CourseRegistrationCode(models.Model):
created_by
=
models
.
ForeignKey
(
User
,
related_name
=
'created_by_user'
)
created_at
=
models
.
DateTimeField
(
default
=
datetime
.
now
(
pytz
.
utc
))
order
=
models
.
ForeignKey
(
Order
,
db_index
=
True
,
null
=
True
,
related_name
=
"purchase_order"
)
invoice
=
models
.
ForeignKey
(
Invoice
,
null
=
True
)
mode_slug
=
models
.
CharField
(
max_length
=
100
,
null
=
True
)
# For backwards compatibility, we maintain the FK to "invoice"
# In the future, we will remove this in favor of the FK
# to "invoice_item" (which can be used to look up the invoice).
invoice
=
models
.
ForeignKey
(
Invoice
,
null
=
True
)
invoice_item
=
models
.
ForeignKey
(
CourseRegistrationCodeInvoiceItem
,
null
=
True
)
class
RegistrationCodeRedemption
(
models
.
Model
):
"""
...
...
@@ -1227,7 +1374,7 @@ class CourseRegCodeItem(OrderItem):
# is in another PR (for another feature)
from
instructor.views.api
import
save_registration_code
for
i
in
range
(
total_registration_codes
):
# pylint: disable=unused-variable
save_registration_code
(
self
.
user
,
self
.
course_id
,
self
.
mode
,
invoice
=
None
,
order
=
self
.
order
)
save_registration_code
(
self
.
user
,
self
.
course_id
,
self
.
mode
,
order
=
self
.
order
)
log
.
info
(
"Enrolled {0} in paid course {1}, paid ${2}"
.
format
(
self
.
user
.
email
,
self
.
course_id
,
self
.
line_cost
))
# pylint: disable=no-member
...
...
lms/djangoapps/shoppingcart/tests/test_views.py
View file @
820cc4aa
...
...
@@ -1518,7 +1518,7 @@ class RegistrationCodeRedemptionCourseEnrollment(ModuleStoreTestCase):
data
=
{
'total_registration_codes'
:
12
,
'company_name'
:
'Test Group'
,
'company_contact_name'
:
'Test@company.com'
,
'company_contact_email'
:
'Test@company.com'
,
'
sale
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'company_contact_email'
:
'Test@company.com'
,
'
unit
_price'
:
122.45
,
'recipient_name'
:
'Test123'
,
'recipient_email'
:
'test@123.com'
,
'address_line_1'
:
'Portland Street'
,
'address_line_2'
:
''
,
'address_line_3'
:
''
,
'city'
:
''
,
'state'
:
''
,
'zip'
:
''
,
'country'
:
''
,
'customer_reference_number'
:
'123A23F'
,
'internal_reference'
:
''
,
'invoice'
:
''
...
...
lms/static/sass/course/instructor/_instructor_2.scss
View file @
820cc4aa
...
...
@@ -1664,7 +1664,7 @@ input[name="subject"] {
height
:
auto
;
}
}
li
#generate-registration-modal-field-country
~
li
#generate-registration-modal-field-
total
-price
,
li
#generate-registration-modal-field-country
~
li
#generate-registration-modal-field-
unit
-price
,
li
#generate-registration-modal-field-country
~
li
#generate-registration-modal-field-internal-reference
{
@include
margin-left
(
0px
!
important
);
@include
margin-right
(
15px
!
important
);
...
...
lms/templates/instructor/instructor_dashboard_2/e-commerce.html
View file @
820cc4aa
...
...
@@ -296,7 +296,7 @@
var
total_registration_codes
=
$
(
'input[name="total_registration_codes"]'
).
val
();
var
recipient_name
=
$
(
'input[name="recipient_name"]'
).
val
();
var
recipient_email
=
$
(
'input[name="recipient_email"]'
).
val
();
var
sale_price
=
$
(
'input[name="sale
_price"]'
).
val
();
var
unit_price
=
$
(
'input[name="unit
_price"]'
).
val
();
var
company_name
=
$
(
'input[name="company_name"]'
).
val
();
var
company_contact_name
=
$
(
'input[name="company_contact_name"]'
).
val
();
var
company_contact_email
=
$
(
'input[name="company_contact_email"]'
).
val
();
...
...
@@ -305,91 +305,91 @@
if
(
company_name
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the company name'
);
registration_code_error
.
text
(
"${_('Please enter the company name')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
((
$
.
isNumeric
(
company_name
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the non-numeric value for company name'
);
registration_code_error
.
text
(
"${_('Please enter the non-numeric value for company name')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
company_contact_name
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the company contact name'
);
registration_code_error
.
text
(
"${_('Please enter the company contact name')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
((
$
.
isNumeric
(
company_contact_name
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the non-numeric value for company contact name'
);
registration_code_error
.
text
(
"${_('Please enter the non-numeric value for company contact name')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
company_contact_email
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the company contact email'
);
registration_code_error
.
text
(
"${_('Please enter the company contact email')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
!
(
validateEmail
(
company_contact_email
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the valid email address'
);
registration_code_error
.
text
(
"${_('Please enter the valid email address')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
recipient_name
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the recipient name'
);
registration_code_error
.
text
(
"${_('Please enter the recipient name')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
((
$
.
isNumeric
(
recipient_name
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the non-numeric value for recipient name'
);
registration_code_error
.
text
(
"${_('Please enter the non-numeric value for recipient name')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
recipient_email
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the recipient email'
);
registration_code_error
.
text
(
"${_('Please enter the recipient email')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
!
(
validateEmail
(
recipient_email
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the valid email address'
);
registration_code_error
.
text
(
"${_('Please enter the valid email address')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
address_line
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the billing address'
);
registration_code_error
.
text
(
"${_('Please enter the billing address')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
if
(
sale
_price
==
''
)
{
if
(
unit
_price
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the sale price'
);
registration_code_error
.
text
(
"${_('Please enter the unit price')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
}
if
(
!
(
$
.
isNumeric
(
sale
_price
)))
{
if
(
!
(
$
.
isNumeric
(
unit
_price
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the numeric value for sale price'
);
registration_code_error
.
text
(
"${_('Please enter the numeric value for unit price')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
}
if
(
total_registration_codes
==
''
)
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the total registration codes'
);
registration_code_error
.
text
(
"${_('Please enter the number of enrollment codes')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
}
if
(
!
(
$
.
isNumeric
(
total_registration_codes
)))
{
registration_code_error
.
attr
(
'style'
,
'display: block !important'
);
registration_code_error
.
text
(
'Please enter the numeric value for total registration codes'
);
registration_code_error
.
text
(
"${_('Please enter the numeric value for number of enrollment codes')}"
);
generate_registration_button
.
removeAttr
(
'disabled'
);
return
false
;
}
...
...
@@ -600,7 +600,7 @@
$
(
'input[name="country"]'
).
val
(
''
);
$
(
'input[name="customer_reference_number"]'
).
val
(
''
);
$
(
'input[name="recipient_name"]'
).
val
(
''
);
$
(
'input[name="
sale
_price"]'
).
val
(
''
);
$
(
'input[name="
unit
_price"]'
).
val
(
''
);
$
(
'input[name="recipient_email"]'
).
val
(
''
);
$
(
'input[name="company_contact_name"]'
).
val
(
''
);
$
(
'input[name="company_contact_email"]'
).
val
(
''
);
...
...
lms/templates/instructor/instructor_dashboard_2/generate_registarion_codes_modal.html
View file @
820cc4aa
...
...
@@ -102,12 +102,12 @@
</span>
</li>
<div
class=
"clearfix"
></div>
<li
class=
"field required text"
id=
"generate-registration-modal-field-
total
-price"
>
<label
for=
"id_
sale_price"
class=
"required text"
>
${_("Sale
Price")}
</label>
<input
class=
"field required"
id=
"id_
sale_price"
type=
"text"
name=
"sale
_price"
<li
class=
"field required text"
id=
"generate-registration-modal-field-
unit
-price"
>
<label
for=
"id_
unit_price"
class=
"required text"
>
${_("Unit
Price")}
</label>
<input
class=
"field required"
id=
"id_
unit_price"
type=
"text"
name=
"unit
_price"
aria-required=
"true"
/>
<span
class=
"tip-text"
>
${_("The
total price for all enrollments
purchased")}
${_("The
price per enrollment
purchased")}
</span>
</li>
<li
class=
"field required text"
id=
"generate-registration-modal-field-total-codes"
>
...
...
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