[Eng-765] feat :add patient appointment support in report builder - #3716
[Eng-765] feat :add patient appointment support in report builder#3716nandkishorr wants to merge 6 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds context-builder schemas for tokens, schedules, availabilities, token bookings, and appointment-related encounter fields. Charge-item resolution is split between queryset, category, and single-object builders. ChangesAppointment context
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryAppointment-related report contexts are added across encounter, booking, scheduling, token, and charge-item data points.
Confidence Score: 4/5The PR is not safe to merge until the encounter-associated appointment builder returns a single booking or None rather than a QuerySet. The attempted fix for encounters without appointments violates the single-object context contract, so accessing an associated appointment field can still terminate report rendering. care/emr/reports/context_builder/data_points/encounter.py Important Files Changed
Reviews (2): Last reviewed commit: "fix:review changes" | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
Adds report-builder context support for scheduling/appointment-related EMR models so encounter reports can include token bookings (“appointments”) and their nested scheduling/token details.
Changes:
- Introduces new nested context builders for Token/TokenCategory, Schedule/Availability, and TokenBooking/TokenSlot.
- Extends the Encounter report context with fields for patient facility appointments and encounter-associated appointment.
- Refactors
ChargeItemContextBuilder.get_context()to use parent attribute (but currently introduces a queryset/single-object mismatch risk).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| care/emr/reports/context_builder/data_points/token.py | Adds nested contexts for token + token category fields for report templates. |
| care/emr/reports/context_builder/data_points/schedule.py | Adds nested contexts for schedule resources, schedules, and availability. |
| care/emr/reports/context_builder/data_points/booking.py | Adds nested contexts for token booking + token slot, linking in schedule/token/user/charge item contexts. |
| care/emr/reports/context_builder/data_points/encounter.py | Adds encounter-level fields/context builders to fetch bookings (appointments) for facility/patient and for an encounter. |
| care/emr/reports/context_builder/data_points/charge_items.py | Changes charge item context sourcing logic (needs adjustment to avoid runtime iteration failures). |
| class EncounterAssociatedAppointmentContextBuilder(SingleTokenBookingContextBuilder): | ||
| def get_context(self): | ||
| return TokenBooking.objects.get( | ||
| associated_encounter_id=self.parent_context.id, | ||
| ) |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@care/emr/reports/context_builder/data_points/booking.py`:
- Around line 72-75: Update the charge_item field in TokenBooking to use a
dedicated single-object charge-item context builder instead of
ChargeItemContextBuilder. Keep ChargeItemContextBuilder collection-oriented so
its override returns a queryset compatible with _filter(); in charge_items.py,
extract or reuse shared fields between the single-object and collection builders
as needed.
In `@care/emr/reports/context_builder/data_points/encounter.py`:
- Around line 249-253: Update
EncounterAssociatedAppointmentContextBuilder.get_context and the corresponding
logic around the additional referenced location to avoid assuming a unique
TokenBooking association: handle missing bookings without breaking report
generation and select duplicates deterministically, or enforce a one-to-one
model invariant if that is the intended contract. Preserve the existing
associated_encounter lookup behavior for valid single-booking cases.
In `@care/emr/reports/context_builder/data_points/schedule.py`:
- Around line 26-29: Update the resource_type Field declaration to apply the
existing RESOURCE_TYPE_CHOICES display mapping, ensuring values such as
healthcare_service are rendered with report-friendly labels instead of raw
identifiers. Preserve the field’s current display and description metadata.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 489011f4-e3fe-41f4-a06f-656feecc4015
📒 Files selected for processing (5)
care/emr/reports/context_builder/data_points/booking.pycare/emr/reports/context_builder/data_points/charge_items.pycare/emr/reports/context_builder/data_points/encounter.pycare/emr/reports/context_builder/data_points/schedule.pycare/emr/reports/context_builder/data_points/token.py
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #3716 +/- ##
===========================================
+ Coverage 79.45% 79.48% +0.03%
===========================================
Files 480 483 +3
Lines 23215 23289 +74
Branches 2420 2420
===========================================
+ Hits 18446 18512 +66
- Misses 4165 4173 +8
Partials 604 604 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| def get_context(self): | ||
| return TokenBooking.objects.filter( | ||
| associated_encounter_id=self.parent_context.id |
There was a problem hiding this comment.
Single appointment remains a QuerySet
When a report accesses a field such as associated_appointment.status, this single-object context stores the QuerySet returned by filter() and resolves the field against that QuerySet rather than a TokenBooking. The resulting attribute lookup fails during report rendering; an empty QuerySet also bypasses the context builder's None handling, so the optional-appointment crash remains.
|
|
||
|
|
||
| class AccountChargeItemContextBuilder(ChargeItemContextBuilder): | ||
| class AccountChargeItemContextBuilder(ChargeItemContextBuilder, QuerysetContextBuilder): |
| class CategoryChargeItemContextBuilder( | ||
| ChargeItemContextBuilder, QuerysetContextBuilder | ||
| ): |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (3)
care/emr/reports/context_builder/data_points/encounter.py:253
- EncounterAssociatedAppointmentContextBuilder inherits SingleTokenBookingContextBuilder (single-object), but get_context currently returns a QuerySet. That will break field access (the TokenBooking fields will be resolved against a QuerySet). The Encounter model already has an
appointmentFK to TokenBooking, so this can be returned directly and avoids an extra query.
class EncounterAssociatedAppointmentContextBuilder(SingleTokenBookingContextBuilder):
def get_context(self):
return TokenBooking.objects.filter(
associated_encounter_id=self.parent_context.id
)
care/emr/reports/context_builder/data_points/token.py:26
- TokenCategoryContextBuilder.resource_type mapping assumes
rcis always present. If the category is missing (e.g., because the parent Token is null), the mapping lambda will raise. Guarding for falsy contexts makes templates safer to evaluate.
resource_type = Field(
display="Resource Type",
description="Type of the resource associated with the token category",
mapping=lambda rc: RESOURCE_CATEGORY_RESOURCE_TYPE.get(
rc.resource_type, rc.resource_type.replace("_", " ").title()
),
care/emr/reports/context_builder/data_points/schedule.py:78
- TokenSlot.availability is nullable (Availability FK is null=True). When availability is null, AvailabilityContextBuilder.context becomes None and the slot_type mapping lambda will raise on
a.slot_type. Guard for missing availability so templates can safely dereference slot_type, and update the description to match SlotTypeOptions (open/appointment/closed).
slot_type = Field(
display="Slot Type",
description="Type of the slot (e.g., token, appointment)",
mapping=lambda a: AVAILABILITY_SLOT_TYPE.get(
a.slot_type, a.slot_type.replace("_", " ").title()
),
)
| class PatientFacilityAppointmentContextBuilder(TokenBookingContextBuilder): | ||
| def get_context(self): | ||
| return TokenBooking.objects.filter( | ||
| patient_id=self.parent_context.patient.id, | ||
| token_slot__resource__facility_id=self.parent_context.facility.id, | ||
| ) |
| def get_context(self): | ||
| return getattr(self.parent_context, self.parent_attribute) |
| def get_context(self): | ||
| return getattr(self.parent_context, self.parent_attribute) | ||
|
|
| def get_context(self): | ||
| return getattr(self.parent_context, self.parent_attribute) |
Proposed Changes
Added context builders for EMR models
Merge Checklist
/docsOnly PR's with test cases included and passing lint and test pipelines will be reviewed
@ohcnetwork/care-backend-maintainers @ohcnetwork/care-backend-admins
Summary by CodeRabbit