Skip to content

feat: ANC visit details with visit locking [MHWC-197]#82

Merged
abhilashkadu-tekdi merged 6 commits intorelease-4.0-rmnchfrom
mhwc-197-anc-visit-details-with-visit-locking
Feb 4, 2026
Merged

feat: ANC visit details with visit locking [MHWC-197]#82
abhilashkadu-tekdi merged 6 commits intorelease-4.0-rmnchfrom
mhwc-197-anc-visit-details-with-visit-locking

Conversation

@abhilashkadu-tekdi
Copy link
Copy Markdown

@abhilashkadu-tekdi abhilashkadu-tekdi commented Feb 1, 2026

📋 Description

JIRA ID: MHWC-197
As a CHO, I want to record ANC visit details and progress the woman through ANC stages while locking previous visits, so that clinical data integrity is maintained.

  • Acceptance Criteria:
    • The ANC module is enabled only after pregnancy registration.
    • The system supports a minimum of four ANC visits.
  • When a new ANC visit is started:
    • Previous ANC visit forms become read-only.
    • Previous visits remain viewable.
  • When a new ANC visit is not started:
    - The most recent ANC visit remains editable.
  • On completion of an ANC visit:
    - The visit is timestamped.
    - The woman’s ANC status is updated.
    - The record progresses to the next ANC stage.
  • ANC Visit Number:
    - Auto-calculated based on gestational age.
    - Manually editable if required.

