Skip to content

Commit

Permalink
Merge branch 'release/v0.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
RamezIssac committed Jun 7, 2023
2 parents 121348f + c04ee4d commit 44b4bad
Show file tree
Hide file tree
Showing 40 changed files with 2,018 additions and 770 deletions.
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
repos:

- repo: https://github.com/adamchainz/blacken-docs
rev: ""
hooks:
- id: blacken-docs
additional_dependencies:
- black==22.12.0

- repo: https://github.com/psf/black
rev: stable
hooks:
- id: black
language_version: python3.9
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@

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

## [0.9.0] - 2023-06-07

- Deprecated ``form_factory`` in favor of ``forms``, to be removed next version.
- Deprecated `crosstab_model` in favor of ``crosstab_field``, to be removed next version.
- 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.
- Allowed cross tab on fields other than ForeignKey
- Added support for start_date_field_name and end_date_field_name
- Added support to crosstab on traversing fields
- Added support for document types / debit and credit calculations
- Added support for ordering via ``ReportView.default_order_by`` and/or passing the parameter ``order_by`` to the view
- Added return of Ajax response in case of error and request is Ajax
- Made it easy override to the search form. Create you own form and subclass BaseReportForm and implement the mandatory method(s).
- Consolidated the needed resources in ``slick_reporting/js_resource.html`` template, so to use your own template you just need to include it.
- Fixed an issue with report fields not respecting the queryset on the ReportView.
- Fixed an issue if a foreign key have a custom `to_field` set either in ``group_by`` and/or `crosstab_field` .
- Enhancing and adding to the documentation.
- Black format the code and the documentation


## [0.8.0]

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

## [0.7.0]

Expand Down
66 changes: 36 additions & 30 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,32 +51,36 @@ You can simply use a code like this
.. code-block:: python
# in your urls.py
path('path-to-report', TotalProductSales.as_view())
path("path-to-report", TotalProductSales.as_view())
# in views.py
from django.db.models import Sum
from slick_reporting.views import SlickReportView
from slick_reporting.views import ReportView
from slick_reporting.fields import SlickReportField
from .models import MySalesItems
class TotalProductSales(SlickReportView):
report_model = MySalesItems
date_field = 'date_placed'
group_by = 'product'
columns = ['title',
SlickReportField.create(Sum, 'quantity') ,
SlickReportField.create(Sum, 'value', name='sum__value') ]
chart_settings = [{
'type': 'column',
'data_source': ['sum__value'],
'plot_total': False,
'title_source': 'title',
'title': _('Detailed Columns'),
class TotalProductSales(ReportView):
}, ]
report_model = MySalesItems
date_field = "date_placed"
group_by = "product"
columns = [
"title",
SlickReportField.create(Sum, "quantity"),
SlickReportField.create(Sum, "value", name="sum__value"),
]
chart_settings = [
{
"type": "column",
"data_source": ["sum__value"],
"plot_total": False,
"title_source": "title",
"title": _("Detailed Columns"),
},
]
To get something like this
Expand All @@ -92,19 +96,22 @@ You can do a monthly time series :
.. code-block:: python
# in views.py
from slick_reporting.views import SlickReportView
from slick_reporting.views import ReportView
from slick_reporting.fields import SlickReportField
from .models import MySalesItems
class MonthlyProductSales(SlickReportView):
class MonthlyProductSales(ReportView):
report_model = MySalesItems
date_field = 'date_placed'
group_by = 'product'
columns = ['name', 'sku']
date_field = "date_placed"
group_by = "product"
columns = ["name", "sku"]
# Analogy for time series
time_series_pattern = 'monthly'
time_series_columns = [SlickReportField.create(Sum, 'quantity', name='sum__quantity') ]
time_series_pattern = "monthly"
time_series_columns = [
SlickReportField.create(Sum, "quantity", name="sum__quantity")
]
This would return a table looking something like this:
Expand All @@ -127,18 +134,17 @@ This would return a table looking something like this:

**On a low level**

You can interact with the `ReportGenerator` using same syntax as used with the `SlickReportView` .
You can interact with the `ReportGenerator` using same syntax as used with the `ReportView` .

.. code-block:: python
from slick_reporting.generator import ReportGenerator
from . models import MySalesModel
from .models import MySalesModel
report = ReportGenerator(report_model=MySalesModel,
group_by='product',
columns=['title', '__total__']
report = ReportGenerator(
report_model=MySalesModel, group_by="product", columns=["title", "__total__"]
)
report.get_report_data() #-> [{'title':'Product 1', '__total__: 56}, {'title':'Product 2', '__total__: 43}, ]
report.get_report_data() # -> [{'title':'Product 1', '__total__: 56}, {'title':'Product 2', '__total__: 43}, ]
This is just a scratch, for more please visit the documentation
Expand Down
Binary file added docs/source/_static/crosstab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/_static/group_report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/_static/list_view_form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions docs/source/charts.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Charting
---------

Charts settings is a list of objects which each object represent a chart configurations.

* type: what kind of chart it is: Possible options are bar, pie, line and others subject of the underlying charting engine.
Hats off to : `Charts.js <https://www.chartjs.org/>`_.
* engine_name: String, default to ``SLICK_REPORTING_DEFAULT_CHARTS_ENGINE``. Passed to front end in order to use the appropriate chart engine.
By default supports `highcharts` & `chartsjs`.
* data_source: Field name containing the numbers we want to plot.
* title_source: Field name containing labels of the data_source
* title: the Chart title. Defaults to the `report_title`.
* plot_total if True the chart will plot the total of the columns. Useful with time series and crosstab reports.

On front end, for each chart needed we pass the whole response to the relevant chart helper function and it handles the rest.


57 changes: 37 additions & 20 deletions docs/source/concept.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,35 @@ And now, Let's explore the main components of Django Slick Reporting and what se

Components
----------
These are the main components of Django Slick Reporting, ordered from low level to high level:

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

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

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.
It's also responsible for computing and provides low level access. *ie you can get the data in a list of dict/objects*
3. View: A wrapper around the generator exposing the generator options in a FormView that you can hook straight to your urls.
It also provide a Search Form to filter the report on.
It mimics the Generator API interface, so knowing one is enough to work with the other.

3. View: Responsible for creating a nice form to filter the report on, pass those filters to the generator class to create the report.
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.*
4. Charting JS helpers: Django slick Reporting comes with highcharts and Charts js helpers libraries to plot the data generated.


Types of Reports
----------------

1. Time Series: A report that is grouped by a date field, and the report fields are calculated on each group.
For example: Sum of sales per month, Count of sales per day, etc..

2. Cross Tab: shows data in rows and columns with information summarized at the intersection points.
For example: Sum of product sales per month, crosstab by client would show Products as rows, clients included in the crosstab_ids as columns.

3. Grouped: A report that is grouped by a field, and the report fields are calculated on each group.
For example: Sum of sales per product, Count of sales per product, etc..

4. Flat: A report that is not grouped, similar to what an admin list view would show.
For example: Sales Transactions log

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


Settings
Expand All @@ -34,19 +51,19 @@ Settings
.. code-block:: python
SLICK_REPORTING_FORM_MEDIA = {
'css': {
'all': (
'https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.css',
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css',
)
},
'js': (
'https://code.jquery.com/jquery-3.3.1.slim.min.js',
'https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js',
'https://code.highcharts.com/highcharts.js',
)
"css": {
"all": (
"https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.css",
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.css",
)
},
"js": (
"https://code.jquery.com/jquery-3.3.1.slim.min.js",
"https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js",
"https://code.highcharts.com/highcharts.js",
),
}
4. ``SLICK_REPORTING_DEFAULT_CHARTS_ENGINE``: Controls the default chart engine used.
25 changes: 13 additions & 12 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@
import sys
import django

sys.path.insert(0, os.path.abspath('../../'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings'
sys.path.insert(0, os.path.abspath("../../"))
os.environ["DJANGO_SETTINGS_MODULE"] = "tests.settings"
django.setup()

# -- Project information -----------------------------------------------------

project = 'Django Slick Reporting'
copyright = '2020, Ramez Ashraf'
author = 'Ramez Ashraf'
project = "Django Slick Reporting"
copyright = "2020, Ramez Ashraf"
author = "Ramez Ashraf"

master_doc = 'index'
master_doc = "index"

# The full version, including alpha/beta/rc tags
release = '0.6.8'
release = "0.6.8"

# -- General configuration ---------------------------------------------------

Expand All @@ -37,12 +37,13 @@
autosummary_generate = True
autoclass_content = "class"
extensions = [
'sphinx.ext.viewcode', 'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
"sphinx.ext.viewcode",
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

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

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

0 comments on commit 44b4bad

Please sign in to comment.