Skip to content

Commit 5427538

Browse files
committed
Merge branch 'release/v0.5.2'
2 parents 5d20886 + b0121f8 commit 5427538

File tree

9 files changed

+55
-61
lines changed

9 files changed

+55
-61
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
## [0.5.1] -
5+
## [0.5.2]
6+
7+
- Enhanced Time Series Plot total HighChart by accenting the categories
8+
- Enhanced the default verbose names of time series.
9+
- Expanding test coverage
10+
11+
12+
## [0.5.1]
613

714
- Allow for time series to operate on a non-group by report
815
- Allow setting time series custom dates on ReportGenerator attr and init

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
master_doc = 'index'
2525

2626
# The full version, including alpha/beta/rc tags
27-
release = '0.5.1'
27+
release = '0.5.2'
2828

2929
# -- General configuration ---------------------------------------------------
3030

slick_reporting/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
default_app_config = 'slick_reporting.apps.ReportAppConfig'
33

4-
VERSION = (0, 5, 1)
4+
VERSION = (0, 5, 2)
55

6-
__version__ = '0.5.1'
6+
__version__ = '0.5.2'

slick_reporting/fields.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import uuid
22

33
from django.db.models import Sum
4+
from django.template.defaultfilters import date as date_filter
45
from django.utils.translation import ugettext_lazy as _
56

6-
from .decorators import report_field_register
77
from .helpers import get_calculation_annotation
88
from .registry import field_registry
99

@@ -284,15 +284,28 @@ def get_crosstab_field_verbose_name(cls, model, id):
284284
return f'{cls.verbose_name} {model} {id}'
285285

286286
@classmethod
287-
def get_time_series_field_verbose_name(cls, date_period):
287+
def get_time_series_field_verbose_name(cls, date_period, index, dates, pattern):
288288
"""
289-
Sent the column data to construct a verbose name.
290-
Default implemenetation is column name + the end date %Y%m%d
291-
:param column_name: the computation field_name
289+
Get the name of the verbose name of a computaion field that's in a time_series.
290+
should be a mix of the date period if the column an it's verbose name.
292291
:param date_period: a tuple of (start_date, end_date)
292+
:param index: the index of the current field in the whole dates to be calculated
293+
:param dates a list of tuples representing the start and the end date
293294
:return: a verbose string
294295
"""
295296
dt_format = '%Y/%m/%d'
297+
298+
if pattern == 'monthly':
299+
month_name = date_filter(date_period[0], 'F Y')
300+
return f'{cls.verbose_name} {month_name}'
301+
elif pattern == 'daily':
302+
return f'{cls.verbose_name} {date_period[0].strftime(dt_format)}'
303+
elif pattern == 'weekly':
304+
return f' {cls.verbose_name} {_("Week")} {index} {date_period[0].strftime(dt_format)}'
305+
elif pattern == 'yearly':
306+
year = date_filter(date_period[0], 'Y')
307+
return f'{cls.verbose_name} {year}'
308+
296309
return f'{cls.verbose_name} {date_period[0].strftime(dt_format)} - {date_period[1].strftime(dt_format)}'
297310

298311

slick_reporting/form_factory.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ class BaseReportForm:
1515

1616
@property
1717
def media(self):
18-
# media = super().media
1918
from .app_settings import SLICK_REPORTING_FORM_MEDIA
20-
# import pdb; pdb.set_trace()
2119
return forms.Media(css=SLICK_REPORTING_FORM_MEDIA.get('css', {}), js=SLICK_REPORTING_FORM_MEDIA.get('js', []))
2220

2321
def get_filters(self):

