Skip to content

Add facility hierarchy creation with village and parent-child mapping#121

Merged
vishwab1 merged 8 commits intorelease-3.8.1from
vb/3.6.2
Mar 2, 2026
Merged

Add facility hierarchy creation with village and parent-child mapping#121
vishwab1 merged 8 commits intorelease-3.8.1from
vb/3.6.2

Conversation

@vishwab1
Copy link
Member

@vishwab1 vishwab1 commented Feb 26, 2026

📋 Description

JIRA ID: AMM-2169 and AMM-2171

Please provide a summary of the change and the motivation behind it. Include relevant context and details.

Summary

  • Added facility creation with hierarchy support (parent-child facility linking and village mapping)
  • Added new master table m_facility_level and mapping table facility_village_mapping
  • Added facility type enhancements with rural/urban classification, state-level scoping, and duplicate name check
  • Added new lookup/filter APIs for facilities by block, state, and facility level

New API Endpoints

StoreController

Method Endpoint Purpose
POST /createFacilityWithHierarchy Create facility with village + child facility mappings
POST /updateFacilityWithHierarchy Update facility and reassign village + child mappings
POST /getFacilitiesByBlock Get facilities filtered by block/taluk
POST /getFacilitiesByBlockAndLevel Get unassigned facilities by block and facility level
POST /getMappedVillageIDs Get village IDs already mapped to facilities in a block
POST /getVillageMappingsByFacility Get village mappings for a specific facility
POST /getChildFacilitiesByParent Get child facilities by parent facility ID

FacilitytypeController

Method Endpoint Purpose
POST /getFacilityTypesByRuralUrban Filter facility types by rural/urban
GET /getFacilityLevels Get all facility levels (master)
POST /getFacilityTypesByBlock Get distinct facility types present in a block
POST /getFacilityTypesByState Get facility types by state
POST /checkFacilityTypeName Check duplicate facility type name within a state

Database Changes

  • New table: m_facility_level (FacilityLevelID, LevelName, LevelDescription, LevelValue)
  • New table: facility_village_mapping (FacilityVillageMappingID, FacilityID, DistrictBranchID)
  • Altered table: m_facility — added columns: StateID, DistrictID, BlockID, ParentFacilityID
  • Altered table: m_facilitytype — added columns: RuralUrban, FacilityLevelID, StateID

Test Plan

  • Verify createFacilityWithHierarchy creates facility, maps villages, and links child facilities in a single transaction
  • Verify updateFacilityWithHierarchy replaces village mappings and child links correctly
  • Verify getMappedVillageIDs returns only villages mapped to non-deleted facilities in the block
  • Verify getFacilitiesByBlockAndLevel returns only facilities with no parent assigned
  • Verify checkFacilityTypeName correctly detects duplicates within the same state
  • Verify all existing store/facility APIs still work unchanged (backward compatibility)
  • Verify DB migration scripts run cleanly on a fresh and existing database

✅ 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
    • Query facility types by rural/urban, state, and block; retrieve facility levels; check facility-type name availability.
    • Create and update facilities with parent/child hierarchy and village mappings.
    • Retrieve facilities by block and by block+level, list child facilities for a parent, get mapped village IDs, and view village mappings.
    • Added support for facility levels and facility-to-village mapping data.

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 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.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds facility-hierarchy functionality: new controller endpoints for facility-type and store operations, new DTOs/entities for facility levels and village mappings, repository query methods (including modifying and custom queries), and service implementations to create/update facilities with village and child-facility mappings.

Changes

Cohort / File(s) Summary
Controllers
src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java, src/main/java/com/iemr/admin/controller/store/StoreController.java
Added 5 facility-type endpoints (levels, by rural/urban, by block, by state, name check) and 7 store endpoints for facility-hierarchy operations (get by block/level, create/update with hierarchy, mapped village IDs, mappings by facility, child facilities).
Facility-type data & repo
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java, src/main/java/com/iemr/admin/data/store/M_FacilityLevel.java, src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java, src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java
Extended M_facilitytype with fields (ruralUrban, facilityLevelID, stateID, blockID) and toString; added M_FacilityLevel entity and repository; extended facility-type repo with queries for rural/urban, block, state and an existence check.
Store data & new DTO/entity
src/main/java/com/iemr/admin/data/store/M_Facility.java, src/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.java, src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java
Added state/district/block/parentFacilityID to M_Facility; added FacilityHierarchyRequest DTO; added FacilityVillageMapping JPA entity (with computed villageName via @Formula, timestamps, deleted flag, and JSON toString).
Store repositories
src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java, src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java
Added FacilityVillageMappingRepo with finders including a custom query for mapped village IDs by block. Extended MainStoreRepo with queries: facilities by block, by block+level, by parent, and a @Modifying bulk update to clear parentFacilityID.
Service interfaces & impls (facilitytype)
src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java, src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java
Added five interface methods and implementations to fetch facility types by rural/urban, block, state; fetch facility levels; and check facility-type name existence. Injected M_FacilityLevelRepo.
Service interfaces & impls (store)
src/main/java/com/iemr/admin/service/store/StoreService.java, src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java
Extended StoreService with methods for block-based retrieval, create/update with hierarchy, mapped village IDs, mappings by facility, and child facilities. Implemented transactional create/update flows in StoreServiceImpl to persist facilities, manage child links, create/soft-delete FacilityVillageMapping entries, and return mappings/child lists. Note: duplicate method definitions appear in the impl file.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Controller as rgba(52,152,219,0.5)
    participant Service as rgba(46,204,113,0.5)
    participant FacilityRepo as rgba(155,89,182,0.5)
    participant MappingRepo as rgba(241,196,15,0.5)
    participant Database as rgba(127,140,141,0.5)

    Client->>Controller: POST /createFacilityWithHierarchy (facility, villageIDs, childFacilityIDs)
    Controller->>Service: createFacilityWithHierarchy(facility, villageIDs, childFacilityIDs)
    Service->>FacilityRepo: save or update M_Facility
    FacilityRepo->>Database: INSERT/UPDATE M_Facility
    Database-->>FacilityRepo: persisted facility (id)
    FacilityRepo-->>Service: returned facility

    loop each villageID
        Service->>MappingRepo: save new FacilityVillageMapping(facilityID, districtBranchID)
        MappingRepo->>Database: INSERT facility_village_mapping
    end

    loop each childFacilityID
        Service->>FacilityRepo: update childFacility.parentFacilityID = facilityID
        FacilityRepo->>Database: UPDATE M_Facility SET ParentFacilityID
    end

    Service-->>Controller: return saved facility and mappings
    Controller-->>Client: JSON response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibble code and hop with glee,
