More docs! w/ some emphasis on "reports" section

This commit is contained in:
Lance Edgar 2021-01-15 15:16:23 -06:00
parent 2072e41e19
commit da9823324d
38 changed files with 358 additions and 71 deletions

View file

@ -0,0 +1,6 @@
====================
Auto-Emailed Reports
====================
TODO

View file

@ -0,0 +1,81 @@
========================
Adding a Custom Report
========================
We'll start with a simple report which shows all departments and the number of
products for each.
Each type of report has a "key" which uniquely identifies it. For this example
we'll use ``poser_dept_prod_counts`` for the key. Note that it's a good idea
to always use an app-specific prefix (e.g. ``poser_``) in the key.
Typically you will create a new Python module which is named according to the
key. Here we'll create ``~/src/poser/poser/reports/dept_prod_counts.py``, and
in it we'll define the report::
from sqlalchemy import orm
from rattail.reporting import ExcelReport
class DepartmentProductCounts(ExcelReport):
"""
Shows all departments and the number of products for each.
"""
type_key = 'poser_dept_prod_counts'
name = "Department Product Counts"
output_fields = [
'department_number',
'department_name',
'product_count',
]
def make_data(self, session, params, progress=None, **kwargs):
model = self.model
# fetch all departments, with product lists pre-loaded
departments = session.query(model.Department)\
.order_by(model.Department.number)\
.options(orm.joinedload(model.Department.products))\
.all()
rows = []
def add_row(department, i):
rows.append({
'department_number': department.number,
'department_name': department.name,
'product_count': len(department.products),
})
self.progress_loop(add_row, departments, progress,
message="Fetching data for report")
return rows
Then you must register your new report type, to make it available to the app.
This is done within your project's ``setup.py`` file, for instance::
setup(
name = "Poser",
# ...
entry_points = {
'rattail.reports': [
'poser_dept_prod_counts = poser.reports.dept_prod_counts:DepartmentProductCounts',
],
},
)
Once you've added that you must re-install the app to your virtual environment,
for instance:
.. code-block:: sh
cd /srv/envs/poser
source bin/activate
pip install -e ~/src/poser
At this point the report should be available for running within the app. See
:doc:`generate` for more info.

View file

@ -0,0 +1,6 @@
===================
Generating a Report
===================
TODO

View file

@ -0,0 +1,19 @@
==============
Report Handler
==============
Each app will have exactly one "report handler" which is reponsible for the
overall logic of running and emailing reports etc. It also determines which
report types are available to be ran.
Rattail provides a default report handler so unless you have custom
requirements, you will not need to define your own report handler. See the
:class:`~rattail:rattail.reporting.handlers.ReportHandler` class for more
details.
Programmatically you can access your report handler like so::
# assuming you already have config
app = config.get_app()
handler = app.get_report_handler()

View file

@ -0,0 +1,13 @@
Reports
=======
.. toctree::
:maxdepth: 2
:caption: Contents:
overview
handler
generate
autoemail
custom

View file

@ -0,0 +1,28 @@
==========
Overview
==========
A report is conceptually just what you think it is, probably. But there are a
few related concepts which we'll try to briefly outline here.
* report type
* report handler
* report output
First a "report type" refers to the logic for running a specific type of
report. For example, "Daily Sales" or "Slow Movers" might be report types.
This defines what sort of data is included on the report, how it is displayed
etc. See :doc:`custom` for how to create a new report type.
Next, a "report handler" is responsible for overall logic used to orchestrate
the running of all reports for the app. See :doc:`handler` for more on that.
Finally "report output" refers to the result of running a report. Generally
speaking whenever a report runs, the details are saved to the DB for
convenience and historical record. See :doc:`generate` for more on that.
It's perhaps worth noting, that in Rattail-speak "an email is not a report" and
vice versa. Meaning, a report is a *generated document* and if sent via email,
it will be an attachment as opposed to being part of the message body. See
also :doc:`autoemail`.