From f2eee7658f2e826b616883f0c9cb30ac0d2837e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Aug 2026 16:13:55 +0000 Subject: [PATCH] docs: add report template concept, flows and reference Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../concepts/definitions/report-template.mdx | 65 +++++++ .../flows/definitions/_category_.json | 5 + .../definitions/create-a-report-template.mdx | 87 +++++++++ .../generate-a-report-from-a-template.mdx | 72 +++++++ .../definitions/report-template.mdx | 176 ++++++++++++++++++ .../references/platform/report.mdx | 1 + .../concepts/definitions/report-template.mdx | 65 +++++++ .../flows/definitions/_category_.json | 5 + .../definitions/create-a-report-template.mdx | 87 +++++++++ .../generate-a-report-from-a-template.mdx | 72 +++++++ .../definitions/report-template.mdx | 176 ++++++++++++++++++ .../references/platform/report.mdx | 1 + versioned_sidebars/version-3.0-sidebars.json | 9 + versioned_sidebars/version-3.1-sidebars.json | 9 + 14 files changed, 830 insertions(+) create mode 100644 versioned_docs/version-3.0/concepts/definitions/report-template.mdx create mode 100644 versioned_docs/version-3.0/flows/definitions/_category_.json create mode 100644 versioned_docs/version-3.0/flows/definitions/create-a-report-template.mdx create mode 100644 versioned_docs/version-3.0/flows/definitions/generate-a-report-from-a-template.mdx create mode 100644 versioned_docs/version-3.0/references/definitions/report-template.mdx create mode 100644 versioned_docs/version-3.1/concepts/definitions/report-template.mdx create mode 100644 versioned_docs/version-3.1/flows/definitions/_category_.json create mode 100644 versioned_docs/version-3.1/flows/definitions/create-a-report-template.mdx create mode 100644 versioned_docs/version-3.1/flows/definitions/generate-a-report-from-a-template.mdx create mode 100644 versioned_docs/version-3.1/references/definitions/report-template.mdx diff --git a/versioned_docs/version-3.0/concepts/definitions/report-template.mdx b/versioned_docs/version-3.0/concepts/definitions/report-template.mdx new file mode 100644 index 00000000..46476355 --- /dev/null +++ b/versioned_docs/version-3.0/concepts/definitions/report-template.mdx @@ -0,0 +1,65 @@ +--- +sidebar_position: 9 +--- + +# Report template + +A **report template** is a reusable document layout that Care fills with real data to produce a report, such as a discharge summary or an account report. A facility authors the template once. Care then generates a report from it for each patient, encounter, or account. + +## Definition + +A report template holds the layout of a printable document and the rules that decide which data Care puts into it. The template stays separate from the reports it produces. + +A report template is specific to Care. It has no equivalent FHIR resource. + +The important distinction: a template is a layout, not a document. Care creates a separate report file each time a user generates a report. A change to the template does not change a report that Care generated before the change. + +A template belongs to one facility, or to the whole deployment. A facility template is visible only inside that facility. A deployment-wide template is visible in every facility. + +## Key Attributes + +| Components | What it captures | +| --- | --- | +| Template Name | The name that users see in the template list. | +| Slug | A short, unique text identifier for the template inside the facility. | +| Description | A short note about the purpose of the template. | +| Status | The stage of the template. See the status table below. | +| Report Type | The kind of report the template produces, such as Discharge Summary. | +| Context | The record that supplies the data, such as an encounter or a patient. | +| Default Format | The output format of the report, PDF or HTML. | +| Template HTML | The layout of the document, with placeholders for the data fields. | + +### Report Type and Context + +The Report Type and the Context must agree with each other. Each report type applies to one kind of record, and the context must supply data for that same kind of record. For example, a Discharge Summary applies to an encounter, so it needs an encounter context. Care refuses a template that pairs a report type with an unrelated context. + +### Status + +| Status | Description | +| --- | --- | +| Draft | The template is in preparation. Users cannot generate reports from the template. | +| Active | The template is published. Users can generate reports from the template. | +| Retired | The template is withdrawn. Users cannot generate reports from the template. | + +## Permissions + +Care grants a permission through a role. A user gets a role in a facility organization, and the permission applies to the facilities under that organization. + +| Permission | Description | System Roles | +| --- | --- | --- | +| Can Read Template | See the template list and open a template. | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | +| Can Create Template on Facility | Create a template, and change a template. | Facility Admin, Admin, Doctor, Nurse | +| Can Preview Template | See a preview of a template with sample data. | Facility Admin, Admin | +| Can View Template Schema | See the list of data fields that a context supplies. | Facility Admin, Admin | +| Can generate report from template | Generate a report from an Active template. | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | + +Only a superuser can create or change a deployment-wide template. + +A user who generates a report also needs read access to the record that supplies the data. For a discharge summary, the user needs access to the encounter. + +## Related + +- Flow: [Create a report template](../../flows/definitions/create-a-report-template.mdx) +- Concept: [Questionnaire](../definitions/questionnaire.mdx) +- Concept: [Encounter](../clinical/encounter.mdx) +- Reference: [Report template](../../references/definitions/report-template.mdx) diff --git a/versioned_docs/version-3.0/flows/definitions/_category_.json b/versioned_docs/version-3.0/flows/definitions/_category_.json new file mode 100644 index 00000000..d30536b2 --- /dev/null +++ b/versioned_docs/version-3.0/flows/definitions/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Definitions & Terminology", + "position": 2, + "key": "definitions-flows" +} diff --git a/versioned_docs/version-3.0/flows/definitions/create-a-report-template.mdx b/versioned_docs/version-3.0/flows/definitions/create-a-report-template.mdx new file mode 100644 index 00000000..bf8d240a --- /dev/null +++ b/versioned_docs/version-3.0/flows/definitions/create-a-report-template.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 1 +--- + +# How to create a report template + +## Overview + +This flow describes how to create a [report template](../../concepts/definitions/report-template.mdx) for a facility in Care. At the end, the facility has a template that users can generate reports from. + +## Pre-requisites + +- You are a member of the facility that the template belongs to. +- You know which record supplies the data for the report, such as an encounter, a patient, or an account. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can Read Template | Open the Templates page, and see the template list. | +| Can Create Template on Facility | Create the template, and save it. | +| Can View Template Schema | See the data fields that a context supplies. | +| Can Preview Template | Preview the template before you publish it. | + +## Steps + +### 1. Open the Templates page + +Go to the facility. Select **Settings** in the facility menu. Select **Templates**. + +### 2. Start a new template + +Select **Create Template**. The template builder opens. + +### 3. Enter the template details + +Fill in the fields at the top of the builder. + +| Components | What it captures | +| --- | --- | +| Template Name | The name that users see in the template list. | +| Slug | A short identifier for the template. Care fills this field from the name. | +| Status | The stage of the template. Select **Draft** while you write it. | +| Default Format | The output format of the report, **PDF** or **HTML**. | +| Report Type | The kind of report, such as **Discharge Summary**. | + +Note: You cannot change the slug after you save the template. + +### 4. Select the context + +Select a context in **Select Context**. The context supplies the data for the report. + +The context must agree with the report type. A Discharge Summary report needs an encounter context. + +### 5. Add the layout + +Write the layout of the document in **Template HTML**. + +Care lists the available data fields below the context. Select a group to see the fields inside it. Select a field to add it at the cursor. + +### 6. Preview the template + +Select **Preview Template**. Care renders the layout with sample values, and shows the result. + +Select **Clear Preview** to go back to the editor. Correct the layout, and preview it again. + +### 7. Publish the template + +Set **Status** to **Active**. Select **Save Template**. + +## Expected Outcome + +- Care confirms that it saved the template. +- The template appears in the template list of the facility. +- Users can generate reports from the template. + +## Related + +Concepts: + +- [Report template](../../concepts/definitions/report-template.mdx) +- [Encounter](../../concepts/clinical/encounter.mdx) + +Flows: + +- [Generate a report from a template](./generate-a-report-from-a-template.mdx) diff --git a/versioned_docs/version-3.0/flows/definitions/generate-a-report-from-a-template.mdx b/versioned_docs/version-3.0/flows/definitions/generate-a-report-from-a-template.mdx new file mode 100644 index 00000000..621d9f87 --- /dev/null +++ b/versioned_docs/version-3.0/flows/definitions/generate-a-report-from-a-template.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 2 +--- + +# How to generate a report from a template + +## Overview + +This flow describes how to generate a report from a [report template](../../concepts/definitions/report-template.mdx) in Care. At the end, the report file is attached to the record, and you can view or download it. + +## Pre-requisites + +- The record that supplies the data exists in Care, such as an encounter, a patient, or an account. +- The facility has an active report template for that kind of record. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can Read Template | See the list of templates that you can use. | +| Can generate report from template | Generate the report. | +| Can Create Template on Facility | Create a template from the list, if none is suitable. | + +Note: To generate a report on an encounter that is complete, you also need the permission to generate a report for a completed encounter. + +## Steps + +### 1. Open the record + +Open the encounter, the patient, or the account that the report is about. + +### 2. Open the Reports tab + +Select **Files**. Select the **Reports** tab. + +Care lists the reports that users already generated for this record. + +### 3. Select a template + +Select **Generate Report**. The **Available Templates** panel opens, and lists the active templates for this kind of record. + +If no template is suitable, select **Create Template** to make one. See [Create a report template](./create-a-report-template.mdx). + +### 4. Generate the report + +Select **Generate Report** on the template that you want. + +Care starts the report, and shows the progress. Only one report can be in progress for a record at a time. + +### 5. Open the report + +Wait until Care confirms that the report is ready. Select **Refresh** if the list does not update. + +Select the report to view it. Select **Download** to save the file. + +## Expected Outcome + +- Care confirms that it generated the report. +- The report appears in the Reports tab of the record. +- You can view, download, or archive the report. + +## Related + +Concepts: + +- [Report template](../../concepts/definitions/report-template.mdx) +- [Encounter](../../concepts/clinical/encounter.mdx) + +Flows: + +- [Create a report template](./create-a-report-template.mdx) diff --git a/versioned_docs/version-3.0/references/definitions/report-template.mdx b/versioned_docs/version-3.0/references/definitions/report-template.mdx new file mode 100644 index 00000000..bdfb7546 --- /dev/null +++ b/versioned_docs/version-3.0/references/definitions/report-template.mdx @@ -0,0 +1,176 @@ +--- +sidebar_position: 9 +--- + +# Report template + +Technical reference for the `Template` model in Care EMR, and for the report generation pipeline that renders it. For the plain-language view, read the [report template concept](../../concepts/definitions/report-template.mdx). + +**Source:** + +- Model: [`report/template.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/report/template.py) +- Resource spec: [`report/template/spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/report/template/spec.py) +- Viewset: [`report/template.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/report/template.py) +- Report types: [`report_types.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/reports/report_types.py) +- Renderer: [`renderer/renderer.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/reports/renderer/renderer.py), [`renderer/template_engine.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/reports/renderer/template_engine.py) + +The model stores the template as plain character fields plus an opaque `options` JSON field. The real constraints live in the Pydantic spec layer, which pins the status and format enums, and validates the compatibility of `template_type`, `context`, and `options`. + +## Models + +| Model | Purpose | +| --- | --- | +| `Template` | A facility-scoped or instance-wide report layout, with its report type, context, output format, and render options | +| `ReportUpload` | One generated report file produced from a `Template`. Documented in [Report & Templates](../platform/report.mdx) | + +`Template` extends `SlugBaseModel`, the facility-scoped slug variant of [`EMRBaseModel`](../foundation/base-model.mdx). The base gives `external_id`, audit fields, `meta`/`history` JSON, and soft delete through `deleted`. + +## `Template` fields + +| Field | Type (model) | Spec constraint | Notes | +| --- | --- | --- | --- | +| `facility` | `FK → Facility (PROTECT, nullable)` | `UUID4 \| None` (write) | Null means instance-wide. Excluded from base serialization through `__exclude__`, resolved server-side on write | +| `slug` | `CharField(255)` | written as `slug_value: SlugType`, read as `slug` plus `slug_config` | Stored with a prefix: `f--` or `i-` | +| `name` | `CharField(255)` | `str`, required | | +| `status` | `CharField(255)` | `TemplateStatusOptions` | See the status values below | +| `template_data` | `TextField` | `str`, required on write | The Jinja2 markup of the layout. Returned only by `TemplateRetrieveSpec` | +| `template_type` | `CharField(255)` | `str`, validated against `ReportTypeRegistry` | See the report type values below | +| `default_format` | `CharField(255)` | `TemplateFormatOptions` | Selects the generator that validates `options` | +| `context` | `CharField(100)`, default `"encounter_base"` | `str`, validated against `DataPointRegistry` | See the context values below | +| `description` | `TextField`, blank, default `""` | `str = ""` | | +| `options` | `JSONField`, default `{}` | `dict = {}`, validated against the generator's `options_model` | Accepted keys depend on `default_format` | + +### `TemplateStatusOptions` values + +| Value | Meaning | +| --- | --- | +| `draft` | In preparation. Report generation rejects the template | +| `active` | Published. Report generation accepts the template | +| `retired` | Withdrawn. Report generation rejects the template | + +### `TemplateFormatOptions` values + +| Value | Generator | Options model | +| --- | --- | --- | +| `pdf` | `WeasyPrintGenerator` | `page_size` (`A4`, `A3`, `A5`, `Letter`, `Legal`), `margin`, `orientation` (`portrait`, `landscape`), `stylesheets` | +| `html` | `HTMLGenerator` | `wrap_document`, `title`, `charset` | + +### Registered report types + +Report types are registered in `report_types.py`. Each one binds a display name, an associating model, and an authorizer class. + +| Key | Display name | Associating model | Authorizer | +| --- | --- | --- | --- | +| `discharge_summary` | Discharge Summary | `Encounter` | `DischargeSummaryReportAuthorizer` | +| `patient_summary` | Patient Summary | `Patient` | `PatientReportAuthorizer` | +| `account_report` | Account Report | `Account` | `AccountReportAuthorizer` | +| `encounter_report` | Encounter Report | `Encounter` | `EncounterReportAuthorizer` | + +### Registered contexts + +Contexts are registered in `DataPointRegistry` by the data point modules under `care/emr/reports/context_builder/data_points/`. + +| Slug | Display name | Context key | Associating model | +| --- | --- | --- | --- | +| `encounter_base` | Encounter Report | `encounter` | `Encounter` | +| `patient_base` | Patient Report | `patient` | `Patient` | +| `account_base` | Account Report | `account` | `Account` | + +A template is valid only when `ReportTypeRegistry.get(template_type).associating_model` equals `DataPointRegistry.get(context).__associating_model__`. + +### `slug_config` shape (read) + +`TemplateReadSpec` parses the stored prefixed slug back into a dict: + +```text +slug_config (facility-scoped) → { facility: , slug_value: } +slug_config (instance-wide) → { slug_value: } +``` + +## Resource specs (API schema) + +| Spec class | Role | Fields and behaviour | +| --- | --- | --- | +| `TemplateBaseSpec` | shared | `id`, `name`, `status`, `default_format`, `description`, `options`. `__exclude__ = ["facility"]` | +| `TemplateCreateSpec` | write · create | Adds `facility`, `slug_value`, `template_data`, `template_type`, `context` | +| `TemplateUpdateSpec` | write · update | Identical to `TemplateCreateSpec` | +| `TemplateReadSpec` | read · list | Base fields plus `slug`, `slug_config`, `template_type`, `context`. No `template_data` | +| `TemplateRetrieveSpec` | read · detail | Extends the read spec with `template_data` and a nested `facility` (`FacilityBareMinimumSpec`) | + +Write-side validation: + +- `template_type` must resolve in `ReportTypeRegistry`, else `Invalid report type`. +- `context` must resolve in `DataPointRegistry`, else `Invalid Context type`. +- `validate_report_type_and_context` compares the two associating models, and raises `Report Type and Context are not compatible` when they differ. +- `options` is validated against `GeneratorRegistry.get(default_format).options_model`. +- `perform_extra_deserialization` resolves the facility external ID, and sets `obj.slug` to the raw `slug_value`. The viewset prefixes the slug afterwards. +- The viewset rejects a duplicate slug in the same scope with `Slug already exists.` + +## Viewset actions and authorization + +`TemplateViewSet` uses `slug` as the lookup field, and supports create, retrieve, update, and list. It filters on `name`, `template_type`, `status`, `facility`, and `facility_only`, and orders by `created_date`, `name`, or `template_type`. + +| Action | Authorization | +| --- | --- | +| `list` (with `facility`) | `can_list_facility_template` → `can_read_template` | +| `list` (without `facility`) | Returns instance-wide templates only | +| `retrieve` | `can_list_facility_template` for a facility template | +| `create`, `update` | `can_write_facility_template` → `can_write_template`, checked at the facility root. A template with no facility needs a superuser | +| `GET schema` | `can_view_template_schema` | +| `POST preview` | `can_preview_template` | + +The permissions and their roles are defined in [`permissions/template.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/permissions/template.py). + +| Permission | Display name | Roles | +| --- | --- | --- | +| `can_read_template` | Can Read Template | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | +| `can_write_template` | Can Create Template on Facility | Facility Admin, Admin, Doctor, Nurse | +| `can_preview_template` | Can Preview Template | Facility Admin, Admin | +| `can_view_template_schema` | Can View Template Schema | Facility Admin, Admin | +| `can_generate_report_from_template` | Can generate report from template | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | + +## Rendering pipeline + +`Renderer` combines a generator with `TemplateEngine`. + +- `TemplateEngine` uses a Jinja2 `SandboxedEnvironment` with `StrictUndefined` and autoescape. `trim_blocks` and `lstrip_blocks` are on. +- Filters: `date`, `datetime`, `time`, `currency`, `phone`. +- Globals: `current_date`, `current_datetime`, `current_time`. +- The generator turns the rendered HTML into the output bytes. `WeasyPrintGenerator` produces the PDF; `HTMLGenerator` returns the HTML, and wraps it in a document when `wrap_document` is true. + +`GET /schema` returns the contexts, output formats, custom types, and report types the builder needs. Each context lists its fields with a display name, a type, and a preview value. + +`POST /preview` renders `template_data` against a preview context that carries sample values, and returns the rendered file. The preview does not read patient data. + +## Report generation + +`ReportUploadViewSet.generate` creates the report file. It runs these checks in order: + +1. Resolves the `Template` from `template_id`. +2. Calls the report type's authorizer for write access on `associating_id`. +3. Checks `can_generate_report_from_template` on the template's facility. +4. Rejects the request when `template.status` is not `active`, with `Template is not active`. +5. Returns HTTP 409 when a generation for the same report type and associating ID is already in progress. `force` clears the lock, and `status_check` returns the progress instead. + +Generation then runs in the `generate_report_task` Celery task, which reports progress and creates a `ReportUpload`. + +`care/security/permissions/template.py` also defines `can_generate_report_for_completed_encounter`, granted to Facility Admin and Admin. The encounter authorization module uses it to allow a report on a completed encounter. + +## API integration notes + +- `template_data` is Jinja2 markup, rendered in a sandbox. An undefined variable fails the render. +- `template_data` is returned only on retrieve, not in the list response. +- `slug` is immutable in the frontend builder after creation. +- `options` is validated server-side against the format generator, so the accepted keys change with `default_format`. +- A template with no facility is instance-wide, and only a superuser can write it. +- A list request without a `facility` query parameter returns instance-wide templates only. With `facility_only=true`, the response holds facility templates only. + +## Related + +- Concept: [Report template](../../concepts/definitions/report-template.mdx) +- Flow: [Create a report template](../../flows/definitions/create-a-report-template.mdx) +- Reference: [Report & Templates](../platform/report.mdx) +- Reference: [Encounter](../clinical/encounter.mdx) +- Reference: [Facility](../facility/facility.mdx) +- Reference: [Base model](../foundation/base-model.mdx) +- Source: [template.py](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/report/template.py), [template/spec.py](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/report/template/spec.py) diff --git a/versioned_docs/version-3.0/references/platform/report.mdx b/versioned_docs/version-3.0/references/platform/report.mdx index f872e605..94029112 100644 --- a/versioned_docs/version-3.0/references/platform/report.mdx +++ b/versioned_docs/version-3.0/references/platform/report.mdx @@ -190,6 +190,7 @@ Alias for `report_type`, kept for compatibility with `S3FilesManager`. ## Related +- Reference: [Report template](../definitions/report-template.mdx) - Reference: [File Upload](../platform/file-upload.mdx) - Reference: [Encounter](../clinical/encounter.mdx) - Reference: [Facility](../facility/facility.mdx) diff --git a/versioned_docs/version-3.1/concepts/definitions/report-template.mdx b/versioned_docs/version-3.1/concepts/definitions/report-template.mdx new file mode 100644 index 00000000..46476355 --- /dev/null +++ b/versioned_docs/version-3.1/concepts/definitions/report-template.mdx @@ -0,0 +1,65 @@ +--- +sidebar_position: 9 +--- + +# Report template + +A **report template** is a reusable document layout that Care fills with real data to produce a report, such as a discharge summary or an account report. A facility authors the template once. Care then generates a report from it for each patient, encounter, or account. + +## Definition + +A report template holds the layout of a printable document and the rules that decide which data Care puts into it. The template stays separate from the reports it produces. + +A report template is specific to Care. It has no equivalent FHIR resource. + +The important distinction: a template is a layout, not a document. Care creates a separate report file each time a user generates a report. A change to the template does not change a report that Care generated before the change. + +A template belongs to one facility, or to the whole deployment. A facility template is visible only inside that facility. A deployment-wide template is visible in every facility. + +## Key Attributes + +| Components | What it captures | +| --- | --- | +| Template Name | The name that users see in the template list. | +| Slug | A short, unique text identifier for the template inside the facility. | +| Description | A short note about the purpose of the template. | +| Status | The stage of the template. See the status table below. | +| Report Type | The kind of report the template produces, such as Discharge Summary. | +| Context | The record that supplies the data, such as an encounter or a patient. | +| Default Format | The output format of the report, PDF or HTML. | +| Template HTML | The layout of the document, with placeholders for the data fields. | + +### Report Type and Context + +The Report Type and the Context must agree with each other. Each report type applies to one kind of record, and the context must supply data for that same kind of record. For example, a Discharge Summary applies to an encounter, so it needs an encounter context. Care refuses a template that pairs a report type with an unrelated context. + +### Status + +| Status | Description | +| --- | --- | +| Draft | The template is in preparation. Users cannot generate reports from the template. | +| Active | The template is published. Users can generate reports from the template. | +| Retired | The template is withdrawn. Users cannot generate reports from the template. | + +## Permissions + +Care grants a permission through a role. A user gets a role in a facility organization, and the permission applies to the facilities under that organization. + +| Permission | Description | System Roles | +| --- | --- | --- | +| Can Read Template | See the template list and open a template. | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | +| Can Create Template on Facility | Create a template, and change a template. | Facility Admin, Admin, Doctor, Nurse | +| Can Preview Template | See a preview of a template with sample data. | Facility Admin, Admin | +| Can View Template Schema | See the list of data fields that a context supplies. | Facility Admin, Admin | +| Can generate report from template | Generate a report from an Active template. | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | + +Only a superuser can create or change a deployment-wide template. + +A user who generates a report also needs read access to the record that supplies the data. For a discharge summary, the user needs access to the encounter. + +## Related + +- Flow: [Create a report template](../../flows/definitions/create-a-report-template.mdx) +- Concept: [Questionnaire](../definitions/questionnaire.mdx) +- Concept: [Encounter](../clinical/encounter.mdx) +- Reference: [Report template](../../references/definitions/report-template.mdx) diff --git a/versioned_docs/version-3.1/flows/definitions/_category_.json b/versioned_docs/version-3.1/flows/definitions/_category_.json new file mode 100644 index 00000000..d30536b2 --- /dev/null +++ b/versioned_docs/version-3.1/flows/definitions/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Definitions & Terminology", + "position": 2, + "key": "definitions-flows" +} diff --git a/versioned_docs/version-3.1/flows/definitions/create-a-report-template.mdx b/versioned_docs/version-3.1/flows/definitions/create-a-report-template.mdx new file mode 100644 index 00000000..bf8d240a --- /dev/null +++ b/versioned_docs/version-3.1/flows/definitions/create-a-report-template.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 1 +--- + +# How to create a report template + +## Overview + +This flow describes how to create a [report template](../../concepts/definitions/report-template.mdx) for a facility in Care. At the end, the facility has a template that users can generate reports from. + +## Pre-requisites + +- You are a member of the facility that the template belongs to. +- You know which record supplies the data for the report, such as an encounter, a patient, or an account. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can Read Template | Open the Templates page, and see the template list. | +| Can Create Template on Facility | Create the template, and save it. | +| Can View Template Schema | See the data fields that a context supplies. | +| Can Preview Template | Preview the template before you publish it. | + +## Steps + +### 1. Open the Templates page + +Go to the facility. Select **Settings** in the facility menu. Select **Templates**. + +### 2. Start a new template + +Select **Create Template**. The template builder opens. + +### 3. Enter the template details + +Fill in the fields at the top of the builder. + +| Components | What it captures | +| --- | --- | +| Template Name | The name that users see in the template list. | +| Slug | A short identifier for the template. Care fills this field from the name. | +| Status | The stage of the template. Select **Draft** while you write it. | +| Default Format | The output format of the report, **PDF** or **HTML**. | +| Report Type | The kind of report, such as **Discharge Summary**. | + +Note: You cannot change the slug after you save the template. + +### 4. Select the context + +Select a context in **Select Context**. The context supplies the data for the report. + +The context must agree with the report type. A Discharge Summary report needs an encounter context. + +### 5. Add the layout + +Write the layout of the document in **Template HTML**. + +Care lists the available data fields below the context. Select a group to see the fields inside it. Select a field to add it at the cursor. + +### 6. Preview the template + +Select **Preview Template**. Care renders the layout with sample values, and shows the result. + +Select **Clear Preview** to go back to the editor. Correct the layout, and preview it again. + +### 7. Publish the template + +Set **Status** to **Active**. Select **Save Template**. + +## Expected Outcome + +- Care confirms that it saved the template. +- The template appears in the template list of the facility. +- Users can generate reports from the template. + +## Related + +Concepts: + +- [Report template](../../concepts/definitions/report-template.mdx) +- [Encounter](../../concepts/clinical/encounter.mdx) + +Flows: + +- [Generate a report from a template](./generate-a-report-from-a-template.mdx) diff --git a/versioned_docs/version-3.1/flows/definitions/generate-a-report-from-a-template.mdx b/versioned_docs/version-3.1/flows/definitions/generate-a-report-from-a-template.mdx new file mode 100644 index 00000000..621d9f87 --- /dev/null +++ b/versioned_docs/version-3.1/flows/definitions/generate-a-report-from-a-template.mdx @@ -0,0 +1,72 @@ +--- +sidebar_position: 2 +--- + +# How to generate a report from a template + +## Overview + +This flow describes how to generate a report from a [report template](../../concepts/definitions/report-template.mdx) in Care. At the end, the report file is attached to the record, and you can view or download it. + +## Pre-requisites + +- The record that supplies the data exists in Care, such as an encounter, a patient, or an account. +- The facility has an active report template for that kind of record. +- You have the permissions listed below. + +## Permissions + +| Permission | Access | +| --- | --- | +| Can Read Template | See the list of templates that you can use. | +| Can generate report from template | Generate the report. | +| Can Create Template on Facility | Create a template from the list, if none is suitable. | + +Note: To generate a report on an encounter that is complete, you also need the permission to generate a report for a completed encounter. + +## Steps + +### 1. Open the record + +Open the encounter, the patient, or the account that the report is about. + +### 2. Open the Reports tab + +Select **Files**. Select the **Reports** tab. + +Care lists the reports that users already generated for this record. + +### 3. Select a template + +Select **Generate Report**. The **Available Templates** panel opens, and lists the active templates for this kind of record. + +If no template is suitable, select **Create Template** to make one. See [Create a report template](./create-a-report-template.mdx). + +### 4. Generate the report + +Select **Generate Report** on the template that you want. + +Care starts the report, and shows the progress. Only one report can be in progress for a record at a time. + +### 5. Open the report + +Wait until Care confirms that the report is ready. Select **Refresh** if the list does not update. + +Select the report to view it. Select **Download** to save the file. + +## Expected Outcome + +- Care confirms that it generated the report. +- The report appears in the Reports tab of the record. +- You can view, download, or archive the report. + +## Related + +Concepts: + +- [Report template](../../concepts/definitions/report-template.mdx) +- [Encounter](../../concepts/clinical/encounter.mdx) + +Flows: + +- [Create a report template](./create-a-report-template.mdx) diff --git a/versioned_docs/version-3.1/references/definitions/report-template.mdx b/versioned_docs/version-3.1/references/definitions/report-template.mdx new file mode 100644 index 00000000..bdfb7546 --- /dev/null +++ b/versioned_docs/version-3.1/references/definitions/report-template.mdx @@ -0,0 +1,176 @@ +--- +sidebar_position: 9 +--- + +# Report template + +Technical reference for the `Template` model in Care EMR, and for the report generation pipeline that renders it. For the plain-language view, read the [report template concept](../../concepts/definitions/report-template.mdx). + +**Source:** + +- Model: [`report/template.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/report/template.py) +- Resource spec: [`report/template/spec.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/report/template/spec.py) +- Viewset: [`report/template.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/api/viewsets/report/template.py) +- Report types: [`report_types.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/reports/report_types.py) +- Renderer: [`renderer/renderer.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/reports/renderer/renderer.py), [`renderer/template_engine.py`](https://github.com/ohcnetwork/care/blob/develop/care/emr/reports/renderer/template_engine.py) + +The model stores the template as plain character fields plus an opaque `options` JSON field. The real constraints live in the Pydantic spec layer, which pins the status and format enums, and validates the compatibility of `template_type`, `context`, and `options`. + +## Models + +| Model | Purpose | +| --- | --- | +| `Template` | A facility-scoped or instance-wide report layout, with its report type, context, output format, and render options | +| `ReportUpload` | One generated report file produced from a `Template`. Documented in [Report & Templates](../platform/report.mdx) | + +`Template` extends `SlugBaseModel`, the facility-scoped slug variant of [`EMRBaseModel`](../foundation/base-model.mdx). The base gives `external_id`, audit fields, `meta`/`history` JSON, and soft delete through `deleted`. + +## `Template` fields + +| Field | Type (model) | Spec constraint | Notes | +| --- | --- | --- | --- | +| `facility` | `FK → Facility (PROTECT, nullable)` | `UUID4 \| None` (write) | Null means instance-wide. Excluded from base serialization through `__exclude__`, resolved server-side on write | +| `slug` | `CharField(255)` | written as `slug_value: SlugType`, read as `slug` plus `slug_config` | Stored with a prefix: `f--` or `i-` | +| `name` | `CharField(255)` | `str`, required | | +| `status` | `CharField(255)` | `TemplateStatusOptions` | See the status values below | +| `template_data` | `TextField` | `str`, required on write | The Jinja2 markup of the layout. Returned only by `TemplateRetrieveSpec` | +| `template_type` | `CharField(255)` | `str`, validated against `ReportTypeRegistry` | See the report type values below | +| `default_format` | `CharField(255)` | `TemplateFormatOptions` | Selects the generator that validates `options` | +| `context` | `CharField(100)`, default `"encounter_base"` | `str`, validated against `DataPointRegistry` | See the context values below | +| `description` | `TextField`, blank, default `""` | `str = ""` | | +| `options` | `JSONField`, default `{}` | `dict = {}`, validated against the generator's `options_model` | Accepted keys depend on `default_format` | + +### `TemplateStatusOptions` values + +| Value | Meaning | +| --- | --- | +| `draft` | In preparation. Report generation rejects the template | +| `active` | Published. Report generation accepts the template | +| `retired` | Withdrawn. Report generation rejects the template | + +### `TemplateFormatOptions` values + +| Value | Generator | Options model | +| --- | --- | --- | +| `pdf` | `WeasyPrintGenerator` | `page_size` (`A4`, `A3`, `A5`, `Letter`, `Legal`), `margin`, `orientation` (`portrait`, `landscape`), `stylesheets` | +| `html` | `HTMLGenerator` | `wrap_document`, `title`, `charset` | + +### Registered report types + +Report types are registered in `report_types.py`. Each one binds a display name, an associating model, and an authorizer class. + +| Key | Display name | Associating model | Authorizer | +| --- | --- | --- | --- | +| `discharge_summary` | Discharge Summary | `Encounter` | `DischargeSummaryReportAuthorizer` | +| `patient_summary` | Patient Summary | `Patient` | `PatientReportAuthorizer` | +| `account_report` | Account Report | `Account` | `AccountReportAuthorizer` | +| `encounter_report` | Encounter Report | `Encounter` | `EncounterReportAuthorizer` | + +### Registered contexts + +Contexts are registered in `DataPointRegistry` by the data point modules under `care/emr/reports/context_builder/data_points/`. + +| Slug | Display name | Context key | Associating model | +| --- | --- | --- | --- | +| `encounter_base` | Encounter Report | `encounter` | `Encounter` | +| `patient_base` | Patient Report | `patient` | `Patient` | +| `account_base` | Account Report | `account` | `Account` | + +A template is valid only when `ReportTypeRegistry.get(template_type).associating_model` equals `DataPointRegistry.get(context).__associating_model__`. + +### `slug_config` shape (read) + +`TemplateReadSpec` parses the stored prefixed slug back into a dict: + +```text +slug_config (facility-scoped) → { facility: , slug_value: } +slug_config (instance-wide) → { slug_value: } +``` + +## Resource specs (API schema) + +| Spec class | Role | Fields and behaviour | +| --- | --- | --- | +| `TemplateBaseSpec` | shared | `id`, `name`, `status`, `default_format`, `description`, `options`. `__exclude__ = ["facility"]` | +| `TemplateCreateSpec` | write · create | Adds `facility`, `slug_value`, `template_data`, `template_type`, `context` | +| `TemplateUpdateSpec` | write · update | Identical to `TemplateCreateSpec` | +| `TemplateReadSpec` | read · list | Base fields plus `slug`, `slug_config`, `template_type`, `context`. No `template_data` | +| `TemplateRetrieveSpec` | read · detail | Extends the read spec with `template_data` and a nested `facility` (`FacilityBareMinimumSpec`) | + +Write-side validation: + +- `template_type` must resolve in `ReportTypeRegistry`, else `Invalid report type`. +- `context` must resolve in `DataPointRegistry`, else `Invalid Context type`. +- `validate_report_type_and_context` compares the two associating models, and raises `Report Type and Context are not compatible` when they differ. +- `options` is validated against `GeneratorRegistry.get(default_format).options_model`. +- `perform_extra_deserialization` resolves the facility external ID, and sets `obj.slug` to the raw `slug_value`. The viewset prefixes the slug afterwards. +- The viewset rejects a duplicate slug in the same scope with `Slug already exists.` + +## Viewset actions and authorization + +`TemplateViewSet` uses `slug` as the lookup field, and supports create, retrieve, update, and list. It filters on `name`, `template_type`, `status`, `facility`, and `facility_only`, and orders by `created_date`, `name`, or `template_type`. + +| Action | Authorization | +| --- | --- | +| `list` (with `facility`) | `can_list_facility_template` → `can_read_template` | +| `list` (without `facility`) | Returns instance-wide templates only | +| `retrieve` | `can_list_facility_template` for a facility template | +| `create`, `update` | `can_write_facility_template` → `can_write_template`, checked at the facility root. A template with no facility needs a superuser | +| `GET schema` | `can_view_template_schema` | +| `POST preview` | `can_preview_template` | + +The permissions and their roles are defined in [`permissions/template.py`](https://github.com/ohcnetwork/care/blob/develop/care/security/permissions/template.py). + +| Permission | Display name | Roles | +| --- | --- | --- | +| `can_read_template` | Can Read Template | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | +| `can_write_template` | Can Create Template on Facility | Facility Admin, Admin, Doctor, Nurse | +| `can_preview_template` | Can Preview Template | Facility Admin, Admin | +| `can_view_template_schema` | Can View Template Schema | Facility Admin, Admin | +| `can_generate_report_from_template` | Can generate report from template | Facility Admin, Administrator, Admin, Staff, Doctor, Nurse, Volunteer, Pharmacist | + +## Rendering pipeline + +`Renderer` combines a generator with `TemplateEngine`. + +- `TemplateEngine` uses a Jinja2 `SandboxedEnvironment` with `StrictUndefined` and autoescape. `trim_blocks` and `lstrip_blocks` are on. +- Filters: `date`, `datetime`, `time`, `currency`, `phone`. +- Globals: `current_date`, `current_datetime`, `current_time`. +- The generator turns the rendered HTML into the output bytes. `WeasyPrintGenerator` produces the PDF; `HTMLGenerator` returns the HTML, and wraps it in a document when `wrap_document` is true. + +`GET /schema` returns the contexts, output formats, custom types, and report types the builder needs. Each context lists its fields with a display name, a type, and a preview value. + +`POST /preview` renders `template_data` against a preview context that carries sample values, and returns the rendered file. The preview does not read patient data. + +## Report generation + +`ReportUploadViewSet.generate` creates the report file. It runs these checks in order: + +1. Resolves the `Template` from `template_id`. +2. Calls the report type's authorizer for write access on `associating_id`. +3. Checks `can_generate_report_from_template` on the template's facility. +4. Rejects the request when `template.status` is not `active`, with `Template is not active`. +5. Returns HTTP 409 when a generation for the same report type and associating ID is already in progress. `force` clears the lock, and `status_check` returns the progress instead. + +Generation then runs in the `generate_report_task` Celery task, which reports progress and creates a `ReportUpload`. + +`care/security/permissions/template.py` also defines `can_generate_report_for_completed_encounter`, granted to Facility Admin and Admin. The encounter authorization module uses it to allow a report on a completed encounter. + +## API integration notes + +- `template_data` is Jinja2 markup, rendered in a sandbox. An undefined variable fails the render. +- `template_data` is returned only on retrieve, not in the list response. +- `slug` is immutable in the frontend builder after creation. +- `options` is validated server-side against the format generator, so the accepted keys change with `default_format`. +- A template with no facility is instance-wide, and only a superuser can write it. +- A list request without a `facility` query parameter returns instance-wide templates only. With `facility_only=true`, the response holds facility templates only. + +## Related + +- Concept: [Report template](../../concepts/definitions/report-template.mdx) +- Flow: [Create a report template](../../flows/definitions/create-a-report-template.mdx) +- Reference: [Report & Templates](../platform/report.mdx) +- Reference: [Encounter](../clinical/encounter.mdx) +- Reference: [Facility](../facility/facility.mdx) +- Reference: [Base model](../foundation/base-model.mdx) +- Source: [template.py](https://github.com/ohcnetwork/care/blob/develop/care/emr/models/report/template.py), [template/spec.py](https://github.com/ohcnetwork/care/blob/develop/care/emr/resources/report/template/spec.py) diff --git a/versioned_docs/version-3.1/references/platform/report.mdx b/versioned_docs/version-3.1/references/platform/report.mdx index f872e605..94029112 100644 --- a/versioned_docs/version-3.1/references/platform/report.mdx +++ b/versioned_docs/version-3.1/references/platform/report.mdx @@ -190,6 +190,7 @@ Alias for `report_type`, kept for compatibility with `S3FilesManager`. ## Related +- Reference: [Report template](../definitions/report-template.mdx) - Reference: [File Upload](../platform/file-upload.mdx) - Reference: [Encounter](../clinical/encounter.mdx) - Reference: [Facility](../facility/facility.mdx) diff --git a/versioned_sidebars/version-3.0-sidebars.json b/versioned_sidebars/version-3.0-sidebars.json index d253abeb..6896cd78 100644 --- a/versioned_sidebars/version-3.0-sidebars.json +++ b/versioned_sidebars/version-3.0-sidebars.json @@ -22,6 +22,15 @@ "label": "Clinical", "key": "clinical-flows", "items": ["flows/clinical/create-patient", "flows/clinical/manage-encounter-care-team"] + }, + { + "type": "category", + "label": "Definitions & Terminology", + "key": "definitions-flows", + "items": [ + "flows/definitions/create-a-report-template", + "flows/definitions/generate-a-report-from-a-template" + ] } ] }, diff --git a/versioned_sidebars/version-3.1-sidebars.json b/versioned_sidebars/version-3.1-sidebars.json index ffc66fb9..3e4d2bfd 100644 --- a/versioned_sidebars/version-3.1-sidebars.json +++ b/versioned_sidebars/version-3.1-sidebars.json @@ -40,6 +40,15 @@ }, "flows/clinical/manage-encounter-care-team" ] + }, + { + "type": "category", + "label": "Definitions & Terminology", + "key": "definitions-flows", + "items": [ + "flows/definitions/create-a-report-template", + "flows/definitions/generate-a-report-from-a-template" + ] } ] },