New maps and branches, a nested tree,
Villages link and parents find,
A rabbit cheers: “Structures aligned!” 🥕✨

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding facility hierarchy creation with village and parent-child mapping, which aligns with the core functionality introduced across the PR.

✏️ 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 vb/3.6.2

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.

@vishwab1 vishwab1 requested a review from drtechie February 26, 2026 13:42
@drtechie
Copy link
Member

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Full review triggered.

@drtechie
Copy link
Member

@vishwab1 release numbers have changed.

Copy link

@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: 9

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java (1)

111-113: ⚠️ Potential issue | 🔴 Critical

Bug: Self-assignment in setter does nothing.

The setter assigns the parameter to itself instead of to the instance field. This is a no-op and leaves facilityTypeID unchanged after calling setFacilityTypeID().

🐛 Fix the setter
 	public void setFacilityTypeID(Integer facilityTypeID) {
-		facilityTypeID = facilityTypeID;
+		this.facilityTypeID = facilityTypeID;
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java` around
lines 111 - 113, The setter setFacilityTypeID currently self-assigns the
parameter; change it to assign the instance field by setting this.facilityTypeID
= facilityTypeID so the class field is actually updated when
setFacilityTypeID(Integer facilityTypeID) is called; locate the facilityTypeID
field in M_facilitytype to confirm the correct field name and use this. to
reference it.
🧹 Nitpick comments (4)
src/main/java/com/iemr/admin/data/store/M_Facility.java (1)

219-249: Redundant accessors due to @Data annotation.

The class already uses Lombok @Data (line 40), which generates getters/setters automatically. These explicit accessors are redundant. This appears to be an existing pattern in the file, but for new fields, you could omit them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/data/store/M_Facility.java` around lines 219 -
249, The explicit getters/setters getStateID, setStateID, getDistrictID,
setDistrictID, getBlockID, setBlockID, getParentFacilityID and
setParentFacilityID are redundant because the class is annotated with Lombok's
`@Data`; remove these explicit accessor methods (unless any contain custom
logic—if so, preserve that method and delete only the redundant ones) so Lombok
can provide the boilerplate automatically and avoid duplication.
src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java (1)

31-35: Consider using List as return type and review package placement.

  1. Using List<M_FacilityLevel> instead of ArrayList<M_FacilityLevel> follows interface-based programming best practices.
  2. Since M_FacilityLevel resides in com.iemr.admin.data.store, this repository might be better placed in com.iemr.admin.repository.store for consistency.
♻️ Suggested change for return type
-	ArrayList<M_FacilityLevel> findByDeletedFalseOrderByLevelName();
+	List<M_FacilityLevel> findByDeletedFalseOrderByLevelName();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java`
around lines 31 - 35, The repository M_FacilityLevelRepo currently returns a
concrete ArrayList from findByDeletedFalseOrderByLevelName; change the method
signature to return the interface type List<M_FacilityLevel> to follow
interface-based programming (replace ArrayList<M_FacilityLevel> with
List<M_FacilityLevel> in M_FacilityLevelRepo). Also consider moving the
repository package to com.iemr.admin.repository.store to match the
M_FacilityLevel entity package (com.iemr.admin.data.store) for consistent
package structure; update the package declaration and imports accordingly.
src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java (1)

70-72: Add clearAutomatically = true to the @Modifying annotation to follow Spring Data best practices.

The service method updateFacilityWithHierarchy is properly annotated with @Transactional, so the persistence context contains the entities during execution. Adding clearAutomatically = true ensures the session cache is cleared after the bulk update, preventing potential stale data issues in the persistence context.

♻️ Suggested fix
-	`@Modifying`
+	`@Modifying`(clearAutomatically = true)
 	`@Query`("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID")
 	int clearParentFacilityID(`@Param`("parentFacilityID") Integer parentFacilityID, `@Param`("modifiedBy") String modifiedBy);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java` around
lines 70 - 72, The `@Modifying` annotation on the repository method
clearParentFacilityID should include clearAutomatically = true to avoid stale
persistence context after the bulk update; update the annotation on the method
clearParentFacilityID in MainStoreRepo to `@Modifying`(clearAutomatically = true)
while keeping the existing `@Query` and `@Param` signatures intact so the
transactional service method updateFacilityWithHierarchy will see a cleared
session after the bulk operation.
src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java (1)

258-266: Consider batching village-mapping inserts.

Current per-row save(...) loops are fine functionally but will scale poorly for larger mapping sets.

💡 Suggested refactor
-			for (Integer villageID : villageIDs) {
+			List<FacilityVillageMapping> mappingsToSave = new ArrayList<>();
+			for (Integer villageID : villageIDs) {
 				FacilityVillageMapping mapping = new FacilityVillageMapping();
 				mapping.setFacilityID(savedFacility.getFacilityID());
 				mapping.setDistrictBranchID(villageID);
 				mapping.setCreatedBy(facility.getCreatedBy());
 				mapping.setDeleted(false);
-				facilityVillageMappingRepo.save(mapping);
+				mappingsToSave.add(mapping);
 			}
+			facilityVillageMappingRepo.saveAll(mappingsToSave);

Also applies to: 320-327

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around
lines 258 - 266, The per-entity persistence inside the loop (creating
FacilityVillageMapping and calling facilityVillageMappingRepo.save(mapping))
will not scale; instead build a List<FacilityVillageMapping> (populate
facilityID from savedFacility.getFacilityID(), districtBranchID from villageID,
createdBy from facility.getCreatedBy(), deleted=false) and call
facilityVillageMappingRepo.saveAll(list) or your repository's bulk insert
method; apply the same change to the other loop that does per-row saves (the
similar block around the later village-mapping insertion).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/com/iemr/admin/controller/store/StoreController.java`:
- Around line 356-363: The controller method createFacilityWithHierarchy
currently uses reqObj and reqObj.getFacility() without validating them; before
calling storeService.createFacilityWithHierarchy (and in the similar block
around the other method using reqObj at 425-432), add null checks for reqObj and
reqObj.getFacility() and short-circuit with a controlled validation
OutputResponse (set an error message and appropriate status/code) instead of
invoking the service; ensure you check both the request body parse result and
that the Facility object is present, returning the validation response
immediately when missing.

In `@src/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.java`:
- Around line 1-21: Add the standard GPL license header to the top of this file
so it matches other files in the PR; open FacilityHierarchyRequest (class
FacilityHierarchyRequest in package com.iemr.admin.data.store) and insert the
project's standard multi-line GPL header comment block immediately above the
package declaration so the file begins with the exact license header used
elsewhere in the repo.

In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 46-47: The Deleted field in FacilityVillageMapping is marked
`@Column`(insertable = false) so calls to mapping.setDeleted(false) in the service
won't persist; either remove the insertable = false attribute on the deleted
field in class FacilityVillageMapping so the JPA entity can insert the value, or
if you must keep insertable=false, ensure the DB column
facility_village_mapping.Deleted has an explicit DEFAULT (e.g., DEFAULT FALSE)
and/or initialize the entity field (private Boolean deleted = false) so new rows
are not NULL; update whichever approach you choose and verify
findByFacilityIDAndDeletedFalse() returns the new mappings.

In
`@src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java`:
- Around line 45-47: The JPQL query in findByProviderServiceMapIDAndRuralUrban
returns soft-deleted rows because it lacks a deleted=false predicate; update the
query string in M_facilitytypeRepo (the `@Query` on
findByProviderServiceMapIDAndRuralUrban) to include "AND f.deleted = false"
(keeping the existing WHERE clauses and ORDER BY f.facilityTypeName) so only
non-deleted M_facilitytype records are returned.
- Around line 55-56: The repository query in M_facilitytypeRepo's findByStateID
method can return soft-deleted rows because it lacks a deleted flag filter;
update the JPQL in the `@Query` on method findByStateID to include "AND f.deleted
= false" (i.e., WHERE f.stateID = :stateID AND f.deleted = false ORDER BY
f.facilityTypeName) so only non-deleted M_facilitytype entities are returned,
keeping the `@Param`("stateID") binding unchanged.

In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`:
- Around line 18-21: The JPQL in FacilityVillageMappingRepo's
findMappedVillageIDsByBlockID can return duplicate IDs; update the query to
select DISTINCT fvm.districtBranchID so the method returns unique village IDs
(modify the `@Query` on findMappedVillageIDsByBlockID to use DISTINCT in the
SELECT clause).

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Line 60: The repository method findByBlockIDOrderByFacilityName lacks the
deleted=false filter and can return soft-deleted facilities; update the
repository to exclude deleted rows by changing the method to include the deleted
flag (e.g., rename/replace with findByBlockIDAndDeletedFalseOrderByFacilityName
or add the equivalent `@Query` condition) so it behaves consistently with
getAllMainFacility and getChildFacility and only returns non-deleted M_Facility
records.

In
`@src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java`:
- Around line 56-58: Method addAllFicilityData in M_facilitytypeServiceImpl
currently unsafely casts the result of m_facilitytypeRepo.saveAll(...) to
ArrayList, which is unsafe because CrudRepository.saveAll returns Iterable;
replace the cast by converting the Iterable to a concrete List/ArrayList
explicitly (e.g., collect the Iterable into a new ArrayList or change the return
type to List<M_facilitytype> and construct/return a List from the Iterable) so
that m_facilitytypeRepo.saveAll(...) is not directly cast to ArrayList and no
ClassCastException can occur.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 269-276: In StoreServiceImpl where childFacilityIDs are processed
(calls to mainStoreRepo.findByFacilityID and child.setParentFacilityID on
M_Facility), validate each childID before updating: if findByFacilityID returns
null, either log/collect and throw a validation exception instead of silently
ignoring; also explicitly check that childID != savedFacility.getFacilityID()
and reject or skip with an error if equal to prevent self-parenting; ensure you
use facility.getCreatedBy()/setModifiedBy only after validation and persist only
validated children (or abort the update with a clear validation error listing
invalid or self-referencing IDs).

---

Outside diff comments:
In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java`:
- Around line 111-113: The setter setFacilityTypeID currently self-assigns the
parameter; change it to assign the instance field by setting this.facilityTypeID
= facilityTypeID so the class field is actually updated when
setFacilityTypeID(Integer facilityTypeID) is called; locate the facilityTypeID
field in M_facilitytype to confirm the correct field name and use this. to
reference it.

---

Nitpick comments:
In `@src/main/java/com/iemr/admin/data/store/M_Facility.java`:
- Around line 219-249: The explicit getters/setters getStateID, setStateID,
getDistrictID, setDistrictID, getBlockID, setBlockID, getParentFacilityID and
setParentFacilityID are redundant because the class is annotated with Lombok's
`@Data`; remove these explicit accessor methods (unless any contain custom
logic—if so, preserve that method and delete only the redundant ones) so Lombok
can provide the boilerplate automatically and avoid duplication.

In
`@src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java`:
- Around line 31-35: The repository M_FacilityLevelRepo currently returns a
concrete ArrayList from findByDeletedFalseOrderByLevelName; change the method
signature to return the interface type List<M_FacilityLevel> to follow
interface-based programming (replace ArrayList<M_FacilityLevel> with
List<M_FacilityLevel> in M_FacilityLevelRepo). Also consider moving the
repository package to com.iemr.admin.repository.store to match the
M_FacilityLevel entity package (com.iemr.admin.data.store) for consistent
package structure; update the package declaration and imports accordingly.

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Around line 70-72: The `@Modifying` annotation on the repository method
clearParentFacilityID should include clearAutomatically = true to avoid stale
persistence context after the bulk update; update the annotation on the method
clearParentFacilityID in MainStoreRepo to `@Modifying`(clearAutomatically = true)
while keeping the existing `@Query` and `@Param` signatures intact so the
transactional service method updateFacilityWithHierarchy will see a cleared
session after the bulk operation.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 258-266: The per-entity persistence inside the loop (creating
FacilityVillageMapping and calling facilityVillageMappingRepo.save(mapping))
will not scale; instead build a List<FacilityVillageMapping> (populate
facilityID from savedFacility.getFacilityID(), districtBranchID from villageID,
createdBy from facility.getCreatedBy(), deleted=false) and call
facilityVillageMappingRepo.saveAll(list) or your repository's bulk insert
method; apply the same change to the other loop that does per-row saves (the
similar block around the later village-mapping insertion).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97ca0ee and 06419a0.

📒 Files selected for processing (15)
  • src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java
  • src/main/java/com/iemr/admin/controller/store/StoreController.java
  • src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java
  • src/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.java
  • src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java
  • src/main/java/com/iemr/admin/data/store/M_Facility.java
  • src/main/java/com/iemr/admin/data/store/M_FacilityLevel.java
  • src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java
  • src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java
  • src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java
  • src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java
  • src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java
  • src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java
  • src/main/java/com/iemr/admin/service/store/StoreService.java
  • src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java

@vishwab1
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Full review triggered.

Copy link

@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: 1

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java (1)

111-113: ⚠️ Potential issue | 🟠 Major

Bug: Setter does not assign to field.

The setter assigns the parameter to itself instead of the instance field. This means setFacilityTypeID() has no effect.

🐛 Fix the assignment
 	public void setFacilityTypeID(Integer facilityTypeID) {
-		facilityTypeID = facilityTypeID;
+		this.facilityTypeID = facilityTypeID;
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java` around
lines 111 - 113, The setter setFacilityTypeID currently assigns the parameter to
itself (facilityTypeID = facilityTypeID) so the instance field is never updated;
fix it by assigning the parameter to the instance field (use this.facilityTypeID
= facilityTypeID or rename the parameter and assign accordingly) in the
M_facilitytype class so the field is properly set by setFacilityTypeID().
♻️ Duplicate comments (1)
src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java (1)

1-23: ⚠️ Potential issue | 🟡 Minor

Missing GPL license header.

This file is missing the standard GPL license header that is present in other files in this PR (e.g., M_FacilityLevelRepo.java, M_FacilityLevel.java). For consistency and compliance, consider adding the license header.

📄 Add license header
+/*
+* AMRIT – Accessible Medical Records via Integrated Technology
+* Integrated EHR (Electronic Health Records) Solution
+*
+* Copyright (C) "Piramal Swasthya Management and Research Institute"
+*
+* This file is part of AMRIT.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program.  If not, see https://www.gnu.org/licenses/.
+*/
 package com.iemr.admin.repository.store;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`
around lines 1 - 23, The file lacks the project's standard GPL license header;
add the same GPL header block used in other files (e.g.,
M_FacilityLevelRepo.java, M_FacilityLevel.java) to the top of this file before
the package declaration so FacilityVillageMappingRepo (interface) and its
imports are covered by the license comment; ensure the header text and
year/owner match the project's existing header exactly for consistency and
compliance.
🧹 Nitpick comments (5)
src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java (1)

70-72: Consider adding clearAutomatically = true to avoid stale entity cache.

The @Modifying query updates entities directly in the database. If the persistence context contains any of the affected M_Facility entities, they will become stale after this bulk update.

♻️ Suggested improvement
 	`@Modifying`
-	`@Query`("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID")
+	`@Modifying`(clearAutomatically = true)
+	`@Query`("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID")
 	int clearParentFacilityID(`@Param`("parentFacilityID") Integer parentFacilityID, `@Param`("modifiedBy") String modifiedBy);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java` around
lines 70 - 72, The bulk update in clearParentFacilityID (method
clearParentFacilityID in MainStoreRepo) uses `@Modifying` and may leave stale
M_Facility entities in the persistence context; modify the annotation to
`@Modifying`(clearAutomatically = true) so the persistence context is cleared
after the update (keep the existing `@Query` and `@Param` usage unchanged).
src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java (2)

302-305: Consider using a more specific exception type.

RuntimeException is generic and doesn't convey semantic meaning. The codebase has IEMRException available (imported at line 43) which would be more appropriate for domain-specific errors.

💡 Suggested fix
 		M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID());
 		if (existing == null) {
-			throw new RuntimeException("Facility not found");
+			throw new IEMRException("Facility not found");
 		}

Note: This would require updating the method signature to declare throws IEMRException.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around
lines 302 - 305, Replace the generic RuntimeException thrown when a facility
isn't found with the domain-specific IEMRException: where you check M_Facility
existing = mainStoreRepo.findByFacilityID(facility.getFacilityID()) and
currently throw new RuntimeException("Facility not found"), throw a new
IEMRException with the same (or more descriptive) message; also update the
enclosing method signature to declare throws IEMRException so callers handle the
specific exception type.

312-328: Document the semantic difference between null and empty list for villageIDs.

The current logic treats null (no change to mappings) differently from an empty list (clears all mappings). This is a reasonable design but could be confusing for API consumers.

  • villageIDs == null: Skip village mapping update entirely
  • villageIDs is empty list: Soft-delete all existing mappings, add none

Consider adding a code comment or API documentation to clarify this behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around
lines 312 - 328, The block in StoreServiceImpl that updates facility-village
mappings (using facilityVillageMappingRepo, oldMappings loop, and the villageIDs
loop) treats null as "leave mappings unchanged" and an empty list as
"soft-delete all mappings and add none"; add a concise inline code comment above
this conditional explaining the semantic difference (null = no change, empty
list = clear mappings), and update the method Javadoc or API docs for the method
that handles facility updates to document this behavior for API consumers so
callers know how to intentionally clear versus retain mappings.
src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java (1)

31-31: Remove unused imports.

GetMapping and RequestParam are imported but not used in this file. The getFacilityLevels endpoint uses @RequestMapping with RequestMethod.GET instead of @GetMapping.

🧹 Suggested fix
-import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;

Also applies to: 35-35

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java`
at line 31, Remove the unused imports
org.springframework.web.bind.annotation.GetMapping and
org.springframework.web.bind.annotation.RequestParam from
FacilitytypeController.java; locate the FacilitytypeController class (and the
getFacilityLevels method which currently uses `@RequestMapping`(method =
RequestMethod.GET)) and either switch that method to use `@GetMapping` or simply
delete the unused import lines so there are no unused import warnings.
src/main/java/com/iemr/admin/controller/store/StoreController.java (1)

341-344: Consider using a dedicated DTO or M_Facility instead of M_facilitytype for parsing the request.

This endpoint parses the request as M_facilitytype to extract blockID and facilityLevelID, but the endpoint operates on facilities, not facility types. Using M_facilitytype here is semantically confusing and couples this endpoint to an unrelated domain object.

💡 Suggested fix

Consider creating a simple request DTO or using FacilityHierarchyRequest (already imported) with the required fields:

 	public String getFacilitiesByBlockAndLevel(`@RequestBody` String request) {

 		OutputResponse response = new OutputResponse();
 		try {
-			com.iemr.admin.data.facilitytype.M_facilitytype reqObj = InputMapper.gson().fromJson(request,
-					com.iemr.admin.data.facilitytype.M_facilitytype.class);
-			ArrayList<M_Facility> data = storeService.getFacilitiesByBlockAndLevel(reqObj.getBlockID(),
-					reqObj.getFacilityLevelID());
+			M_Facility reqObj = InputMapper.gson().fromJson(request, M_Facility.class);
+			ArrayList<M_Facility> data = storeService.getFacilitiesByBlockAndLevel(reqObj.getBlockID(),
+					reqObj.getFacilityLevelID());
 			response.setResponse(data.toString());

This requires ensuring M_Facility has facilityLevelID field, or creating a dedicated request DTO.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/controller/store/StoreController.java` around
lines 341 - 344, The controller is deserializing the request into
com.iemr.admin.data.facilitytype.M_facilitytype even though the endpoint is
fetching facilities; change the parsing to use a dedicated request DTO (e.g.,
FacilityHierarchyRequest) or a new FacilityLookupRequest with blockID and
facilityLevelID, and pass those values to
storeService.getFacilitiesByBlockAndLevel instead of reading them from
M_facilitytype; update the parsing call in StoreController (replace
InputMapper.gson().fromJson(..., M_facilitytype.class)) to deserialize into the
chosen DTO and ensure the DTO field names match reqObj.getBlockID() and
reqObj.getFacilityLevelID() accessors (or add accessors) so
getFacilitiesByBlockAndLevel receives the correct IDs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 37-39: The `@Formula` on the villageName field is referencing
districtBranchID directly which Hibernate cannot resolve; update the Formula on
facility's villageName to use Hibernate's {alias} placeholder so the owning
entity's column is referenced (e.g., change the WHERE to use
{alias}.DistrictBranchID) when querying m_DistrictBranchMapping.VillageName.

