Skip to content

Commit 44b4bad

Browse files
committed
Merge branch 'release/v0.9.0'
2 parents 121348f + c04ee4d commit 44b4bad

40 files changed

+2018
-770
lines changed

.pre-commit-config.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
repos:
2+
3+
- repo: https://github.com/adamchainz/blacken-docs
4+
rev: ""
5+
hooks:
6+
- id: blacken-docs
7+
additional_dependencies:
8+
- black==22.12.0
9+
10+
- repo: https://github.com/psf/black
11+
rev: stable
12+
hooks:
13+
- id: black
14+
language_version: python3.9

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,31 @@
22

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

5+
## [0.9.0] - 2023-06-07
6+
7+
- Deprecated ``form_factory`` in favor of ``forms``, to be removed next version.
8+
- Deprecated `crosstab_model` in favor of ``crosstab_field``, to be removed next version.
9+
- Deprecated ``slick_reporting.view.SlickReportView`` and ``slick_reporting.view.SlickReportViewBase`` in favor of ``slick_reporting.view.ReportView`` and ``slick_reporting.view.BaseReportView``, to be removed next version.
10+
- Allowed cross tab on fields other than ForeignKey
11+
- Added support for start_date_field_name and end_date_field_name
12+
- Added support to crosstab on traversing fields
13+
- Added support for document types / debit and credit calculations
14+
- Added support for ordering via ``ReportView.default_order_by`` and/or passing the parameter ``order_by`` to the view
15+
- Added return of Ajax response in case of error and request is Ajax
16+
- Made it easy override to the search form. Create you own form and subclass BaseReportForm and implement the mandatory method(s).
17+
- Consolidated the needed resources in ``slick_reporting/js_resource.html`` template, so to use your own template you just need to include it.
18+
- Fixed an issue with report fields not respecting the queryset on the ReportView.
19+
- Fixed an issue if a foreign key have a custom `to_field` set either in ``group_by`` and/or `crosstab_field` .
20+
- Enhancing and adding to the documentation.
21+
- Black format the code and the documentation
22+
23+
524
## [0.8.0]
625

726
- Breaking: [Only if you use Crosstab reports] renamed crosstab_compute_reminder to crosstab_compute_remainder
827
- Breaking : [Only if you set the templates statics by hand] renamed slick_reporting to ra.hightchart.js and ra.chartjs.js to
928
erp_framework.highchart.js and erp_framework.chartjs.js respectively
29+
- Fix an issue with Crosstab when there crosstab_compute_remainder = False
1030

1131
## [0.7.0]
1232

README.rst

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,36 @@ You can simply use a code like this
5151
.. code-block:: python
5252
5353
# in your urls.py
54-
path('path-to-report', TotalProductSales.as_view())
54+
path("path-to-report", TotalProductSales.as_view())
5555
5656
5757
# in views.py
5858
from django.db.models import Sum
59-
from slick_reporting.views import SlickReportView
59+
from slick_reporting.views import ReportView
6060
from slick_reporting.fields import SlickReportField
6161
from .models import MySalesItems
6262
63-
class TotalProductSales(SlickReportView):
6463
65-
report_model = MySalesItems
66-
date_field = 'date_placed'
67-
group_by = 'product'
68-
columns = ['title',
69-
SlickReportField.create(Sum, 'quantity') ,
70-
SlickReportField.create(Sum, 'value', name='sum__value') ]
71-
72-
chart_settings = [{
73-
'type': 'column',
74-
'data_source': ['sum__value'],
75-
'plot_total': False,
76-
'title_source': 'title',
77-
'title': _('Detailed Columns'),
64+
class TotalProductSales(ReportView):
7865
79-
}, ]
66+
report_model = MySalesItems
67+
date_field = "date_placed"
68+
group_by = "product"
69+
columns = [
70+
"title",
71+
SlickReportField.create(Sum, "quantity"),
72+
SlickReportField.create(Sum, "value", name="sum__value"),
73+
]
74+
75+
chart_settings = [
76+
{
77+
"type": "column",
78+
"data_source": ["sum__value"],
79+
"plot_total": False,
80+
"title_source": "title",
81+
"title": _("Detailed Columns"),
82+
},
83+
]
8084
8185
8286
To get something like this
@@ -92,19 +96,22 @@ You can do a monthly time series :
9296
.. code-block:: python
9397
9498
# in views.py
95-
from slick_reporting.views import SlickReportView
99+
from slick_reporting.views import ReportView
96100
from slick_reporting.fields import SlickReportField
97101
from .models import MySalesItems
98102
99-
class MonthlyProductSales(SlickReportView):
103+
104+
class MonthlyProductSales(ReportView):
100105
report_model = MySalesItems
101-
date_field = 'date_placed'
102-
group_by = 'product'
103-
columns = ['name', 'sku']
106+
date_field = "date_placed"
107+
group_by = "product"
108+
columns = ["name", "sku"]
104109
105110
# Analogy for time series
106-
time_series_pattern = 'monthly'
107-
time_series_columns = [SlickReportField.create(Sum, 'quantity', name='sum__quantity') ]
111+
time_series_pattern = "monthly"
112+
time_series_columns = [
113+
SlickReportField.create(Sum, "quantity", name="sum__quantity")
114+
]
108115
109116
110117
This would return a table looking something like this:
@@ -127,18 +134,17 @@ This would return a table looking something like this:
127134

