Skip to content

Commit e030f03

Browse files
authored
Add project reports reference doc & enable mermaid diagrams (#4503)
- Document the key functionalities, features and known limitations of reporting module. - Enable mermaid diagrams Reviewers: - Report anything that feels wrong - Switch to GitHub's rich diff to view rendered diagrams. ![Screenshot 2025-04-17 at 7  03 08@2x](https://github.com/user-attachments/assets/6430458a-bab2-4edf-9969-b0f9b099ed61)
1 parent 90ce66a commit e030f03

File tree

2 files changed

+176
-1
lines changed

2 files changed

+176
-1
lines changed

docs/references/project-reports.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Project Reports
2+
3+
The `hypha.apply.projects.reports` app provides functionality for managing periodic progress or financial reports associated with funded projects within the Hypha platform. It allows administrators to configure reporting schedules, project owners to submit reports using dynamic forms, and staff to track reporting status, view submitted reports, and manage the reporting lifecycle.
4+
5+
## Key Functionalities
6+
7+
- **Staff:** Configure reporting frequency, enable/disable reporting, view reporting status across projects, view submitted reports, edit submitted reports, skip reports, receive notifications.
8+
- **Project Owners:** View reporting schedule, submit new reports, save draft reports, view their submitted reports, receive notifications.
9+
- **Finance:** View submitted reports, view reporting status across projects.
10+
- **System:** Automatically calculates reporting periods, sends due date reminders.
11+
12+
```mermaid
13+
---
14+
title: Reporting module
15+
---
16+
erDiagram
17+
18+
Project ||--|| ReportConfig : "has one"
19+
Project ||--o{ Report : "has many"
20+
Report ||--o| ReportVersion : "current"
21+
Report ||--o| ReportVersion : "draft"
22+
ReportVersion }o--|| User : "authored by"
23+
ReportVersion ||..o{ ReportPrivateFiles : "has many"
24+
25+
ReportConfig {
26+
date schedule_start
27+
int occurrence
28+
string frequency
29+
boolean disable_reporting
30+
boolean does_not_repeat
31+
}
32+
33+
Report {
34+
date end_date
35+
StreamField form_fields
36+
json form_data
37+
boolean skipped
38+
datetime submitted
39+
datetime notified
40+
int current_id FK
41+
int draft_id FK
42+
}
43+
44+
ReportVersion {
45+
datetime submitted
46+
json form_data
47+
boolean draft
48+
int author_id FK
49+
}
50+
```
51+
52+
## Key Features
53+
54+
### Configurable Reporting Schedules
55+
56+
- **Frequency:** Define how often reports are due (Weeks, Months, Years).
57+
- **Occurrence:** Specify the interval (e.g., every 2 weeks, every 3 months).
58+
- **Start Date:** Set a specific date for the reporting schedule to commence or adjust.
59+
- **One-Time Reporting:** Configure reports that do not repeat (`does_not_repeat`).
60+
- **Enable/Disable:** Ability to completely disable reporting for a project.
61+
- **Dynamic Calculation:** Automatically calculates the next due date based on the configuration and the last submitted report or project start date.
62+
- Implemented via `ReportConfig`
63+
64+
### Dynamic Report Forms
65+
66+
- Reports utilize Hypha's `StreamField` functionality, allowing report forms to be dynamically constructed using various field types (text, numbers, dates, files, etc.).
67+
- The specific form structure (`form_fields`) used for a report is associated with the `Report` model instance, often derived from a `ProjectReportForm` configured at the Fund level.
68+
- Submitted data (`form_data`) is stored as JSON.
69+
- Implemented via `Report`, `ReportEditForm` and `StreamField`
70+
71+
### Report Submission Workflow
72+
73+
- Project owners (and staff) can fill and submit reports corresponding to specific reporting periods.
74+
- **Draft Mode:** Reports can be saved as drafts before final submission. The latest draft is stored separately (`Report.draft`).
75+
- **Versioning:** Each submission creates a `ReportVersion`, storing the submitted data, timestamp, and author. The currently active submission is linked via `Report.current`.
76+
- Implemented via `ReportUpdateView` and `ReportEditForm`
77+
78+
```mermaid
79+
stateDiagram-v2
80+
[*] --> Due : System identifies upcoming report period
81+
Draft --> Submitted : User submits
82+
Due --> Draft : User saves<br>as draft
83+
Draft --> Due : User discards draft (implicitly)
84+
Skipped --> Due : Staff unskips
85+
Due --> Skipped : Staff skips
86+
Due --> Submitted : User submits (no draft)
87+
88+
89+
note right of Submitted
90+
Creates ReportVersion.
91+
Updates Report.current.
92+
Final state unless edited by Staff.
93+
end note
94+
note right of Draft
95+
Stores data in Report.draft.
96+
Not yet submitted.
97+
end note
98+
note right of Skipped
99+
Report explicitly marked as not required.
100+
Final state unless unskipped.
101+
end note
102+
```
103+
104+
### Access Control & Permissions
105+
106+
- Granular permissions control who can perform actions:
107+
- `view_report`: Staff, Finance users, and the Project Owner can view submitted reports (if project status allows and report is not skipped).
108+
- `update_report`: Staff and the Project Owner (only before initial submission) can edit/submit reports (if project status allows, report isn't skipped, and it's submittable).
109+
- `update_report_config`: Staff can modify the reporting schedule (if project status allows and it's not a completed one-time report).
110+
- Views enforce these permissions, raising `PermissionDenied` if rules aren't met.
111+
- Implemented via `permissions.py` and Views
112+
113+
### Report Skipping
114+
115+
- Staff members have the ability to mark a due report as "skipped".
116+
- This action can be undone. Skipping is generally only allowed for reports that haven't been submitted and aren't the *very next* one due according to the config.
117+
- Implemented via `ReportSkipView`
118+
119+
### Status Tracking & Notifications
120+
121+
- **Due Dates:** Reports have calculated `start_date` and `end_date` for their period.
122+
- **Status:** Reports can be implicitly categorized (e.g., "Due", "Submitted", "Skipped", "Draft"). The `ReportingTable` displays a calculated `current_report_status`.
123+
- **Notifications (`notify_report_due.py`, `messenger`):**
124+
- An automated management command (`notify_report_due`) periodically checks for reports due soon (based on `ProjectSettings` reminder frequencies) and sends notifications (`REPORT_NOTIFY`).
125+
- Manual actions like submission (`SUBMIT_REPORT`), skipping (`SKIPPED_REPORT`), and frequency changes (`REPORT_FREQUENCY_CHANGED`) also trigger system messages/notifications.
126+
127+
```mermaid
128+
---
129+
title: Automated Due Date Notification Flow
130+
---
131+
sequenceDiagram
132+
participant CronJob as Scheduled <br> Task
133+
participant ManagementCmd as notify_report_due
134+
participant System as Hypha <br> System
135+
participant Messenger
136+
137+
CronJob->>ManagementCmd: Execute periodically
138+
ManagementCmd->>System: Query projects with reports due soon <br>(based on ProjectSettings)
139+
System-->>ManagementCmd: List of due reports & projects
140+
loop For each due report
141+
ManagementCmd->>System: Identify relevant users (Owner, Staff) for project
142+
System-->>ManagementCmd: User list
143+
ManagementCmd->>Messenger: Send REPORT_NOTIFY(Report, User)
144+
Messenger-->>ManagementCmd: Confirmation (or queued)
145+
end
146+
ManagementCmd-->>CronJob: Completion
147+
```
148+
149+
### Private File Attachments
150+
151+
- Reports can include file uploads.
152+
- These files are stored using private storage (`PrivateStorage`) ensuring they are not publicly accessible.
153+
- A dedicated view (`ReportPrivateMedia`) serves these files, checking permissions and ensuring only files from the current, live report version are served directly.
154+
- Implemented via `ReportPrivateFiles` and `ReportPrivateMedia`
155+
156+
### Admin/Staff Views
157+
158+
- Dedicated table views for Staff/Finance users:
159+
- `ReportingView`: Lists projects and their current reporting status, due dates, and notification status. Filterable by status.
160+
- `ReportListView`: Lists all submitted reports across projects. Filterable by reporting period and submission date.
161+
- Implemented via `ReportListView`, `ReportingView`, `tables.py`, `filters.py`.
162+
163+
## Known Limitations
164+
165+
1. **Single Active Report Form Definition:** The system pulls the report form structure (`form_fields`) from the associated Fund page (`project.submission.page.specific.report_forms.first()`) when a `Report` instance is first created or needs its fields defined. While this structure is saved with the `Report`, there is no explicit mechanism within this app's code to use *different* report form structures for different reporting periods of the *same* project without changing the Fund configuration itself.
166+
2. **No Explicit Report Review Cycle:** Unlike application reviews, this app lacks a built-in, multi-stage review process for submitted reports (e.g., "Needs Revision", "Approved"). Reports are Draft, Submitted, or Skipped.
167+
3. **Basic Notification Rules:** The automated due date notification logic is tied to predefined reminder intervals (`ProjectReminderFrequency`). More complex escalation logic (e.g., different message if report is >2 weeks late) is not supported.
168+
4. **Simple Schedule Calculation:** The `next_date` calculation is based on adding fixed weeks, months, or years. It doesn't support more complex financial or business calendars (e.g., "end of quarter", "last working day").
169+
5. **Reporting Tied to Project Status:** Report submission and configuration updates are restricted based on project status, primarily occurring during the `INVOICING_AND_REPORTING` phase. Viewing submitted reports is possible in other statuses like `COMPLETE` or `CLOSING`, subject to permissions.
170+
6. **No Bulk Actions in UI:** The provided table views (`ReportListView`, `ReportingView`) do not provide UI elements for performing bulk actions (e.g., bulk skipping, bulk notifying).
171+
7. **Fixed Permission Roles:** Access control is tightly coupled to predefined roles (Staff, Finance, StaffAdmin) and Project Ownership. Assigning report-specific permissions to arbitrary users is not directly supported by the `permissions.py` module.

mkdocs.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@ markdown_extensions:
9595
- pymdownx.magiclink
9696
- pymdownx.mark
9797
- pymdownx.smartsymbols
98-
- pymdownx.superfences
98+
- pymdownx.superfences:
99+
custom_fences:
100+
- name: mermaid
101+
class: mermaid
102+
format: !!python/name:pymdownx.superfences.fence_code_format
99103
- pymdownx.tabbed:
100104
alternate_style: true
101105
- pymdownx.tasklist:

0 commit comments

Comments
 (0)