---

Outside diff comments:
In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java`:
- Around line 111-113: The setter setFacilityTypeID currently assigns the
parameter to itself (facilityTypeID = facilityTypeID) so the instance field is
never updated; fix it by assigning the parameter to the instance field (use
this.facilityTypeID = facilityTypeID or rename the parameter and assign
accordingly) in the M_facilitytype class so the field is properly set by
setFacilityTypeID().

---

Duplicate comments:
In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`:
- Around line 1-23: The file lacks the project's standard GPL license header;
add the same GPL header block used in other files (e.g.,
M_FacilityLevelRepo.java, M_FacilityLevel.java) to the top of this file before
the package declaration so FacilityVillageMappingRepo (interface) and its
imports are covered by the license comment; ensure the header text and
year/owner match the project's existing header exactly for consistency and
compliance.

---

Nitpick comments:
In
`@src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java`:
- Line 31: Remove the unused imports
org.springframework.web.bind.annotation.GetMapping and
org.springframework.web.bind.annotation.RequestParam from
FacilitytypeController.java; locate the FacilitytypeController class (and the
getFacilityLevels method which currently uses `@RequestMapping`(method =
RequestMethod.GET)) and either switch that method to use `@GetMapping` or simply
delete the unused import lines so there are no unused import warnings.