slick_reporting/generator.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,6 @@ def __init__(self, report_model=None, main_queryset=None, start_date=None, end_d
230230
# group_by_filter = self.kwargs_filters.get(self.group_by, '')
231231
# qs = self.group_by_field.related_model.objects
232232
# if group_by_filter:
233-
# import pdb; pdb.set_trace()
234233
# lookup = 'pk__in' if isinstance(group_by_filter, Iterable) else 'pk'
235234
# qs = qs.filter(**{lookup: group_by_filter})
236235
# self.main_queryset = qs.values()
@@ -300,11 +299,8 @@ def _prepare_report_dependencies(self):
300299
fields_on_report = [x for x in window_cols if x['ref'] in dependencies_names]
301300
for field in fields_on_report:
302301
self._report_fields_dependencies[window][field['name']] = col_data['name']
303-
# import pdb; pdb.set_trace()
304302
for col_data in window_cols:
305303
klass = col_data['ref']
306-
# if getattr(klass, 'name', '') not in klasses_names:
307-
# continue
308304
name = col_data['name']
309305

310306
# if column has a dependency then skip it
@@ -519,7 +515,7 @@ def get_time_series_parsed_columns(self):
519515
cols = self.time_series_columns or []
520516
series = self._get_time_series_dates(self.time_series_pattern)
521517

522-
for dt in series:
518+
for index, dt in enumerate(series):
523519
for col in cols:
524520
magic_field_class = None
525521

@@ -531,7 +527,7 @@ def get_time_series_parsed_columns(self):
531527
_values.append({
532528
'name': magic_field_class.name + 'TS' + dt[1].strftime('%Y%m%d'),
533529
'original_name': magic_field_class.name,
534-
'verbose_name': self.get_time_series_field_verbose_name(magic_field_class, dt),
530+
'verbose_name': self.get_time_series_field_verbose_name(magic_field_class, dt, index, series),
535531
'ref': magic_field_class,
536532
'start_date': dt[0],
537533
'end_date': dt[1],
@@ -540,7 +536,7 @@ def get_time_series_parsed_columns(self):
540536
})
541537
return _values
542538

543-
def get_time_series_field_verbose_name(self, computation_class, date_period):
539+
def get_time_series_field_verbose_name(self, computation_class, date_period, index, series, pattern=None):
544540
"""
545541
Sent the column data to construct a verbose name.
546542
Default implementation is delegated to the ReportField.get_time_series_field_verbose_name
@@ -550,7 +546,9 @@ def get_time_series_field_verbose_name(self, computation_class, date_period):
550546
:param date_period: a tuple of (start_date, end_date)
551547
:return: a verbose string
552548
"""
553-
return computation_class.get_time_series_field_verbose_name(date_period)
549+
pattern = pattern or self.time_series_pattern
550+
return computation_class.get_time_series_field_verbose_name(date_period, index, series,
551+
pattern)
554552

555553
def get_custom_time_series_dates(self):
556554
"""

slick_reporting/static/slick_reporting/ra.highchart.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,17 @@
360360
Object.keys(data_sources).forEach(function (series_cols, index) {
361361
let data = []
362362
data_sources[series_cols].forEach(function (col, index) {
363-
data.push(totalValues[col])
364-
})
365-
series.push({
366-
'name': 'Total', //todo
367-
'data': data
363+
364+
series.push({
365+
'name': response.metadata.time_series_column_verbose_names[index],
366+
data: [totalValues[col]]
367+
})
368368
})
369+
369370
})
370371
}
371372
return {
372-
// 'categories': response.metadata.time_series_column_verbose_names,
373+
'categories': response.metadata.time_series_column_verbose_names,
373374
'titles': response.metadata.time_series_column_verbose_names,
374375
'series': series,
375376
}

tests/test_generator.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,30 @@ def test_time_series_columns_inclusion(self):
5454
self.assertEqual(len(x.get_list_display_columns()), 13)
5555

5656
def test_time_series_patterns(self):
57+
from slick_reporting.fields import TotalReportField
5758
report = ReportGenerator(OrderLine, date_field='order__date_placed', group_by='client',
5859
columns=['name', '__time_series__'],
5960
time_series_columns=['__total_quantity__'], time_series_pattern='monthly',
6061
start_date=datetime(2020, 1, 1, tzinfo=pytz.timezone('utc')),
6162
end_date=datetime(2020, 12, 31, tzinfo=pytz.timezone('utc')))
63+
64+
report_field_class = TotalReportField
6265
dates = report._get_time_series_dates()
6366
self.assertEqual(len(dates), 12)
67+
self.assertIsNotNone(report.get_time_series_field_verbose_name(TotalReportField, dates[0], 0, dates))
6468

6569
dates = report._get_time_series_dates('daily')
6670
self.assertEqual(len(dates), 365, len(dates))
71+
self.assertIsNotNone(report.get_time_series_field_verbose_name(TotalReportField, dates[0], 0, dates, 'daily'))
6772

6873
dates = report._get_time_series_dates('weekly')
6974
self.assertEqual(len(dates), 53, len(dates))
75+
self.assertIsNotNone(report.get_time_series_field_verbose_name(TotalReportField, dates[0], 0, dates, 'weekly'))
7076

7177
dates = report._get_time_series_dates('semimonthly')
7278
self.assertEqual(len(dates), 27, len(dates))
79+
self.assertIsNotNone(
80+
report.get_time_series_field_verbose_name(TotalReportField, dates[0], 0, dates, 'semimonthly'))
7381

7482
dates = report._get_time_series_dates('quarterly')
7583
self.assertEqual(len(dates), 4, len(dates))
@@ -78,7 +86,7 @@ def test_time_series_patterns(self):
7886
self.assertEqual(len(dates), 2, len(dates))
7987
dates = report._get_time_series_dates('annually')
8088
self.assertEqual(len(dates), 1, len(dates))
81-
89+
self.assertIsNotNone(report.get_time_series_field_verbose_name(TotalReportField, dates[0], 0, dates))
8290

8391
def test_time_series_custom_pattern(self):
8492
# report = ReportGenerator(OrderLine, date_field='order__date_placed', group_by='client',

tests/tests.py

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -126,33 +126,6 @@ def test_productclientsalesmatrix(self):
126126
self.assertEqual(data[0]['__total__CT%s' % self.client2.pk], 600)
127127
self.assertEqual(data[0]['__total__CT----'], 900)
128128

129-
def _test_default_order_by(self):
130-
self.client.login(username='super', password='secret')
131-
response = self.client.get(reverse('ra_admin:report', args=('client', 'clienttotalbalancesordered')),
132-
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
133-
self.assertEqual(response.status_code, 200)
134-
data = response.json()
135-
previous_balance = 0
136-
self.assertTrue(len(data['data']) > 1)
137-
for i, line in enumerate(data['data']):
138-
if i == 0:
139-
previous_balance = line['__balance__']
140-
else:
141-
self.assertTrue(line['__balance__'] > previous_balance)
142-
143-
def _test_default_order_by_reversed(self):
144-
self.client.login(username='super', password='secret')
145-
response = self.client.get(reverse('ra_admin:report', args=('client', 'ClientTotalBalancesOrderedDESC')),
146-
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
147-
self.assertEqual(response.status_code, 200)
148-
data = response.json()
149-
previous_balance = 0
150-
self.assertTrue(len(data['data']) > 1)
151-
for i, line in enumerate(data['data']):
152-
if i == 0:
153-
previous_balance = line['__balance__']
154-
else:
155-
self.assertTrue(line['__balance__'] < previous_balance)
156129

157130
def test_show_empty_records(self):
158131
report = report_generators.ClientTotalBalance()
@@ -252,6 +225,8 @@ def test_crosstab_report_view(self):
252225
data = ProductClientSalesMatrix(crosstab_compute_reminder=True,
253226
crosstab_ids=[self.client1.pk, self.client2.pk]).get_report_data()
254227

228+
response = self.client.get(reverse('product_crosstab_client'))
229+
self.assertEqual(response.status_code, 200)
255230
response = self.client.get(reverse('product_crosstab_client'), data={
256231
'client_id': [self.client1.pk, self.client2.pk],
257232
'crosstab_compute_reminder': True,
@@ -283,10 +258,6 @@ def test_chart_settings(self):
283258
self.assertTrue('pie' in data['chart_settings'][0]['id'])
284259
self.assertTrue(data['chart_settings'][0]['title'], 'awesome report title')
285260

286-
def _test_column_names_are_always_strings(self):
287-
# todo
288-
pass
289-
290261
def test_error_on_missing_date_field(self):
291262
def test_function():
292263
class TotalClientSales(SlickReportView):
@@ -333,12 +304,10 @@ def register():
333304

334305
def test_get_non_existent_field(self):
335306
def register():
336-
field = field_registry.get_field_by_name('__a_weird_name__')
337-
return field
307+
return field_registry.get_field_by_name('__a_weird_name__')
338308

339309
with self.assertRaises(Exception):
340-
field = register()
341-
self.assertIsNone(field)
310+
register()
342311

343312
def test_creating_a_report_field_on_the_fly(self):
344313
from django.db.models import Sum

0 commit comments

Comments
 (0)