Commit 68174dc3 by Julia Hansbrough

Initial view

parent e3114a54
......@@ -636,6 +636,8 @@ class RefundReport(Report):
def get_query(self, start_date, end_date):
return CertificateItem.objects.filter(
status="refunded",
refund_requested_time__gte=start_date,
refund_requested_time__lt=end_date,
)
def csv_report_header_row(self):
......@@ -653,7 +655,7 @@ class RefundReport(Report):
item.order_id,
item.user.get_full_name(),
item.fulfilled_time,
item.refund_requested_time, # TODO actually may need to use refund_fulfilled here
item.refund_requested_time, # TODO Change this torefund_fulfilled once we start recording that value
item.line_cost,
item.service_fee,
]
......@@ -707,7 +709,8 @@ class CertificateStatusReport(Report):
cur_course = get_course_by_id(course_id)
university = cur_course.org
course = cur_course.number + " " + cur_course.display_name # TODO add term (i.e. Fall 2013)?
enrollments = CourseEnrollment.objects.filter(course_id=course_id,is_active=True)
enrollments = CourseEnrollment.objects.filter(course_id=course_id,
is_active=True,)
total_enrolled = enrollments.count()
audit_enrolled = enrollments.filter(mode="audit").count()
honor_enrolled = enrollments.filter(mode="honor").count()
......@@ -717,7 +720,6 @@ class CertificateStatusReport(Report):
gross_rev_temp = CertificateItem.objects.filter(course_id=course_id, mode="verified", status="purchased").aggregate(Sum('unit_cost'))
gross_rev = gross_rev_temp['unit_cost__sum']
gross_rev_over_min = gross_rev - (CourseMode.objects.get(course_id=course_id, mode_slug="verified").min_price * verified_enrolled)
num_verified_over_min = 0 # TODO clarify with billing what exactly this means
refunded_enrollments = CertificateItem.objects.filter(course_id='course_id', mode="verified", status="refunded")
number_of_refunds = refunded_enrollments.count()
dollars_refunded_temp = refunded_enrollments.aggregate(Sum('unit_cost'))
......@@ -735,7 +737,6 @@ class CertificateStatusReport(Report):
verified_enrolled,
gross_rev,
gross_rev_over_min,
num_verified_over_min,
number_of_refunds,
dollars_refunded
]
......@@ -753,7 +754,6 @@ class CertificateStatusReport(Report):
"Verified Enrollment",
"Gross Revenue",
"Gross Revenue over the Minimum",
"Number of Verified over the Minimum",
"Number of Refunds",
"Dollars Refunded",
]
......@@ -772,7 +772,7 @@ class UniversityRevenueShareReport(Report):
cur_course = get_course_by_id(course_id)
university = cur_course.org
course = cur_course.number + " " + cur_course.display_name
num_transactions = 0 # TODO clarify with building what transactions are included in this (purchases? refunds? etc)
num_transactions = 0 # TODO clarify with billing what transactions are included in this (purchases? refunds? etc)
all_paid_certs = CertificateItem.objects.filter(course_id=course_id, status="purchased")
......
......@@ -510,8 +510,8 @@ class ReportTypeTests(ModuleStoreTestCase):
""".format(time_str=str(self.test_time)))
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 Verified over the Minimum,Number of Refunds,Dollars Refunded
MITx,999 Robot Super Course,6,3,1,2,80.00,0.00,0,0,0
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
""".format(time_str=str(self.test_time)))
self.CORRECT_UNI_REVENUE_SHARE_CSV = dedent("""
......
......@@ -304,6 +304,11 @@ class CSVReportViewsTest(ModuleStoreTestCase):
mode_display_name="honor cert",
min_price=self.cost)
self.course_mode.save()
self.course_mode2 = CourseMode(course_id=self.course_id,
mode_slug="verified",
mode_display_name="verified cert",
min_price=self.cost)
self.course_mode2.save()
self.verified_course_id = 'org/test/Test_Course'
CourseFactory.create(org='org', number='test', run='course1', display_name='Test Course')
self.cart = Order.get_cart_for_user(self.user)
......@@ -343,13 +348,14 @@ class CSVReportViewsTest(ModuleStoreTestCase):
self.assertEqual(template, 'shoppingcart/download_report.html')
self.assertFalse(context['total_count_error'])
self.assertFalse(context['date_fmt_error'])
self.assertIn(_("Download Purchase Report"), response.content)
self.assertIn(_("Download CSV Reports"), response.content)
@patch('shoppingcart.views.render_to_response', render_mock)
def test_report_csv_bad_date(self):
self.login_user()
self.add_to_download_group(self.user)
response = self.client.post(reverse('payment_csv_report'), {'start_date': 'BAD', 'end_date': 'BAD'})
report_type = "itemized_purchase_report"
response = self.client.post(reverse('payment_csv_report'), {'start_date': 'BAD', 'end_date': 'BAD', 'requested_report': 'itemized_purchase_report'})
((template, context), unused_kwargs) = render_mock.call_args
self.assertEqual(template, 'shoppingcart/download_report.html')
......@@ -366,7 +372,8 @@ class CSVReportViewsTest(ModuleStoreTestCase):
self.login_user()
self.add_to_download_group(self.user)
response = self.client.post(reverse('payment_csv_report'), {'start_date': '1970-01-01',
'end_date': '2100-01-01'})
'end_date': '2100-01-01',
'requested_report': 'itemized_purchase_report'})
((template, context), unused_kwargs) = render_mock.call_args
self.assertEqual(template, 'shoppingcart/download_report.html')
......@@ -376,22 +383,22 @@ class CSVReportViewsTest(ModuleStoreTestCase):
# just going to ignored the date in this test, since we already deal with date testing
# in test_models.py
CORRECT_CSV_NO_DATE = ",1,purchased,1,40,40,usd,Registration for Course: Robot Super Course,"
def test_report_csv(self):
# TODO test multiple types
report_type = "itemized_purchase_report"
CORRECT_CSV_NO_DATE_ITEMIZED_PURCHASE = ",1,purchased,1,40,40,usd,Registration for Course: Robot Super Course,"
def test_report_csv(self):
report_type = 'itemized_purchase_report'
PaidCourseRegistration.add_to_order(self.cart, self.course_id)
self.cart.purchase()
self.login_user()
self.add_to_download_group(self.user)
response = self.client.post(reverse('payment_csv_report'), {'start_date': '1970-01-01',
'end_date': '2100-01-01'})
'end_date': '2100-01-01',
'requested_report': report_type})
self.assertEqual(response['Content-Type'], 'text/csv')
report = Report.initialize_report(report_type)
self.assertIn(",".join(report.csv_report_header_row()), response.content)
self.assertIn(self.CORRECT_CSV_NO_DATE, response.content)
self.assertIn(self.CORRECT_CSV_NO_DATE_ITEMIZED_PURCHASE, response.content)
class UtilFnsTest(TestCase):
......
......@@ -5,6 +5,7 @@ urlpatterns = patterns('shoppingcart.views', # nopep8
url(r'^postpay_callback/$', 'postpay_callback'), # Both the ~accept and ~reject callback pages are handled here
url(r'^receipt/(?P<ordernum>[0-9]*)/$', 'show_receipt'),
)
if settings.FEATURES['ENABLE_SHOPPING_CART']:
urlpatterns += patterns(
'shoppingcart.views',
......@@ -19,5 +20,5 @@ if settings.FEATURES.get('ENABLE_PAYMENT_FAKE'):
from shoppingcart.tests.payment_fake import PaymentFakeView
urlpatterns += patterns(
'shoppingcart.tests.payment_fake',
url(r'^payment_fake', PaymentFakeView.as_view())
url(r'^payment_fake', PaymentFakeView.as_view()),
)
......@@ -95,7 +95,6 @@ def postpay_callback(request):
return render_to_response('shoppingcart/error.html', {'order': result['order'],
'error_html': result['error_html']})
@login_required
def show_receipt(request, ordernum):
"""
......@@ -156,7 +155,7 @@ def _get_date_from_str(date_input):
return datetime.datetime.strptime(date_input.strip(), "%Y-%m-%d").replace(tzinfo=pytz.UTC)
def _render_report_form(start_str, end_str, total_count_error=False, date_fmt_error=False):
def _render_report_form(start_str, end_str, report_type, total_count_error=False, date_fmt_error=False):
"""
Helper function that renders the purchase form. Reduces repetition
"""
......@@ -165,6 +164,7 @@ def _render_report_form(start_str, end_str, total_count_error=False, date_fmt_er
'date_fmt_error': date_fmt_error,
'start_date': start_str,
'end_date': end_str,
'requested_report': report_type,
}
return render_to_response('shoppingcart/download_report.html', context)
......@@ -174,8 +174,6 @@ def csv_report(request):
"""
Downloads csv reporting of orderitems
"""
# TODO: change this to something modular later
report_type = "itemized_purchase_report"
if not _can_download_report(request.user):
return HttpResponseForbidden(_('You do not have permission to view this page.'))
......@@ -183,18 +181,19 @@ def csv_report(request):
if request.method == 'POST':
start_str = request.POST.get('start_date', '')
end_str = request.POST.get('end_date', '')
report_type = request.POST.get('requested_report', '')
try:
start_date = _get_date_from_str(start_str)
end_date = _get_date_from_str(end_str) + datetime.timedelta(days=1)
except ValueError:
# Error case: there was a badly formatted user-input date string
return _render_report_form(start_str, end_str, date_fmt_error=True)
return _render_report_form(start_str, end_str, report_type, date_fmt_error=True)
report = Report.initialize_report(report_type)
items = report.get_query(start_date, end_date)
if items.count() > settings.PAYMENT_REPORT_MAX_ITEMS:
# Error case: too many items would be generated in the report and we're at risk of timeout
return _render_report_form(start_str, end_str, total_count_error=True)
return _render_report_form(start_str, end_str, report_type, total_count_error=True)
response = HttpResponse(mimetype='text/csv')
filename = "purchases_report_{}.csv".format(datetime.datetime.now(pytz.UTC).strftime("%Y-%m-%d-%H-%M-%S"))
......@@ -206,7 +205,7 @@ def csv_report(request):
elif request.method == 'GET':
end_date = datetime.datetime.now(pytz.UTC)
start_date = end_date - datetime.timedelta(days=30)
return _render_report_form(start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d"))
return _render_report_form(start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d"), report_type="")
else:
return HttpResponseBadRequest("HTTP Method Not Supported")
......@@ -2,11 +2,11 @@
<%! from django.core.urlresolvers import reverse %>
<%inherit file="../main.html" />
<%block name="title"><title>${_("Download Purchase Report")}</title></%block>
<%block name="title"><title>${_("Download CSV Reports")}</title></%block>
<section class="container">
<h2>${_("Download CSV of purchase data")}</h2>
<h2>${_("Download CSV Data")}</h2>
% if date_fmt_error:
<section class="error_msg">
${_("There was an error in your date input. It should be formatted as YYYY-MM-DD")}
......@@ -24,6 +24,13 @@
<label for="end_date">${_("End Date: ")}</label>
<input id="end_date" type="text" value="${end_date}" name="end_date"/>
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf_token}" />
<input type="submit" />
<br/>
<button type = "submit" name="requested_report" value="itemized_purchase_report">Itemized Purchase Report</button>
<br/>
<button type = "submit" name="requested_report" value="refund_report">Refund Report</button>
<br/>
<button type = "submit" name="requested_report" value="university_revenue_share">University Revenue Share</button>
<br/>
<button type="submit" name="requested_report" value="certificate_status">Certiciate Status</button>
</form>
</section>
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