128135
**On a low level**
129136

130-
You can interact with the `ReportGenerator` using same syntax as used with the `SlickReportView` .
137+
You can interact with the `ReportGenerator` using same syntax as used with the `ReportView` .
131138

132139
.. code-block:: python
133140
134141
from slick_reporting.generator import ReportGenerator
135-
from . models import MySalesModel
142+
from .models import MySalesModel
136143
137-
report = ReportGenerator(report_model=MySalesModel,
138-
group_by='product',
139-
columns=['title', '__total__']
144+
report = ReportGenerator(
145+
report_model=MySalesModel, group_by="product", columns=["title", "__total__"]
140146
)
141-
report.get_report_data() #-> [{'title':'Product 1', '__total__: 56}, {'title':'Product 2', '__total__: 43}, ]
147+
report.get_report_data() # -> [{'title':'Product 1', '__total__: 56}, {'title':'Product 2', '__total__: 43}, ]
142148
143149
144150
This is just a scratch, for more please visit the documentation

docs/source/_static/crosstab.png

43.4 KB
Loading

docs/source/_static/group_report.png

29.2 KB
Loading
7.79 KB
Loading

docs/source/charts.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Charting
2+
---------
3+
4+
Charts settings is a list of objects which each object represent a chart configurations.
5+
6+
* type: what kind of chart it is: Possible options are bar, pie, line and others subject of the underlying charting engine.
7+
Hats off to : `Charts.js <https://www.chartjs.org/>`_.
8+
* engine_name: String, default to ``SLICK_REPORTING_DEFAULT_CHARTS_ENGINE``. Passed to front end in order to use the appropriate chart engine.
9+
By default supports `highcharts` & `chartsjs`.
10+
* data_source: Field name containing the numbers we want to plot.
11+
* title_source: Field name containing labels of the data_source
12+
* title: the Chart title. Defaults to the `report_title`.
13+
* plot_total if True the chart will plot the total of the columns. Useful with time series and crosstab reports.
14+
15+
On front end, for each chart needed we pass the whole response to the relevant chart helper function and it handles the rest.
16+
17+

docs/source/concept.rst

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,35 @@ And now, Let's explore the main components of Django Slick Reporting and what se
99

1010
Components
1111
----------
12+
These are the main components of Django Slick Reporting, ordered from low level to high level:
1213

14+
1. Report Field: represent a calculation unit, for example: a Sum or a Count of a certain field.
15+
The report field identifies how the calculation should be done. ReportFields can depend on each other.
1316

14-
1. Report Field: represent a number, a calculation unit, for example: a Sum of a certain field.
15-
The report field identifies how the calculation should be done. ResultFields can depend on each other.
17+
2. Generator: The heart of the reporting engine , It's responsible for computing and generating the data and provides low level access.
1618

17-
2. Generator: Represent a concrete report structure.If it would group by certain field, do a time series or a cross tab, and which columns (Report Field) to be calculated.
18-
It's also responsible for computing and provides low level access. *ie you can get the data in a list of dict/objects*
19+
3. View: A wrapper around the generator exposing the generator options in a FormView that you can hook straight to your urls.
20+
It also provide a Search Form to filter the report on.
21+
It mimics the Generator API interface, so knowing one is enough to work with the other.
1922

20-
3. View: Responsible for creating a nice form to filter the report on, pass those filters to the generator class to create the report.
21-
It mimic the Generator API. Provide high level access. *You can hook it to your urls.py and you're all set, with the charts.*
23+
4. Charting JS helpers: Django slick Reporting comes with highcharts and Charts js helpers libraries to plot the data generated.
24+
25+
26+
Types of Reports
27+
----------------
28+
29+
1. Time Series: A report that is grouped by a date field, and the report fields are calculated on each group.
30+
For example: Sum of sales per month, Count of sales per day, etc..
31+
32+
2. Cross Tab: shows data in rows and columns with information summarized at the intersection points.
33+
For example: Sum of product sales per month, crosstab by client would show Products as rows, clients included in the crosstab_ids as columns.
34+
35+
3. Grouped: A report that is grouped by a field, and the report fields are calculated on each group.
36+
For example: Sum of sales per product, Count of sales per product, etc..
37+
38+
4. Flat: A report that is not grouped, similar to what an admin list view would show.
39+
For example: Sales Transactions log
2240

23-
4. Charting JS helpers: Django slick Reporting comes with highcharts and Charts js helpers libraries to plot the charts generated by the View
2441

2542

2643
Settings
@@ -34,19 +51,19 @@ Settings
3451
.. code-block:: python
3552
3653
SLICK_REPORTING_FORM_MEDIA = {
37-
'css': {
38-
'all': (
39-
'https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.css',
40-
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css',
41-
)
42-
},
43-
'js': (
44-
'https://code.jquery.com/jquery-3.3.1.slim.min.js',
45-
'https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.js',
46-
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js',
47-
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js',
48-
'https://code.highcharts.com/highcharts.js',
49-
)
54+
"css": {
55+
"all": (
56+
"https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.css",
57+
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css",
58+
)
59+
},
60+
"js": (
61+
"https://code.jquery.com/jquery-3.3.1.slim.min.js",
62+
"https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.js",
63+
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js",
64+
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js",
65+
"https://code.highcharts.com/highcharts.js",
66+
),
5067
}
5168
5269
4. ``SLICK_REPORTING_DEFAULT_CHARTS_ENGINE``: Controls the default chart engine used.

docs/source/conf.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,20 @@
1414
import sys
1515
import django
1616

17-
sys.path.insert(0, os.path.abspath('../../'))
18-
os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings'
17+
sys.path.insert(0, os.path.abspath("../../"))
18+
os.environ["DJANGO_SETTINGS_MODULE"] = "tests.settings"
1919
django.setup()
2020

2121
# -- Project information -----------------------------------------------------
2222

23-
project = 'Django Slick Reporting'
24-
copyright = '2020, Ramez Ashraf'
25-
author = 'Ramez Ashraf'
23+
project = "Django Slick Reporting"
24+
copyright = "2020, Ramez Ashraf"
25+
author = "Ramez Ashraf"
2626

27-
master_doc = 'index'
27+
master_doc = "index"
2828

2929
# The full version, including alpha/beta/rc tags
30-
release = '0.6.8'
30+
release = "0.6.8"
3131

3232
# -- General configuration ---------------------------------------------------
3333

@@ -37,12 +37,13 @@
3737
autosummary_generate = True
3838
autoclass_content = "class"
3939
extensions = [
40-
'sphinx.ext.viewcode', 'sphinx.ext.autodoc',
41-
'sphinx.ext.autosummary',
40+
"sphinx.ext.viewcode",
41+
"sphinx.ext.autodoc",
42+
"sphinx.ext.autosummary",
4243
]
4344

4445
# Add any paths that contain templates here, relative to this directory.
45-
templates_path = ['_templates']
46+
templates_path = ["_templates"]
4647

4748
# List of patterns, relative to source directory, that match files and
4849
# directories to ignore when looking for source files.
@@ -54,9 +55,9 @@
5455
# The theme to use for HTML and HTML Help pages. See the documentation for
5556
# a list of builtin themes.
5657
#
57-
html_theme = 'sphinx_rtd_theme'
58+
html_theme = "sphinx_rtd_theme"
5859

5960
# Add any paths that contain custom static files (such as style sheets) here,
6061
# relative to this directory. They are copied after the builtin static files,
6162
# so a file named "default.css" will overwrite the builtin "default.css".
62-
html_static_path = ['_static']
63+
html_static_path = ["_static"]

0 commit comments

Comments
 (0)