In `@src/main/java/com/iemr/admin/controller/store/StoreController.java`:
- Around line 341-344: The controller is deserializing the request into
com.iemr.admin.data.facilitytype.M_facilitytype even though the endpoint is
fetching facilities; change the parsing to use a dedicated request DTO (e.g.,
FacilityHierarchyRequest) or a new FacilityLookupRequest with blockID and
facilityLevelID, and pass those values to
storeService.getFacilitiesByBlockAndLevel instead of reading them from
M_facilitytype; update the parsing call in StoreController (replace
InputMapper.gson().fromJson(..., M_facilitytype.class)) to deserialize into the
chosen DTO and ensure the DTO field names match reqObj.getBlockID() and
reqObj.getFacilityLevelID() accessors (or add accessors) so
getFacilitiesByBlockAndLevel receives the correct IDs.

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Around line 70-72: The bulk update in clearParentFacilityID (method
clearParentFacilityID in MainStoreRepo) uses `@Modifying` and may leave stale
M_Facility entities in the persistence context; modify the annotation to
`@Modifying`(clearAutomatically = true) so the persistence context is cleared
after the update (keep the existing `@Query` and `@Param` usage unchanged).

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 302-305: Replace the generic RuntimeException thrown when a
facility isn't found with the domain-specific IEMRException: where you check
M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID())
and currently throw new RuntimeException("Facility not found"), throw a new
IEMRException with the same (or more descriptive) message; also update the
enclosing method signature to declare throws IEMRException so callers handle the
specific exception type.
- Around line 312-328: The block in StoreServiceImpl that updates
facility-village mappings (using facilityVillageMappingRepo, oldMappings loop,
and the villageIDs loop) treats null as "leave mappings unchanged" and an empty
list as "soft-delete all mappings and add none"; add a concise inline code
comment above this conditional explaining the semantic difference (null = no
change, empty list = clear mappings), and update the method Javadoc or API docs
for the method that handles facility updates to document this behavior for API
consumers so callers know how to intentionally clear versus retain mappings.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97ca0ee and 5229423.

