Commit 99e8596f by Julia Hansbrough

Response to CR

parent 893acc57
......@@ -581,9 +581,15 @@ class CourseEnrollment(models.Model):
)
@classmethod
def enrollments_in(cls, course_id):
"""Return a queryset of CourseEnrollment for every active enrollment in the course."""
return cls.objects.filter(course_id=course_id, is_active=True,)
def enrollments_in(cls, course_id, mode=None):
"""
Return a queryset of CourseEnrollment for every active enrollment in the course course_id.
Returns only CourseEnrollments with the given mode, if a mode is supplied by the caller.
"""
if mode is None:
return cls.objects.filter(course_id=course_id, is_active=True,)
else:
return cls.objects.filter(course_id=course_id, is_active=True, mode=mode)
def activate(self):
"""Makes this `CourseEnrollment` record active. Saves immediately."""
......
......@@ -205,13 +205,13 @@ class OrderItem(models.Model):
# this is denormalized, but convenient for SQL queries for reports, etc. user should always be = order.user
user = models.ForeignKey(User, db_index=True)
# this is denormalized, but convenient for SQL queries for reports, etc. status should always be = order.status
status = models.CharField(max_length=32, default='cart', choices=ORDER_STATUSES)
status = models.CharField(max_length=32, default='cart', choices=ORDER_STATUSES, db_index=True)
qty = models.IntegerField(default=1)
unit_cost = models.DecimalField(default=0.0, decimal_places=2, max_digits=30)
line_desc = models.CharField(default="Misc. Item", max_length=1024)
currency = models.CharField(default="usd", max_length=8) # lower case ISO currency codes
fulfilled_time = models.DateTimeField(null=True)
refund_requested_time = models.DateTimeField(null=True)
fulfilled_time = models.DateTimeField(null=True, db_index=True)
refund_requested_time = models.DateTimeField(null=True, db_index=True)
service_fee = models.DecimalField(default=0.0, decimal_places=2, max_digits=30)
# general purpose field, not user-visible. Used for reporting
report_comments = models.TextField(default="")
......@@ -568,3 +568,8 @@ class CertificateItem(OrderItem):
"Please include your order number in your e-mail. "
"Please do NOT include your credit card information.").format(
billing_email=settings.PAYMENT_SUPPORT_EMAIL)
@classmethod
def verified_certificates_in(cls, course_id, status):
"""Return a queryset of CertificateItem for every verified enrollment in course_id with the given status."""
return CertificateItem.objects.filter(course_id=course_id, mode='verified', status=status)
......@@ -356,32 +356,47 @@ class ItemizedPurchaseReportTest(ModuleStoreTestCase):
self.cart.purchase()
self.now = datetime.datetime.now(pytz.UTC)
# We can't modify the values returned by report_row_generator directly, since it's a generator, but
# we need the times on CORRECT_CSV and the generated report to match. So, we extract the times from
# the report_row_generator and place them in CORRECT_CSV.
self.time_str = {}
report = initialize_report("itemized_purchase_report")
purchases = report.report_row_generator(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
num_of_item = 0
for item in purchases:
num_of_item += 1
self.time_str[num_of_item] = item[0]
self.CORRECT_CSV = dedent("""
Purchase Time,Order ID,Status,Quantity,Unit Cost,Total Cost,Currency,Description,Comments
{time_str1},1,purchased,1,40,40,usd,Registration for Course: Robot Super Course,Ba\xc3\xbc\xe5\x8c\x85
{time_str2},1,purchased,1,40,40,usd,"Certificate of Achievement, verified cert for course Robot Super Course",
""".format(time_str1=str(self.time_str[1]), time_str2=str(self.time_str[2])))
def test_purchased_items_btw_dates(self):
report = initialize_report("itemized_purchase_report")
purchases = report.get_report_data(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
self.assertEqual(len(purchases), 2)
self.assertIn(self.reg.orderitem_ptr, purchases)
self.assertIn(self.cert_item.orderitem_ptr, purchases)
no_purchases = report.get_report_data(self.now + self.FIVE_MINS, self.now + self.FIVE_MINS + self.FIVE_MINS)
self.assertFalse(no_purchases)
purchases = report.report_row_generator(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
test_time = datetime.datetime.now(pytz.UTC)
# since there's not many purchases, just run through the generator to make sure we've got the right number
num_purchases = 0
for item in purchases:
num_purchases += 1
self.assertEqual(num_purchases, 2)
#self.assertIn(self.reg.orderitem_ptr, purchases)
#self.assertIn(self.cert_item.orderitem_ptr, purchases)
CORRECT_CSV = dedent("""
Purchase Time,Order ID,Status,Quantity,Unit Cost,Total Cost,Currency,Description,Comments
{time_str},1,purchased,1,40,40,usd,Registration for Course: Robot Super Course,Ba\xc3\xbc\xe5\x8c\x85
{time_str},1,purchased,1,40,40,usd,"Certificate of Achievement, verified cert for course Robot Super Course",
""".format(time_str=str(test_time)))
no_purchases = report.report_row_generator(self.now + self.FIVE_MINS, self.now + self.FIVE_MINS + self.FIVE_MINS)
num_purchases = 0
for item in no_purchases:
num_purchases +=1
self.assertEqual(num_purchases, 0)
def test_purchased_csv(self):
"""
Tests that a generated purchase report CSV is as we expect
"""
report = initialize_report("itemized_purchase_report")
for item in report.get_report_data(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS):
item.fulfilled_time = self.test_time
item.save()
csv_file = StringIO.StringIO()
report.make_report(csv_file, self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
csv = csv_file.getvalue()
......
......@@ -29,44 +29,36 @@ class ReportTypeTests(ModuleStoreTestCase):
def setUp(self):
# Need to make a *lot* of users for this one
self.user1 = UserFactory.create()
self.user1.first_name = "John"
self.user1.last_name = "Doe"
self.user1.save()
self.user1.profile.name = "John Doe"
self.user1.profile.save()
self.user2 = UserFactory.create()
self.user2.first_name = "Jane"
self.user2.last_name = "Deer"
self.user2.save()
self.user2.profile.name = "Jane Deer"
self.user2.profile.save()
self.user3 = UserFactory.create()
self.user3.first_name = "Joe"
self.user3.last_name = "Miller"
self.user3.save()
self.user3.profile.name = "Joe Miller"
self.user3.profile.save()
self.user4 = UserFactory.create()
self.user4.first_name = "Simon"
self.user4.last_name = "Blackquill"
self.user4.save()
self.user4.profile.name = "Simon Blackquill"
self.user4.profile.save()
self.user5 = UserFactory.create()
self.user5.first_name = "Super"
self.user5.last_name = "Mario"
self.user5.save()
self.user5.profile.name = "Super Mario"
self.user5.profile.save()
self.user6 = UserFactory.create()
self.user6.first_name = "Princess"
self.user6.last_name = "Peach"
self.user6.save()
self.user6.profile.name = "Princess Peach"
self.user6.profile.save()
self.user7 = UserFactory.create()
self.user7.first_name = "King"
self.user7.last_name = "Bowser"
self.user7.save()
self.user7.profile.name = "King Bowser"
self.user7.profile.save()
self.user8 = UserFactory.create()
self.user8.first_name = "Susan"
self.user8.last_name = "Smith"
self.user8.save()
self.user8.profile.name = "Susan Smith"
self.user8.profile.save()
# Two are verified, three are audit, one honor
......@@ -116,16 +108,29 @@ class ReportTypeTests(ModuleStoreTestCase):
self.cart.purchase(self.user8, self.course_id)
CourseEnrollment.unenroll(self.user8, self.course_id)
self.test_time = datetime.datetime.now(pytz.UTC)
# We can't modify the values returned by report_row_generator directly, since it's a generator, but
# we need the times on CORRECT_CSV and the generated report to match. So, we extract the times from
# the report_row_generator and place them in CORRECT_CSV.
self.time_str = {}
report = initialize_report("refund_report")
refunds = report.report_row_generator(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
time_index = 0
for item in refunds:
self.time_str[time_index] = item[2]
time_index += 1
self.time_str[time_index] = item[3]
time_index += 1
self.CORRECT_REFUND_REPORT_CSV = dedent("""
Order Number,Customer Name,Date of Original Transaction,Date of Refund,Amount of Refund,Service Fees (if any)
3,King Bowser,{time_str},{time_str},40,0
4,Susan Smith,{time_str},{time_str},40,0
""".format(time_str=str(self.test_time)))
3,King Bowser,{time_str0},{time_str1},40,0
4,Susan Smith,{time_str2},{time_str3},40,0
""".format(time_str0=str(self.time_str[0]), time_str1=str(self.time_str[1]), time_str2=str(self.time_str[2]), time_str3=str(self.time_str[3])))
self.test_time = datetime.datetime.now(pytz.UTC)
self.CORRECT_CERT_STATUS_CSV = dedent("""
University,Course,Total Enrolled,Audit Enrollment,Honor Code Enrollment,Verified Enrollment,Gross Revenue,Gross Revenue over the Minimum,Number of Refunds,Dollars Refunded
MITx,999 Robot Super Course,6,3,1,2,80.00,0.00,0,0
MITx,999 Robot Super Course,6,3,1,2,80.00,0.00,2,80.00
""".format(time_str=str(self.test_time)))
self.CORRECT_UNI_REVENUE_SHARE_CSV = dedent("""
......@@ -133,10 +138,16 @@ class ReportTypeTests(ModuleStoreTestCase):
MITx,999 Robot Super Course,0,80.00,0.00,2,80.00
""".format(time_str=str(self.test_time)))
def test_refund_report_get_report_data(self):
def test_refund_report_report_row_generator(self):
report = initialize_report("refund_report")
refunded_certs = report.get_report_data(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
self.assertEqual(len(refunded_certs), 2)
refunded_certs = report.report_row_generator(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
# check that we have the right number
num_certs = 0
for cert in refunded_certs:
num_certs += 1
self.assertEqual(num_certs, 2)
self.assertTrue(CertificateItem.objects.get(user=self.user7, course_id=self.course_id))
self.assertTrue(CertificateItem.objects.get(user=self.user8, course_id=self.course_id))
......@@ -145,11 +156,6 @@ class ReportTypeTests(ModuleStoreTestCase):
Tests that a generated purchase report CSV is as we expect
"""
report = initialize_report("refund_report")
for item in report.get_report_data(self.now - self.FIVE_MINS, self.now + self.FIVE_MINS):
item.fulfilled_time = self.test_time
item.refund_requested_time = self.test_time # hm do we want to make these different
item.save()
csv_file = StringIO.StringIO()
report.make_report(csv_file, self.now - self.FIVE_MINS, self.now + self.FIVE_MINS)
csv = csv_file.getvalue()
......
......@@ -213,7 +213,7 @@ def csv_report(request):
return _render_report_form(start_str, end_str, start_letter, end_letter, report_type, date_fmt_error=True)
report = initialize_report(report_type)
items = report.get_report_data(start_date, end_date, start_letter, end_letter)
items = report.report_row_generator(start_date, end_date, start_letter, end_letter)
# TODO add this back later as a query-est function or something
try:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment