Skip to content

Commit

Permalink
Merge branch 'release/1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
RamezIssac committed Jul 3, 2023
2 parents 44b4bad + dea2e75 commit e2b2eeb
Show file tree
Hide file tree
Showing 36 changed files with 1,482 additions and 432 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
repos:

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

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

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

## [1.0.0] - 2023-07-03

- Added crosstab_ids_custom_filters to allow custom filters on crosstab ids
- Added ``group_by_querysets`` to allow custom querysets as group
- Added ability to have crosstab report in a time series report
- Enhanced Docs content and structure.

## [0.9.0] - 2023-06-07

- Deprecated ``form_factory`` in favor of ``forms``, to be removed next version.
Expand Down
110 changes: 76 additions & 34 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ Django Slick Reporting

A one stop reports engine with batteries included.

This is project is an extract of the reporting engine of `Django ERP Framework <https://github.com/RamezIssac/django-erp-framework>`_

Features
--------

- Effortlessly create Simple, Grouped, Time series and Crosstab reports in a handful of code lines.
- Create your Custom Calculation easily, which will be integrated with the above reports types
- Create Chart(s) for your reports with a single line of code.
- Create Custom complex Calculation.
- Optimized for speed.
- Batteries included! Highcharts & Chart.js charting capabilities , DataTable.net & easily customizable Bootstrap form.
- Easily extendable.

Installation
------------
Expand All @@ -56,7 +55,7 @@ You can simply use a code like this
# in views.py
from django.db.models import Sum
from slick_reporting.views import ReportView
from slick_reporting.views import ReportView, Chart
from slick_reporting.fields import SlickReportField
from .models import MySalesItems
Expand All @@ -73,24 +72,24 @@ You can simply use a code like this
]
chart_settings = [
{
"type": "column",
"data_source": ["sum__value"],
"plot_total": False,
"title_source": "title",
"title": _("Detailed Columns"),
},
Chart(
"Total sold $",
Chart.BAR,
data_source="value__sum",
title_source="title",
),
]
To get something like this
To get something this

.. image:: https://i.ibb.co/SvxTM23/Selection-294.png
:target: https://i.ibb.co/SvxTM23/Selection-294.png
:alt: Shipped in View Page


You can do a monthly time series :
Time Series
-----------


.. code-block:: python
Expand All @@ -107,44 +106,88 @@ You can do a monthly time series :
group_by = "product"
columns = ["name", "sku"]
# Analogy for time series
time_series_pattern = "monthly"
# Settings for creating time series report
time_series_pattern = (
"monthly" # or "yearly" , "weekly" , "daily" , others and custom patterns
)
time_series_columns = [
SlickReportField.create(Sum, "quantity", name="sum__quantity")
SlickReportField.create(
Sum, "value", verbose_name=_("Sales Value"), name="value"
)
]
chart_settings = [
Chart(
_("Total Sales Monthly"),
Chart.PIE,
data_source=["value"],
title_source=["name"],
plot_total=True,
),
]
This would return a table looking something like this:
.. image:: https://github.com/ra-systems/django-slick-reporting/blob/develop/docs/source/report_view/_static/timeseries.png?raw=true
:alt: Time Series Report
:align: center

Cross Tab
---------

.. code-block:: python
# in views.py
from slick_reporting.views import ReportView
from slick_reporting.fields import SlickReportField
from .models import MySalesItems
class MyCrosstabReport(ReportView):
+--------------+----------------------+-----------------+----------------+-----------------------+-------------------------------+
| Product Name | SKU | Total Quantity | Total Quantity | Total Quantity in ... | Total Quantity in December 20 |
| | | in Jan 20 | in Feb 20 | | |
+--------------+----------------------+-----------------+----------------+-----------------------+-------------------------------+
| Product 1 | <from product model> | 10 | 15 | ... | 14 |
+--------------+----------------------+-----------------+----------------+-----------------------+-------------------------------+
| Product 2 | <from product model> | 11 | 12 | ... | 12 |
+--------------+----------------------+-----------------+----------------+-----------------------+-------------------------------+
| Product 3 | <from product model> | 17 | 12 | ... | 17 |
+--------------+----------------------+-----------------+----------------+-----------------------+-------------------------------+
crosstab_field = "client"
crosstab_ids = [1, 2, 3]
crosstab_columns = [
SlickReportField.create(Sum, "value", verbose_name=_("Value for")),
]
crosstab_compute_remainder = True
*This example code assumes your "MySalesItems" model contains the fields `product` as foreign key, `quantity` as number , and `date_placed` as a date field. It also assumes your `Product` model has an SKU field.. Change those to better suit your structure.*
columns = [
"some_optional_field",
# You can customize where the crosstab columns are displayed in relation to the other columns
"__crosstab__",
# This is the same as the Same as the calculation in the crosstab, but this one will be on the whole set. IE total value
SlickReportField.create(Sum, "value", verbose_name=_("Total Value")),
]
--
.. image:: https://github.com/ra-systems/django-slick-reporting/blob/develop/docs/source/report_view/_static/crosstab.png?raw=true
:alt: Homepage
:align: center

**On a low level**

Low level
---------

The view is a wrapper over the `ReportGenerator` class, which is the core of the reporting engine.
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
report = ReportGenerator(
class MyReport(ReportGenerator):
report_model = MySalesModel
group_by = "product"
columns = ["title", "__total__"]
# OR
my_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}, ]
my_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 Expand Up @@ -183,7 +226,6 @@ This project is young and can use your support.
Some of the ideas / features that ought be added

* Support Other backends like SQL Alchemy & Pandas
* Support Time Series and Crosstab at the same time


Running tests
Expand Down
101 changes: 99 additions & 2 deletions docs/source/charts.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Charting
---------
Charting and Front End Customization
=====================================

Charts Configuration
---------------------

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

Expand All @@ -15,3 +18,97 @@ Charts settings is a list of objects which each object represent a chart configu
On front end, for each chart needed we pass the whole response to the relevant chart helper function and it handles the rest.




The ajax response structure
---------------------------

Understanding how the response is structured is imperative in order to customize how the report is displayed on the front end

Let's have a look

.. code-block:: python
# Ajax response or `report_results` template context variable.
response = {
# the report slug, defaults to the class name all lower
"report_slug": "",
# a list of objects representing the actual results of the report
"data": [
{
"name": "Product 1",
"quantity__sum": "1774",
"value__sum": "8758",
"field_x": "value_x",
},
{
"name": "Product 2",
"quantity__sum": "1878",
"value__sum": "3000",
"field_x": "value_x",
},
# etc .....
],
# A list explaining the columns/keys in the data results.
# ie: len(response.columns) == len(response.data[i].keys())
# It contains needed information about verbose name , if summable and hints about the data type.
"columns": [
{
"name": "name",
"computation_field": "",
"verbose_name": "Name",
"visible": True,
"type": "CharField",
"is_summable": False,
},
{
"name": "quantity__sum",
"computation_field": "",
"verbose_name": "Quantities Sold",
"visible": True,
"type": "number",
"is_summable": True,
},
{
"name": "value__sum",
"computation_field": "",
"verbose_name": "Value $",
"visible": True,
"type": "number",
"is_summable": True,
},
],
# Contains information about the report as whole if it's time series or a a crosstab
# And what's the actual and verbose names of the time series or crosstab specific columns.
"metadata": {
"time_series_pattern": "",
"time_series_column_names": [],
"time_series_column_verbose_names": [],
"crosstab_model": "",
"crosstab_column_names": [],
"crosstab_column_verbose_names": [],
},
# A mirror of the set charts_settings on the ReportView
# ``ReportView`` populates the id and the `engine_name' if not set
"chart_settings": [
{
"type": "pie",
"engine_name": "highcharts",
"data_source": ["quantity__sum"],
"title_source": ["name"],
"title": "Pie Chart (Quantities)",
"id": "pie-0",
},
{
"type": "bar",
"engine_name": "chartsjs",
"data_source": ["value__sum"],
"title_source": ["name"],
"title": "Column Chart (Values)",
"id": "bar-1",
},
],
}
Loading

0 comments on commit e2b2eeb

Please sign in to comment.