Complete Report Examples

Developer guide for the Enezaframework reporting engine. Part of the Add Report series.

Table of Contents

  1. Overview
  2. Complete Invoice Report
  3. Complete Drill-Down Report
  4. Computation Fields with the New API
  5. Related Guides

Overview

These examples combine everything from the topic guides. Copy them as starting points and replace the models with your own.


Complete Invoice Report

python
# myapp/reports.py
from enezareporting.report_base import DocumentReportView
from enezareporting.parameters import ParameterSet, DocumentParam
from myapp.models import Invoice


class InvoiceReport(DocumentReportView):
    report_title = "Sales Invoice"
    header_model = Invoice
    header_fields = [
        "invoice_number", "customer", "date", "due_date",
        "status", "payment_terms",
    ]
    lines_related_name = "lines"
    line_columns = [
        "item_code", "description", "quantity",
        "unit_price", "discount_percent", "line_total",
    ]
    line_total_fields = ["line_total", "quantity"]
    parameter_spec = ParameterSet(
        DocumentParam(name="document_id", model=Invoice),
    )
python
# myapp/urls.py
from django.urls import path
from myapp.reports import InvoiceReport

urlpatterns = [
    path("invoice/", InvoiceReport.as_view(), name="invoice_report"),
]
sequenceDiagram
    actor U as User
    participant V as InvoiceReport
    participant G as DocumentReportGenerator
    participant T as document_report.html

    U->>V: GET /invoice/?document_id=42
    V->>G: get_report_data(42)
    G-->>V: {header, lines, totals}
    V->>T: render(document_header, document_lines, document_totals)
    T-->>U: invoice page

The pk-driven alternative for opening a report directly at /myapp/invoice_report/42/ is covered in Document Report Page View.


Complete Drill-Down Report

python
# myapp/reports.py
from enezareporting.report_types import HierarchyLevel
from enezareporting.report_base import DrillDownReportView
from myapp.models import Region, Branch, SalesPerson


class SalesHierarchy(DrillDownReportView):
    report_title = "Sales Hierarchy"
    max_depth = 3
    hierarchy = [
        HierarchyLevel(
            model=Region,
            display_field="name",
            label="Regions",
            columns=["name", "code"],
        ),
        HierarchyLevel(
            model=Branch,
            display_field="name",
            parent_field="region",
            label="Branches",
            columns=["name", "branch_code", "manager"],
        ),
        HierarchyLevel(
            model=SalesPerson,
            display_field="name",
            parent_field="branch",
            value_field="total_sales",
            aggregation="sum",
            label="Sales People",
            columns=["name", "email", "total_sales"],
        ),
    ]
flowchart TD
    ROOT["Level 0: Regions<br/>?level=0"]
    BRANCH["Level 1: Branches<br/>?level=1&path=1"]
    PERSON["Level 2: Sales People<br/>?level=2&path=1&path=7"]
    ROOT -->|drill region 1| BRANCH
    BRANCH -->|drill branch 7| PERSON

Computation Fields with the New API

python
from enezareporting.fields import ComputationField
from django.db.models import Sum, Avg


# Registered computation fields (use by name):
columns = ["__total__", "__balance__", "__debit__", "__credit__"]


# Custom computation field (use the class directly):
class AvgOrderValue(ComputationField):
    name = "__avg_order__"
    verbose_name = "Avg Order Value"
    calculation_method = Avg
    calculation_field = "value"


# Or create one on the fly:
TotalWeight = ComputationField.create(
    Sum,
    "weight",
    name="total_weight",
    verbose_name="Total Weight",
)