✅ Type of Change

  • 🐞 Bug fix (non-breaking change which resolves an issue)
  • New feature (non-breaking change which adds functionality)
  • 🔥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 🛠 Refactor (change that is neither a fix nor a new feature)
  • ⚙️ Config change (configuration file or build script updates)
  • 📚 Documentation (updates to docs or readme)
  • 🧪 Tests (adding new or updating existing tests)
  • 🎨 UI/UX (changes that affect the user interface)
  • 🚀 Performance (improves performance)
  • 🧹 Chore (miscellaneous changes that don't modify src or test files)

ℹ️ Additional Information

Please describe how the changes were tested, and include any relevant screenshots, logs, or other information that provides additional context.

Summary by CodeRabbit

  • New Features

    • Pregnancy registration flow: capture/save LMP/EDD before proceeding.
    • Dynamic ANC visit suggestion based on gestational age and last visit.
    • Reason-for-visit dropdown adapts between pregnancy registration, ANC, and PNC.
    • Ability to switch and load different ANC visit forms with preserved state.
  • Bug Fixes

    • Tighter visit identity checks for accurate list updates.
    • Improved form editability, state restoration and navigation for old vs new ANC visits.

✏️ Tip: You can customize this high-level summary in your review settings.

…small fixes were applied: corrected AncVisitAdapter DiffUtil so multiple visits per patient are identified correctly, used the ViewModel’s last visit when deciding read-only for list clicks, ensured setUpPage uses a local recordExists flag, and capped suggested ANC visit numbers at 4 to match the form’s supported range.
- Visit locking: only last ANC visit editable; previous visits read-only from list
- Pregnancy Registration first: show ANC only after LMP registration
- ANC Period dropdown by visit: 1→1–4, 2→2–4, 3→3–4, 4→no dropdown
- Edit by clicking visit in list; form editability updates when switching visit in dropdown
- Timestamp ANC record on save (updatedDate); status/next stage via persist and lastVisitNumber
- Comment out 28-day ANC gap check per product request
- AncVisitAdapter: DiffUtil identity by patientID + visitNumber for multi-visit list
…visit-locking' into mhwc-197-anc-visit-details-with-visit-locking

# Conflicts:
#	app/src/main/java/org/piramalswasthya/cho/ui/commons/fhir_visit_details/FragmentVisitDetail.kt
#	app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormFragment.kt
#	app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormViewModel.kt
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 1, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review
📝 Walkthrough

Walkthrough

Dynamic ANC visit handling and pregnancy-registration flows added: visit-number-dependent dropdowns, GA-based ANC visit suggestion, LMP-save-driven registration path, form editability toggles based on visit age, and isOldVisit refactored to LiveData with visit-switching support.

Changes

Cohort / File(s) Summary
DiffUtil Item Identity
app/src/main/java/org/piramalswasthya/cho/adapter/AncVisitAdapter.kt
Tightened areItemsTheSame to require both patientID and visitNumber to match for item identity.
Visit Dataset
app/src/main/java/org/piramalswasthya/cho/configuration/PregnantWomanAncVisitDataset.kt
Make ancVisit entries depend on numeric visitNumber (1→["1","2","3","4"], 2→["2","3","4"], 3→["3","4"], 4→["4"]); remove ancVisit when visitNumber == 4; added getAncVisitNumber(): Int?.
Constants
app/src/main/java/org/piramalswasthya/cho/ui/commons/DropdownConst.kt
Added pregnancyRegistration constant ("Pregnancy Registration") to companion object.
Visit Detail & Navigation Logic
app/src/main/java/org/piramalswasthya/cho/ui/commons/fhir_visit_details/FragmentVisitDetail.kt
Reworked reason-for-visit options and visibility; added pregnancyRegistration branch requiring LMP save before proceeding; introduced GA-based weeks→suggested ANC visit mapping; compute and pass isOldVisit dynamically when navigating to PwAncFormFragment.
PwAnc Form UI & Adapter
app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormFragment.kt
Added cached latestFormList and nullable ancFormAdapter; derive formEditable from isOldVisit; observe isOldVisit to rebuild adapter, toggle submit visibility, and reapply latest form list.
PwAnc ViewModel State & Logic
app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormViewModel.kt
Refactored isOldVisit into LiveData<Boolean> (_isOldVisit); added internal tracking (ben, lastAncVisitNumber, currentVisitNumber), visit-switching via switchToVisit(), updated record-exists logic, and ensure ancCache.updatedDate stamped before save.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant FragmentVisitDetail
    participant PwAncFormFragment
    participant PwAncFormViewModel
    participant PregnantWomanAncVisitDataset

    rect rgba(135, 206, 250, 0.5)
        Note over User,FragmentVisitDetail: Pregnancy Registration flow
        User->>FragmentVisitDetail: Select "Pregnancy Registration"
        FragmentVisitDetail->>FragmentVisitDetail: Require LMP date and save registration
        FragmentVisitDetail->>PwAncFormViewModel: Observe LMP/save confirmation
        FragmentVisitDetail->>FragmentVisitDetail: Update reason dropdown to ANC
    end

    rect rgba(144, 238, 144, 0.5)
        Note over User,FragmentVisitDetail: ANC navigation with GA suggestion
        User->>FragmentVisitDetail: Choose ANC
        FragmentVisitDetail->>FragmentVisitDetail: Compute weeks via getWeeksOfPregnancy()
        FragmentVisitDetail->>FragmentVisitDetail: Map weeks → suggestedVisitNumber (1-4)
        FragmentVisitDetail->>PwAncFormFragment: Navigate(with suggestedVisitNumber, computed isOldVisit)
        PwAncFormFragment->>PwAncFormViewModel: Initialize for visit
        PwAncFormViewModel->>PregnantWomanAncVisitDataset: Request visit-number-dependent ancVisit entries
        PregnantWomanAncVisitDataset-->>PwAncFormViewModel: Return filtered entries
        PwAncFormViewModel-->>PwAncFormFragment: Emit isOldVisit/formEditable state
        PwAncFormFragment->>PwAncFormFragment: Configure adapter and UI based on formEditable
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nudge the dropdowns, count weeks by the moon,

LMP sings first, then GA hums a tune,
Visits shuffle numbers, forms wake or rest,
LiveData whispers which visit is best,
I hop—this branch is stitched with zest!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature being implemented: ANC visit details with visit locking functionality, and references the JIRA ticket (MHWC-197) for context.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mhwc-197-anc-visit-details-with-visit-locking

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@abhilashkadu-tekdi
Copy link
Copy Markdown
Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 1, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
`@app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormFragment.kt`:
- Around line 81-118: The two LiveData observers (viewModel.recordExists.observe
and viewModel.isOldVisit.observe) race and leave formEditable stale; factor the
UI update into a single function (e.g., updateFormEditable) and call it from
both observers (or use a combined observable) so visibility/adapter state is
always recomputed from the latest values; specifically, remove the early return
in the isOldVisit observer, compute formEditable from both
viewModel.recordExists.value and viewModel.isOldVisit.value, set
binding.btnSubmit and activity?.findViewById<Button>(R.id.btnSubmit) visibility
accordingly, re-create ancFormAdapter with the same
FormInputAdapter.FormValueListener (calling viewModel.updateListOnValueChanged
and hardCodedListUpdate), set binding.form.rvInputForm.adapter and submit
latestFormList if present, ensuring latestFormList / ancFormAdapter updates are
centralized to avoid the race.

In
`@app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormViewModel.kt`:
- Around line 119-136: The isOld calculation in switchToVisit incorrectly uses
inequality and marks future (unsaved) visits as old; change the logic so a visit
is considered old only when its number is less than the last saved visit.
Replace the current computation of isOld with a comparison like: isOld =
selectedVisit < max(1, lastAncVisitNumber) (i.e., use selectedVisit <
lastAncVisitNumber with lastAncVisitNumber floored to 1) so that future visits
are not treated as old; update the assignment to _isOldVisit and keep references
to switchToVisit, selectedVisit, lastAncVisitNumber, and _isOldVisit to locate
the change.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
`@app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormViewModel.kt`:
- Line 95: The assignment registerRecord =
maternalHealthRepo.getSavedRegistrationRecord(patientID)!! in PwAncFormViewModel
uses a non-null assertion that can crash; replace it with a null-safe check of
maternalHealthRepo.getSavedRegistrationRecord(patientID) and handle the null
case explicitly (e.g., log/processLogger an error, show a user-facing message,
navigate back/abort form initialization, or throw a clear IllegalStateException
with context) so the ViewModel does not NPE on unexpected navigation states;
update any consumers of registerRecord to account for the nullable type or
ensure early return after the null handling.
- Around line 119-146: switchToVisit lacks try/catch and can crash or leak DB
errors (and will throw UninitializedPropertyAccessException if called before
init due to the lateinit registerRecord). Wrap the coroutine body (inside
viewModelScope.launch/withContext) in a try/catch that catches Exception (and
optionally UninitializedPropertyAccessException) and on error posts a UI-visible
error state (e.g., a LiveData/SingleEvent) and logs the exception; ensure you
check the lateinit registerRecord before use (use ::registerRecord.isInitialized
or null/guard path) before passing it to dataset.setUpPage, and keep existing DB
calls to maternalHealthRepo.getSavedAncRecord and userRepo.getLoggedInUser()
inside the guarded block so failures are handled similarly.
🧹 Nitpick comments (1)
app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormViewModel.kt (1)

117-117: Consider extracting magic number to a named constant.

ancPeriodFormId = 3 is a magic number. For maintainability, consider defining this alongside other form IDs in a shared constants file or within the dataset class.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/src/main/java/org/piramalswasthya/cho/ui/commons/maternal_health/pregnant_woment_anc_visits/form/PwAncFormViewModel.kt (2)

83-120: ⚠️ Potential issue | 🟠 Major

Prevent ancCache from remaining uninitialized when patient display is missing.
If patientRepo.getPatientDisplay(patientID) returns null and no existing ANC record exists, ancCache never initializes and saveForm() will crash. Fail fast or initialize ancCache regardless.

🛠️ Suggested fix
-            ben = patientRepo.getPatientDisplay(patientID)?.also { ben ->
-                _benName.value =
-                    "${ben.patient.firstName} ${ben.patient.lastName ?: ""}"
-                _benAgeGender.value = "${ben.patient.age} ${ben.ageUnit?.name} | ${ben.gender?.genderName}"
-                ancCache = PregnantWomanAncCache(
-                    patientID = patientID,
-                    visitNumber = visitNumber,
-                    syncState = SyncState.UNSYNCED,
-                    createdBy = asha.userName,
-                    updatedBy = asha.userName
-                )
-            }
+            val patient = patientRepo.getPatientDisplay(patientID)
+            if (patient == null) {
+                Timber.e("No patient display for patientID=$patientID; cannot load ANC form")
+                _state.postValue(State.SAVE_FAILED)
+                return@launch
+            }
+            ben = patient
+            _benName.value =
+                "${patient.patient.firstName} ${patient.patient.lastName ?: ""}"
+            _benAgeGender.value =
+                "${patient.patient.age} ${patient.ageUnit?.name} | ${patient.gender?.genderName}"
+            ancCache = PregnantWomanAncCache(
+                patientID = patientID,
+                visitNumber = visitNumber,
+                syncState = SyncState.UNSYNCED,
+                createdBy = asha.userName,
+                updatedBy = asha.userName
+            )

176-183: ⚠️ Potential issue | 🟠 Major

Refresh lastAncVisitNumber after save to enforce visit locking in-session.
Without updating it, earlier visits can remain editable after saving a newer visit until the screen is reloaded.

🛠️ Suggested fix
                     ancCache.updatedDate = System.currentTimeMillis()
                     maternalHealthRepo.persistAncRecord(ancCache)
+                    lastAncVisitNumber = maxOf(lastAncVisitNumber, ancCache.visitNumber)

@abhilashkadu-tekdi abhilashkadu-tekdi changed the title Mhwc 197 anc visit details with visit locking MHWC-197 anc visit details with visit locking Feb 2, 2026
@abhilashkadu-tekdi abhilashkadu-tekdi changed the base branch from main to release-4.0 February 2, 2026 07:20
@abhilashkadu-tekdi abhilashkadu-tekdi changed the title MHWC-197 anc visit details with visit locking feat: ANC visit details with visit locking [MHWC-197] Feb 2, 2026
Copy link
Copy Markdown
Contributor

@DeepakKumar471 DeepakKumar471 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good.
Approved.

@ShivaShirsath ShivaShirsath changed the base branch from release-4.0 to release-4.0-rmnch February 4, 2026 10:13
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Feb 4, 2026

@abhilashkadu-tekdi abhilashkadu-tekdi merged commit 53a1b3d into release-4.0-rmnch Feb 4, 2026
2 checks passed
@ShivaShirsath ShivaShirsath deleted the mhwc-197-anc-visit-details-with-visit-locking branch February 9, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants