You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

reports.py 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from datetime import datetime, time
  2. from django.http import HttpResponse
  3. from django.utils.translation import ugettext_lazy as _
  4. from django.utils import timezone
  5. from oscar.core import utils
  6. from oscar.core.compat import UnicodeCSVWriter
  7. class ReportGenerator(object):
  8. """
  9. Top-level class that needs to be subclassed to provide a
  10. report generator.
  11. """
  12. filename_template = 'report-%s-to-%s.csv'
  13. content_type = 'text/csv'
  14. code = ''
  15. description = '<insert report description>'
  16. date_range_field_name = None
  17. def __init__(self, **kwargs):
  18. self.start_date = kwargs.get('start_date')
  19. self.end_date = kwargs.get('end_date')
  20. formatter_name = '%s_formatter' % kwargs['formatter']
  21. self.formatter = self.formatters[formatter_name]()
  22. def report_description(self):
  23. return _('%(report_filter)s between %(start_date)s and %(end_date)s') \
  24. % {'report_filter': self.description,
  25. 'start_date': self.start_date,
  26. 'end_date': self.end_date,
  27. }
  28. def generate(self, response):
  29. pass
  30. def filename(self):
  31. """
  32. Returns the filename for this report
  33. """
  34. return self.formatter.filename()
  35. def is_available_to(self, user):
  36. """
  37. Checks whether this report is available to this user
  38. """
  39. return user.is_staff
  40. def filter_with_date_range(self, queryset):
  41. """
  42. Filter results based that are within a (possibly open ended) daterange
  43. """
  44. # Nothing to do if we don't have a date field
  45. if not self.date_range_field_name:
  46. return queryset
  47. # After the start date
  48. if self.start_date:
  49. start_datetime = timezone.make_aware(
  50. datetime.combine(self.start_date, time(0, 0)),
  51. timezone.get_default_timezone())
  52. filter_kwargs = {
  53. "%s__gt" % self.date_range_field_name: start_datetime,
  54. }
  55. queryset = queryset.filter(**filter_kwargs)
  56. # Before the end of the end date
  57. if self.end_date:
  58. end_of_end_date = datetime.combine(
  59. self.end_date,
  60. time(hour=23, minute=59, second=59)
  61. )
  62. end_datetime = timezone.make_aware(end_of_end_date,
  63. timezone.get_default_timezone())
  64. filter_kwargs = {
  65. "%s__lt" % self.date_range_field_name: end_datetime,
  66. }
  67. queryset = queryset.filter(**filter_kwargs)
  68. return queryset
  69. class ReportFormatter(object):
  70. def format_datetime(self, dt):
  71. if not dt:
  72. return ''
  73. return utils.format_datetime(dt, 'DATETIME_FORMAT')
  74. def format_date(self, d):
  75. if not d:
  76. return ''
  77. return utils.format_datetime(d, 'DATE_FORMAT')
  78. def filename(self):
  79. return self.filename_template
  80. class ReportCSVFormatter(ReportFormatter):
  81. def get_csv_writer(self, file_handle, **kwargs):
  82. return UnicodeCSVWriter(open_file=file_handle, **kwargs)
  83. def generate_response(self, objects, **kwargs):
  84. response = HttpResponse(content_type='text/csv')
  85. response['Content-Disposition'] = 'attachment; filename=%s' \
  86. % self.filename(**kwargs)
  87. self.generate_csv(response, objects)
  88. return response
  89. class ReportHTMLFormatter(ReportFormatter):
  90. def generate_response(self, objects, **kwargs):
  91. return objects