📒 Files selected for processing (15)
  • src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java
  • src/main/java/com/iemr/admin/controller/store/StoreController.java
  • src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java
  • src/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.java
  • src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java
  • src/main/java/com/iemr/admin/data/store/M_Facility.java
  • src/main/java/com/iemr/admin/data/store/M_FacilityLevel.java
  • src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java
  • src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java
  • src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java
  • src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java
  • src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java
  • src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java
  • src/main/java/com/iemr/admin/service/store/StoreService.java
  • src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java

@vishwab1
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Full review triggered.

Copy link

@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

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java (1)

111-113: ⚠️ Potential issue | 🟠 Major

Bug: setFacilityTypeID does not update the field.

The setter assigns the parameter to itself instead of to the instance field. This means calling setFacilityTypeID() has no effect.

🐛 Proposed fix
 public void setFacilityTypeID(Integer facilityTypeID) {
-    facilityTypeID = facilityTypeID;
+    this.facilityTypeID = facilityTypeID;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java` around
lines 111 - 113, In M_facilitytype the setter method setFacilityTypeID(Integer
facilityTypeID) is assigning the parameter to itself instead of updating the
instance field; change the assignment to set the class field (e.g.,
this.facilityTypeID = facilityTypeID or the appropriate field name) inside
setFacilityTypeID so the instance value is updated when the setter is called.
🧹 Nitpick comments (6)
src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java (1)

1-21: Missing GPL license header.

This file is missing the standard GPL license header present in other files in this PR. Consider adding it for consistency and compliance.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java` around
lines 1 - 21, Add the project's standard GPL license header to the top of this
source file so it matches other files in the PR; specifically insert the same
GPL comment block used across the project before the package declaration in
FacilityVillageMapping (class FacilityVillageMapping in
src/main/java/com/iemr/admin/data/store) so licensing is consistent and
compliant.
src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java (1)

70-72: Consider filtering out soft-deleted facilities in the bulk update.

The clearParentFacilityID method updates all facilities with a matching parentFacilityID, including soft-deleted ones. If only active facilities should be detached, add a deleted = false condition.

♻️ Optional fix to exclude soft-deleted records
 `@Modifying`
-@Query("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID")
+@Query("UPDATE M_Facility f SET f.parentFacilityID = NULL, f.modifiedBy = :modifiedBy WHERE f.parentFacilityID = :parentFacilityID AND f.deleted = false")
 int clearParentFacilityID(`@Param`("parentFacilityID") Integer parentFacilityID, `@Param`("modifiedBy") String modifiedBy);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java` around
lines 70 - 72, The bulk update in clearParentFacilityID currently affects all
M_Facility rows (including soft-deleted ones); modify the JPQL query in the
clearParentFacilityID repository method to only target non-deleted facilities by
adding a condition such as "AND f.deleted = false" (or the actual soft-delete
flag name) so the WHERE clause becomes f.parentFacilityID = :parentFacilityID
AND f.deleted = false; keep the method signature (clearParentFacilityID) and
parameters unchanged and ensure the `@Modifying` `@Query` annotation on the
MainStoreRepo method references the updated JPQL.
src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java (1)

1-23: Missing GPL license header.

This file is missing the standard GPL license header that is present in other repository files (e.g., MainStoreRepo.java, M_facilitytypeRepo.java). Consider adding it for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`
around lines 1 - 23, Add the project's standard GPL license header to this file
to match other repository files; open the FacilityVillageMappingRepo interface
(public interface FacilityVillageMappingRepo extends CrudRepository) and insert
the same GPL comment block used in MainStoreRepo.java and
M_facilitytypeRepo.java at the top of the file above the package declaration,
preserving formatting and year/owner info as in other files so the file header
is consistent with the repository.
src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java (1)

43-43: Consider adding an import for M_FacilityLevel instead of using the fully qualified name.

Using com.iemr.admin.data.store.M_FacilityLevel inline is functional but inconsistent with the M_facilitytype import at line 27.

Suggested fix

Add to imports:

import com.iemr.admin.data.store.M_FacilityLevel;

Then change line 43 to:

ArrayList<M_FacilityLevel> getFacilityLevels();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java`
at line 43, Add an import for com.iemr.admin.data.store.M_FacilityLevel and
replace the fully-qualified type in the getFacilityLevels() signature with the
short name; specifically, add "import
com.iemr.admin.data.store.M_FacilityLevel;" alongside the existing
M_facilitytype import and change the method declaration
"ArrayList<com.iemr.admin.data.store.M_FacilityLevel> getFacilityLevels();" to
"ArrayList<M_FacilityLevel> getFacilityLevels();" to keep imports consistent.
src/main/java/com/iemr/admin/controller/store/StoreController.java (1)

341-344: Consider using a dedicated DTO or M_Facility for the request parsing.

Using M_facilitytype to extract blockID and facilityLevelID works but is semantically confusing since this endpoint returns facilities, not facility types. A more intuitive approach would be to use M_Facility (if it has these fields) or create a simple request DTO.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/controller/store/StoreController.java` around
lines 341 - 344, The request is currently parsed into
com.iemr.admin.data.facilitytype.M_facilitytype which is semantically
misleading; change the deserialization to a more appropriate type that
represents the request (either com.iemr.admin.data.facility.M_Facility if it
contains blockID and facilityLevelID, or create a small request DTO like
FacilityLookupRequest with those two fields) and update the local variable name
accordingly; ensure the call to
storeService.getFacilitiesByBlockAndLevel(req.getBlockID(),
req.getFacilityLevelID()) uses the new DTO or M_Facility getters and adjust any
imports/usages of M_facilitytype in this method.
src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java (1)

302-305: Consider using a more specific exception type.

RuntimeException("Facility not found") is generic. A domain-specific exception (e.g., EntityNotFoundException or a custom FacilityNotFoundException) would provide better semantics and enable more granular exception handling at the controller layer if needed in the future.

Example
 M_Facility existing = mainStoreRepo.findByFacilityID(facility.getFacilityID());
 if (existing == null) {
-    throw new RuntimeException("Facility not found");
+    throw new IllegalArgumentException("Facility not found with ID: " + facility.getFacilityID());
 }

Or use a custom exception if one exists in the codebase (e.g., IEMRException).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java` around
lines 302 - 305, Replace the generic RuntimeException thrown when no facility is
found in the block that calls
mainStoreRepo.findByFacilityID(facility.getFacilityID()) with a more specific
domain exception; for example throw new EntityNotFoundException("Facility not
found: " + facility.getFacilityID()) or a custom
FacilityNotFoundException/IEMRException if that exists in the codebase, so
update the check around M_Facility existing =
mainStoreRepo.findByFacilityID(...) to throw the chosen specific exception type
with contextual message.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java`:
- Line 35: Remove the unused import of RequestParam from the
FacilitytypeController class: delete the line importing
org.springframework.web.bind.annotation.RequestParam since no methods in
FacilitytypeController reference `@RequestParam`; after removal, run a quick
compile to ensure no other code in that class depends on RequestParam and clean
up any unused imports using your IDE's organize/imports feature.

In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 41-43: The field providerServiceMapID in FacilityVillageMapping
should not default to 0 because that persists an invalid FK; remove the "= 0"
default so the Integer is null by default, or alternatively ensure
StoreServiceImpl always assigns a valid providerServiceMapID before calling
save; update FacilityVillageMapping (providerServiceMapID) to have no default
and/or modify the service (StoreServiceImpl where new FacilityVillageMapping
instances are created) to set providerServiceMapID from the incoming DTO/params
prior to persistence.

---

Outside diff comments:
In `@src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java`:
- Around line 111-113: In M_facilitytype the setter method
setFacilityTypeID(Integer facilityTypeID) is assigning the parameter to itself
instead of updating the instance field; change the assignment to set the class
field (e.g., this.facilityTypeID = facilityTypeID or the appropriate field name)
inside setFacilityTypeID so the instance value is updated when the setter is
called.

---

Nitpick comments:
In `@src/main/java/com/iemr/admin/controller/store/StoreController.java`:
- Around line 341-344: The request is currently parsed into
com.iemr.admin.data.facilitytype.M_facilitytype which is semantically
misleading; change the deserialization to a more appropriate type that
represents the request (either com.iemr.admin.data.facility.M_Facility if it
contains blockID and facilityLevelID, or create a small request DTO like
FacilityLookupRequest with those two fields) and update the local variable name
accordingly; ensure the call to
storeService.getFacilitiesByBlockAndLevel(req.getBlockID(),
req.getFacilityLevelID()) uses the new DTO or M_Facility getters and adjust any
imports/usages of M_facilitytype in this method.

In `@src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java`:
- Around line 1-21: Add the project's standard GPL license header to the top of
this source file so it matches other files in the PR; specifically insert the
same GPL comment block used across the project before the package declaration in
FacilityVillageMapping (class FacilityVillageMapping in
src/main/java/com/iemr/admin/data/store) so licensing is consistent and
compliant.

In
`@src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java`:
- Around line 1-23: Add the project's standard GPL license header to this file
to match other repository files; open the FacilityVillageMappingRepo interface
(public interface FacilityVillageMappingRepo extends CrudRepository) and insert
the same GPL comment block used in MainStoreRepo.java and
M_facilitytypeRepo.java at the top of the file above the package declaration,
preserving formatting and year/owner info as in other files so the file header
is consistent with the repository.

In `@src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java`:
- Around line 70-72: The bulk update in clearParentFacilityID currently affects
all M_Facility rows (including soft-deleted ones); modify the JPQL query in the
clearParentFacilityID repository method to only target non-deleted facilities by
adding a condition such as "AND f.deleted = false" (or the actual soft-delete
flag name) so the WHERE clause becomes f.parentFacilityID = :parentFacilityID
AND f.deleted = false; keep the method signature (clearParentFacilityID) and
parameters unchanged and ensure the `@Modifying` `@Query` annotation on the
MainStoreRepo method references the updated JPQL.

In `@src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java`:
- Line 43: Add an import for com.iemr.admin.data.store.M_FacilityLevel and
replace the fully-qualified type in the getFacilityLevels() signature with the
short name; specifically, add "import
com.iemr.admin.data.store.M_FacilityLevel;" alongside the existing
M_facilitytype import and change the method declaration
"ArrayList<com.iemr.admin.data.store.M_FacilityLevel> getFacilityLevels();" to
"ArrayList<M_FacilityLevel> getFacilityLevels();" to keep imports consistent.

In `@src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java`:
- Around line 302-305: Replace the generic RuntimeException thrown when no
facility is found in the block that calls
mainStoreRepo.findByFacilityID(facility.getFacilityID()) with a more specific
domain exception; for example throw new EntityNotFoundException("Facility not
found: " + facility.getFacilityID()) or a custom
FacilityNotFoundException/IEMRException if that exists in the codebase, so
update the check around M_Facility existing =
mainStoreRepo.findByFacilityID(...) to throw the chosen specific exception type
with contextual message.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97ca0ee and 3c27b2e.

📒 Files selected for processing (15)
  • src/main/java/com/iemr/admin/controller/facilitytype/FacilitytypeController.java
  • src/main/java/com/iemr/admin/controller/store/StoreController.java
  • src/main/java/com/iemr/admin/data/facilitytype/M_facilitytype.java
  • src/main/java/com/iemr/admin/data/store/FacilityHierarchyRequest.java
  • src/main/java/com/iemr/admin/data/store/FacilityVillageMapping.java
  • src/main/java/com/iemr/admin/data/store/M_Facility.java
  • src/main/java/com/iemr/admin/data/store/M_FacilityLevel.java
  • src/main/java/com/iemr/admin/repository/facilitytype/M_FacilityLevelRepo.java
  • src/main/java/com/iemr/admin/repository/facilitytype/M_facilitytypeRepo.java
  • src/main/java/com/iemr/admin/repository/store/FacilityVillageMappingRepo.java
  • src/main/java/com/iemr/admin/repository/store/MainStoreRepo.java
  • src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeInter.java
  • src/main/java/com/iemr/admin/service/facilitytype/M_facilitytypeServiceImpl.java
  • src/main/java/com/iemr/admin/service/store/StoreService.java
  • src/main/java/com/iemr/admin/service/store/StoreServiceImpl.java

@vishwab1
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Full review triggered.

@vishwab1
Copy link
Member Author

@drtechie
Could we please merge the existing PRs into 3.6.2? I have one more PR to raise, and then I’ll move everything to the new release branch. Is this okay?

@vishwab1 vishwab1 changed the base branch from release-3.6.2 to release-3.8.1 February 27, 2026 14:13
@sonarqubecloud
Copy link

@vishwab1 vishwab1 merged commit 68e4130 into release-3.8.1 Mar 2, 2026
2 of 3 checks passed
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