Document Reports (Header & Lines)

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

Table of Contents

  1. Overview
  2. Document Shape
  3. Attributes
  4. Default Parameter
  5. Example
  6. Validation
  7. DocumentReportView vs. BaseDocumentReport
  8. Related Guides

Overview

DocumentReportView renders documents that have a single header and many line items, such as invoices, purchase orders, and vendor statements. The user picks the document through a DocumentParam form field and the report renders the header grid, the lines table, and a totals footer.


Document Shape

erDiagram
    HEADER ||--o{ LINE : "lines_related_name"
    HEADER {
        string header_fields
    }
    LINE {
        string line_columns
    }
    HEADER ||--o{ TOTALS : "line_total_fields"
  • Header — selected by DocumentParam and rendered from header_fields.
  • Lines — fetched through the header instance attribute named by lines_related_name and rendered from line_columns.
  • Totals — the numeric fields in line_total_fields, summed in the footer.

Attributes

Attribute Required Description
header_model Yes Django model for the document header.
header_fields Yes Field names displayed in the header grid.
line_columns Yes Field names used as columns in the lines table.
lines_related_name No Related name on the header for line items (default: "lines").
line_total_fields No Numeric fields to sum in the footer.

Default Parameter

DocumentReportView inherits a default parameter specification from DocumentReport (enezareporting/report_types.py):

python
parameter_spec = ParameterSet(
    DocumentParam(name="document_id"),
)

Set model on the DocumentParam to render a choice field; without it the parameter degrades to a plain integer input (enezareporting/parameters.py:214-233).


Example

python
from enezareporting.report_base import DocumentReportView
from enezareporting.parameters import ParameterSet, DocumentParam
from myapp.models import Invoice


class InvoiceReport(DocumentReportView):
    report_title = "Invoice"
    header_model = Invoice
    header_fields = ["invoice_number", "customer", "date", "due_date", "status"]
    lines_related_name = "lines"
    line_columns = ["item_code", "description", "quantity", "unit_price", "line_total"]
    line_total_fields = ["line_total", "quantity"]
    parameter_spec = ParameterSet(
        DocumentParam(name="document_id", model=Invoice),
    )

Register it like any other report:

python
# myapp/urls.py
from django.urls import path
from myapp.views.reports import InvoiceReport

urlpatterns = [
    path("invoice-report/", InvoiceReport.as_view(), name="invoice_report"),
]

The report can be opened with a preselected document via /myapp/invoice-report/?document_id=42.


Validation

When header_model is set, DocumentReportView raises ImproperlyConfigured at class creation if header_fields or line_columns is empty.


DocumentReportView vs. BaseDocumentReport

Two document-report flows exist. Pick the one that matches your entry point:

DocumentReportView (this guide) BaseDocumentReport
Entry point URL + parameter_spec form URL with <str:pk> (no form)
URL name You define it manually Auto-registered via @auto_url_register
Typical use Standalone report page Print action from a detail view
Guide This document Document Report Page View

The pk-driven flow is documented in Document Report Page View and BaseDocumentReport.