Conversation
* fix: implement elasticsearch functionality * fix: update the response code * fix: update pom.xml * fix: advance search functionality * fix: add env properties * fix: updated to advancedSearch * fix: update to advanced
* fix:prescription drug for hwc * fix:doctor signature * fix:doctor signature
* Add /health endpoint and update /version endpoint * Update HTTPRequests and fix issues in /health and /version * fix(security): validate authentication for /health details * feat: update version and health endpoints * fix(redis): fix redis timeout handling issue * fix(health): fix InterruptedException handling and add redis timeout with proper interrupt restore * refactor(health): simplify MySQL health check and remove sensitive details * fix(health): removed unused methods from healthservices * fix(health): remove unused imports * fix(health): scope PROCESSLIST lock-wait check to application DB user * fix(health): avoid permanent DEGRADED from historical deadloc * fix(health): handle executor rejection during shutdown in /health * refactor(health): centralize component names and fix InterruptedException handling * fix(health): resolve remaining reliability issues on new code * fix(health): isolate advanced checks in dedicated executor to avoid thread starvation * fix(health): cancel timed-out advanced MySQL checks to avoid orphaned tasks * fix(health): make advanced MySQL checks interruptible on timeout * fix(health): remove unsafe connection sharing from advanced MySQL checks * refactor(health): reduce cognitive complexity of advanced MySQL throttle logic * fix(health): cancel in-flight futures on generic failure * feat(health): add gpl license header
# Conflicts: # pom.xml # src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java # src/main/java/com/iemr/hwc/repo/nurse/ncdcare/NCDCareDiagnosisRepo.java
Merge 3.6.1 to 3.8.0
📝 WalkthroughWalkthroughThis PR introduces version 3.8.0 with Elasticsearch search capability additions and propagates a new Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant RegistrarController
participant RegistrarService
participant ElasticsearchAPI as Elasticsearch<br/>API
Client->>RegistrarController: POST /registrar/quickSearchES<br/>(requestObj, Authorization)
activate RegistrarController
RegistrarController->>RegistrarService: beneficiaryQuickSearchES(requestObj, Authorization)
activate RegistrarService
RegistrarService->>RegistrarService: Parse JSON request<br/>Extract search field
alt Search field present
RegistrarService->>ElasticsearchAPI: POST to registrarQuickSearchByESUrl<br/>(requestObj)
activate ElasticsearchAPI
ElasticsearchAPI-->>RegistrarService: Response body
deactivate ElasticsearchAPI
RegistrarService->>RegistrarService: Return response
else Search field absent/null
RegistrarService->>RegistrarService: Return null/error
end
RegistrarService-->>RegistrarController: Result
deactivate RegistrarService
RegistrarController-->>Client: searchList or error response
deactivate RegistrarController
sequenceDiagram
participant DoctorController
participant DoctorService
participant NurseService
participant CommonDoctorService
participant BenFlowStatusService
participant BenFlowStatusRepo
DoctorController->>DoctorService: saveDoctorData(requestObj)
activate DoctorService
DoctorService->>DoctorService: Extract doctorSignatureFlag<br/>(default: false)
DoctorService->>NurseService: saveBenPrescribedDrugsList(drugs)
activate NurseService
NurseService-->>DoctorService: Map{count, prescribedDrugIDs}
deactivate NurseService
DoctorService->>DoctorService: Extract count & IDs from Map<br/>Store savedDrugIDs in request
DoctorService->>CommonDoctorService: updateBenFlowtableAfterDocDataSave(...,<br/>doctorSignatureFlag)
activate CommonDoctorService
CommonDoctorService->>BenFlowStatusService: updateBenFlowAfterDocData(...,<br/>doctorSignatureFlag)
activate BenFlowStatusService
BenFlowStatusService->>BenFlowStatusRepo: updateBenFlowStatusAfterDoctorActivity(...,<br/>doctorSignatureFlag)
activate BenFlowStatusRepo
BenFlowStatusRepo->>BenFlowStatusRepo: UPDATE query set<br/>doctorSignatureFlag
BenFlowStatusRepo-->>BenFlowStatusService: Success
deactivate BenFlowStatusRepo
BenFlowStatusService-->>CommonDoctorService: Success
deactivate BenFlowStatusService
CommonDoctorService-->>DoctorService: Success
deactivate CommonDoctorService
DoctorService-->>DoctorController: Result
deactivate DoctorService
DoctorController->>DoctorController: Build response with<br/>prescribedDrugIDs
DoctorController-->>Client: JSON response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.41.1)src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.javaThanks 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 |
|
There was a problem hiding this comment.
Actionable comments posted: 18
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/main/java/com/iemr/hwc/repo/benFlowStatus/BeneficiaryFlowStatusRepo.java (1)
236-276:⚠️ Potential issue | 🟠 MajorAdd
doctorSignatureFlagparameter to specialist doctor activity update methods for consistency.The
doctorSignatureFlagis properly handled inupdateBenFlowStatusAfterDoctorActivity, but the three specialist variant methods (updateBenFlowStatusAfterDoctorActivitySpecialist,updateBenFlowStatusAfterDoctorActivitySpecialistANC, andupdateBenFlowStatusAfterDoctorActivityTCSpecialist) lack this parameter. Their SQL queries also do not update this field. Since the service layer (CommonBenStatusFlowServiceImpl) has access todoctorSignatureFlagfor these specialist flows, the repository methods should accept and propagate this flag to maintain consistency across all doctor activity updates.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/repo/benFlowStatus/BeneficiaryFlowStatusRepo.java` around lines 236 - 276, The three specialist update methods (updateBenFlowStatusAfterDoctorActivitySpecialist, updateBenFlowStatusAfterDoctorActivitySpecialistANC, updateBenFlowStatusAfterDoctorActivityTCSpecialist) are missing a doctorSignatureFlag parameter and do not update t.doctor_signature_flag in their JPQL; add a new `@Param`("doctorSignatureFlag") Short doctorSignatureFlag to each method signature and include "t.doctor_signature_flag = :doctorSignatureFlag" in their `@Query` UPDATE clauses so the repository stores the passed flag consistent with updateBenFlowStatusAfterDoctorActivity.src/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.java (1)
1187-1209:⚠️ Potential issue | 🟠 MajorResolve the latest ANC visit once for the whole nurse payload.
This method now backfills ANC care/vaccine data with
benVisitIdwhenvisitCodeis absent, but the aggregategetBenANCNurseData(...)path still requests history, vitals, examination, and CDSS with the originalvisitCode. A null-visit caller can therefore get a mixed record for one screen.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.java` around lines 1187 - 1209, The method getBenANCNurseData(...) resolves visitCode/benVisitId in multiple places causing mixed data when visitCode is null; determine the canonical visit identifier once (e.g., if visitCode==null use benVisitId, otherwise use visitCode) and store it in local variables (e.g., resolvedVisitCode or resolvedBenVisitId and a boolean useBenVisitId), then use that single resolution for all downstream calls (ancNurseServiceImpl.getANCCareDetails*, getANCWomenVaccineDetails*, and the history/vitals/examination/CDSS calls that currently use visitCode) so every part of the nurse payload is fetched consistently using the same identifier. Ensure all callers reference these resolved variables rather than re-checking visitCode/benVisitId.src/main/java/com/iemr/hwc/service/benFlowStatus/CommonBenStatusFlowServiceImpl.java (1)
292-305:⚠️ Potential issue | 🟠 MajorDon't blindly overwrite
doctorSignatureFlagon update.This update path now forwards the flag directly into the repository update, which writes the column unconditionally. Because several new callers default an omitted field to
false, an edit from an older client can clear a previously stored signature unless the existing DB value is preserved when the field is absent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/benFlowStatus/CommonBenStatusFlowServiceImpl.java` around lines 292 - 305, The update unconditionally writes doctorSignatureFlag into beneficiaryFlowStatusRepo.updateBenFlowStatusAfterDoctorActivity, which lets newer callers that default this field to false overwrite an existing signature; change the code in CommonBenStatusFlowServiceImpl so that before calling updateBenFlowStatusAfterDoctorActivity you resolve doctorSignatureFlag: if the incoming doctorSignatureFlag is null/absent, fetch the current value from the repository (e.g., via a getter like beneficiaryFlowStatusRepo.getDoctorSignatureFlag(benFlowID) or an equivalent method) and pass that preserved value to updateBenFlowStatusAfterDoctorActivity; otherwise pass the provided flag. Ensure you reference doctorSignatureFlag and updateBenFlowStatusAfterDoctorActivity when making the change.src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.java (1)
3233-3264:⚠️ Potential issue | 🟡 MinorReturn an actual saved count from the new result object.
The empty-list path still returns
count = 1whileprescribedDrugIDs = []. The new contract is already consumed ascountplusprescribedDrugIDsinsrc/main/java/com/iemr/hwc/service/adolescent/AdolescentAndChildCareServiceImpl.java:1058-1067andsrc/main/java/com/iemr/hwc/service/ncdscreening/NCDSCreeningDoctorServiceImpl.java:217-223, so a no-op now looks like one saved drug. Keepcountas the persisted row count, and add a separate success flag only if callers still need the old sentinel behavior.♻️ Proposed fix
public Map<String, Object> saveBenPrescribedDrugsList(List<PrescribedDrugDetail> prescribedDrugDetailList) { Map<String, Object> result = new HashMap<>(); List<Long> prescribedDrugIDs = new ArrayList<>(); - Integer r = 0; + Integer savedCount = 0; if (prescribedDrugDetailList.size() > 0) { for (PrescribedDrugDetail obj : prescribedDrugDetailList) { if (obj.getFormName().equalsIgnoreCase("Tablet") || obj.getFormName().equalsIgnoreCase("Capsule")) { int qtyPrescribed = calculateQtyPrescribed(obj.getFormName(), obj.getDose(), obj.getFrequency(), obj.getDuration(), obj.getUnit()); obj.setQtyPrescribed(qtyPrescribed); } } List<PrescribedDrugDetail> prescribedDrugDetailListRS = (List<PrescribedDrugDetail>) prescribedDrugDetailRepo .saveAll(prescribedDrugDetailList); if (prescribedDrugDetailList.size() == prescribedDrugDetailListRS.size()) { - r = prescribedDrugDetailListRS.size(); + savedCount = prescribedDrugDetailListRS.size(); for (PrescribedDrugDetail savedDrug : prescribedDrugDetailListRS) { if (savedDrug.getId() != null) { prescribedDrugIDs.add(savedDrug.getId()); } } } - } else { - r = 1; } - result.put("count", r); + result.put("count", savedCount); result.put("prescribedDrugIDs", prescribedDrugIDs); return result; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.java` around lines 3233 - 3264, The method saveBenPrescribedDrugsList currently sets r = 1 for the empty-list path which falsely reports one saved row; change the logic so r reflects the actual persisted row count (0 when prescribedDrugDetailList is empty) and only set r = prescribedDrugDetailListRS.size() after saveAll; ensure prescribedDrugIDs is populated from prescribedDrugDetailListRS as already done; if callers need the previous sentinel behavior add a separate boolean (e.g., "success") instead of returning count=1.
🟡 Minor comments (6)
src/main/java/com/iemr/hwc/controller/covid19/CovidController.java-372-389 (1)
372-389:⚠️ Potential issue | 🟡 MinorSame concern applies to update path.
This duplicates the same pattern from
saveBenCovidDoctorData- readingsavedDrugIDsfrom input rather than service output.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/covid19/CovidController.java` around lines 372 - 389, The update path in CovidController duplicates the save path bug by extracting "savedDrugIDs" directly from the input JsonObject (jsnOBJ) instead of using the service/update result; in the update flow replace the input-derived extraction (the block that builds prescribedDrugIDs from jsnOBJ.getAsJsonArray("savedDrugIDs")) with the IDs returned by the update service call (the same approach used to fix saveBenCovidDoctorData), and ensure the responseData.put("prescribedDrugIDs", ...) uses the service's output list before serializing and calling response.setResponse(...).src/main/java/com/iemr/hwc/service/ncdscreening/NCDSCreeningDoctorServiceImpl.java-227-229 (1)
227-229:⚠️ Potential issue | 🟡 MinorIncorrect null check order - potential NPE if unboxing null.
The condition
r > 0 && r != nullchecksr > 0before checking ifris null. Ifris null, unboxing it to compare with0will throw aNullPointerException.🐛 Fix condition order
- if (r > 0 && r != null) { + if (r != null && r > 0) { prescriptionSuccessFlag = r; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/ncdscreening/NCDSCreeningDoctorServiceImpl.java` around lines 227 - 229, The null-check and comparison order is unsafe: in NCDSCreeningDoctorServiceImpl where variable r is evaluated, change the condition from "r > 0 && r != null" to check null first (e.g., "r != null && r > 0") or use Objects.nonNull(r) before performing the numeric comparison, then set prescriptionSuccessFlag = r only when the null-safe condition passes.src/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.java-1437-1439 (1)
1437-1439:⚠️ Potential issue | 🟡 MinorNull check should precede the comparison to avoid potential NPE.
The condition
if (r > 0 && r != null)will evaluater > 0first, which throws aNullPointerExceptionifrisnulldue to auto-unboxing. Reorder the checks:Proposed fix
- if (r > 0 && r != null) { + if (r != null && r > 0) { prescriptionSuccessFlag = r; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.java` around lines 1437 - 1439, The null-check for the Integer variable r is after the numeric comparison which can cause an NPE; in NCDScreeningServiceImpl change the condition used where r is evaluated (the if block that assigns prescriptionSuccessFlag) to check for null first (e.g., r != null && r > 0 or Objects.nonNull(r) && r > 0) so you only evaluate r > 0 when r is non-null before assigning prescriptionSuccessFlag = r.src/main/java/com/iemr/hwc/service/family_planning/FamilyPlanningServiceImpl.java-951-953 (1)
951-953:⚠️ Potential issue | 🟡 MinorNull check should precede the comparison to avoid potential NPE.
Same issue as in
NCDScreeningServiceImpl: the conditionif (r > 0 && r != null)will throw aNullPointerExceptionifrisnull.Proposed fix
- if (r > 0 && r != null) { + if (r != null && r > 0) { prescriptionSuccessFlag = r; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/family_planning/FamilyPlanningServiceImpl.java` around lines 951 - 953, The null-check and comparison on variable r are reversed causing a possible NPE; in FamilyPlanningServiceImpl replace the condition "if (r > 0 && r != null)" with a null-first guard (e.g., check r != null before r > 0) so that prescriptionSuccessFlag is only assigned when r is non-null and greater than zero; update the conditional surrounding assignment to prescriptionSuccessFlag accordingly.src/main/java/com/iemr/hwc/controller/registrar/main/RegistrarController.java-328-330 (1)
328-330:⚠️ Potential issue | 🟡 MinorKeep backend exception text out of the API response.
Appending
e.getMessage()here can expose Elasticsearch or internal network details to clients. Log the exception server-side and return a fixed error message instead.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/registrar/main/RegistrarController.java` around lines 328 - 330, In the RegistrarController catch block handling ES Advance Search (the catch(Exception e) where logger.error(...) and response.setError(...) are called), stop exposing e.getMessage() to clients: keep the server-side logging (logger.error("Error in ES Advance Search: {}", e.getMessage(), e)) so the exception is recorded, but change the response.setError(5000, ...) call to return a fixed generic message (e.g., "Error while searching beneficiary") without including e.getMessage() or any internal details.src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.java-3112-3127 (1)
3112-3127:⚠️ Potential issue | 🟡 MinorKeep diagnosis serialization identical on save and update.
saveBenPrescriptionnow builds separators from accumulated output, butupdatePrescriptionat Lines 3149-3172 still uses the oldpointer == list.size()logic. For inputs like[A, null], create will persistAwhile update can still persistA ||. Please extract one helper and reuse it in both paths so the stored diagnosis fields do not drift.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.java` around lines 3112 - 3127, The diagnosis concatenation logic differs between saveBenPrescription and updatePrescription causing trailing separators for null entries; extract the append/serialize logic into a single helper (e.g., a private method serializeDiagnosis(List<Diagnosis> or serializeTermAndConcept(Diagnosis obj, StringBuilder pdTerm, StringBuilder pdConceptID)) and call it from both saveBenPrescription and updatePrescription so both use the same rules (skip null terms/conceptIDs and only insert " || " between real entries). Update references to pdTerm/pdConceptID building in both methods to use that helper so stored diagnosis fields remain identical on create and update.
🧹 Nitpick comments (12)
src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java (1)
44-48: Remove duplicate imports.These imports are duplicates of lines 28-31.
🧹 Proposed fix
-import com.google.gson.annotations.Expose; -import com.iemr.hwc.annotation.sqlInjectionSafe.SQLInjectionSafe; -import com.iemr.hwc.data.login.MasterVan; -import com.iemr.hwc.data.masterdata.registrar.GenderMaster; -🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java` around lines 44 - 48, The file BeneficiaryFlowStatus contains duplicated import statements (com.google.gson.annotations.Expose, com.iemr.hwc.annotation.sqlInjectionSafe.SQLInjectionSafe, com.iemr.hwc.data.login.MasterVan, com.iemr.hwc.data.masterdata.registrar.GenderMaster) — remove the redundant second set so each import appears only once; locate the duplicate block in the BeneficiaryFlowStatus class and delete it, keeping the original import declarations intact.src/main/java/com/iemr/hwc/data/ncdcare/NCDCareDiagnosis.java (1)
407-409: Redundant setter calls.The constructor at lines 382-398 already assigns
createdByandcreatedDatefromobj[9]andobj[10]. These explicit setter calls immediately after construction are unnecessary.🧹 Proposed fix
cOBJ = new NCDCareDiagnosis((Long) obj[0], (Long) obj[1], (Integer) obj[2], (Long) obj[3], (String) obj[4], (String) obj[5], (String) obj[6], (Long) obj[7], null, (String) obj[8], (String) obj[9], (Timestamp) obj[10]); - - // Set audit fields - cOBJ.setCreatedBy((String) obj[9]); - cOBJ.setCreatedDate((Timestamp) obj[10]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/data/ncdcare/NCDCareDiagnosis.java` around lines 407 - 409, Remove the redundant post-construction assignments to the audit fields: delete the calls to cOBJ.setCreatedBy((String) obj[9]) and cOBJ.setCreatedDate((Timestamp) obj[10]) since the NCDCareDiagnosis constructor (the block that maps obj[9] and obj[10] to createdBy/createdDate around lines 382-398) already initializes these fields; leave the constructor initialization as-is and remove only the duplicate setter invocations following construction.src/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.java (1)
38-38: Remove duplicate Gson import.
Gsonis imported twice: on line 38 and line 50.🧹 Remove duplicate import
import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.iemr.hwc.data.quickConsultation.WrapperQuickConsultation; import com.iemr.hwc.service.quickConsultation.QuickConsultationServiceImpl; import com.iemr.hwc.utils.mapper.InputMapper; import com.iemr.hwc.utils.response.OutputResponse; import io.swagger.v3.oas.annotations.Operation; import java.util.*; -import com.google.gson.Gson; import com.google.gson.JsonArray;Also applies to: 49-51
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.java` at line 38, Remove the duplicate import of com.google.gson.Gson in QuickConsultController.java: locate the repeated import statements for Gson (the import of class Gson) and delete the redundant one so only a single import com.google.gson.Gson; remains; ensure no other imports around (lines importing Gson) are duplicated to avoid compilation warnings.src/main/java/com/iemr/hwc/controller/cancerscreening/CancerScreeningController.java (2)
129-145: Consider extracting duplicated drug ID extraction logic into a utility method.This exact pattern for extracting
savedDrugIDsand building the response map is repeated in bothsaveBenCancerScreeningDoctorData(lines 129-145) andupdateCancerScreeningDoctorData(lines 600-616), as well as across multiple other controllers in this PR.♻️ Suggested helper method (could be placed in a utility class)
public static Map<String, Object> buildDrugResponseData(JsonObject jsnOBJ, String message) { List<Long> prescribedDrugIDs = new ArrayList<>(); if (jsnOBJ.has("savedDrugIDs") && !jsnOBJ.get("savedDrugIDs").isJsonNull()) { JsonArray drugIDsArray = jsnOBJ.getAsJsonArray("savedDrugIDs"); for (int j = 0; j < drugIDsArray.size(); j++) { prescribedDrugIDs.add(drugIDsArray.get(j).getAsLong()); } } Map<String, Object> responseData = new HashMap<>(); responseData.put("message", message); responseData.put("prescribedDrugIDs", prescribedDrugIDs); return responseData; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/cancerscreening/CancerScreeningController.java` around lines 129 - 145, Extract the duplicated logic that reads "savedDrugIDs" from a JsonObject and builds the response map into a single reusable utility method (e.g., buildDrugResponseData(JsonObject jsnOBJ, String message)) and replace the repeated blocks in saveBenCancerScreeningDoctorData and updateCancerScreeningDoctorData with a call to that helper; the helper should create the List<Long> prescribedDrugIDs by checking jsnOBJ.has("savedDrugIDs") && !jsnOBJ.get("savedDrugIDs").isJsonNull(), iterate the JsonArray to add longs, then return a Map<String,Object> containing "message" and "prescribedDrugIDs" which the controllers serialize and set on response.
600-616: Duplicate code block - same extraction pattern as in save method.This is the same drug ID extraction and response building logic as lines 129-145. Consider the refactoring suggestion above to reduce duplication.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/cancerscreening/CancerScreeningController.java` around lines 600 - 616, The block that extracts savedDrugIDs into prescribedDrugIDs and builds the response (using prescribedDrugIDs, savedDrugIDs, jsnOBJ and response.setResponse) duplicates logic already present in the save method; refactor by extracting this into a reusable private helper (e.g., a method like extractPrescribedDrugIdsAndBuildResponse or extractSavedDrugIds) that accepts the JsonObject (jsnOBJ) and returns the List<Long> or the response JSON, then call that helper from both the current update flow and the save method to remove duplication and centralize the JSON extraction and response construction.src/main/java/com/iemr/hwc/service/adolescent/AdolescentAndChildCareServiceImpl.java (1)
1058-1067: Unchecked cast may generate compiler warning.Line 1061 performs an unchecked cast from
ObjecttoList<Long>. While this should work at runtime (assuming the service returns the expected type), it may generate a compiler warning.💡 Consider adding `@SuppressWarnings` or explicit type checking
// Option 1: Add annotation at method level `@SuppressWarnings`("unchecked") // Option 2: Add null/type check Object drugIDsObj = drugSaveResult.get("prescribedDrugIDs"); List<Long> prescribedDrugIDs = (drugIDsObj instanceof List) ? (List<Long>) drugIDsObj : Collections.emptyList();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/adolescent/AdolescentAndChildCareServiceImpl.java` around lines 1058 - 1067, The unchecked cast of drugSaveResult.get("prescribedDrugIDs") to List<Long> can produce compiler warnings; update the code in AdolescentAndChildCareServiceImpl where you call commonNurseServiceImpl.saveBenPrescribedDrugsList and assign to prescribedDrugIDs so it safely handles types (e.g., retrieve into Object drugIDsObj, check instanceof List before casting and fall back to an empty List<Long>), or if you intentionally accept the unchecked cast, annotate the enclosing method with `@SuppressWarnings`("unchecked"); ensure requestOBJ.add("savedDrugIDs", ...) still uses a List<Long> variable after the safe check.src/main/java/com/iemr/hwc/controller/anc/AntenatalCareController.java (1)
565-581: Minor formatting inconsistency.Line 565 has an extra leading space before the comment compared to the surrounding code block.
🧹 Fix indentation
try { Long result = ancService.updateANCDoctorData(jsnOBJ, Authorization); if (null != result && result > 0) { - // Extract drug IDs from JsonObject + // Extract drug IDs from JsonObject List<Long> prescribedDrugIDs = new ArrayList<>();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/anc/AntenatalCareController.java` around lines 565 - 581, The comment indentation in AntenatalCareController's block that extracts drug IDs is inconsistent (there is an extra leading space before the comment "// Extract drug IDs from JsonObject"); fix by removing the extra leading space so the comment aligns with surrounding code in the method (the block containing prescribedDrugIDs, drugIDsArray loop, and responseData creation), ensuring consistent indentation/formatting across the extract-and-response section.src/main/java/com/iemr/hwc/controller/generalOPD/GeneralOPDController.java (1)
24-26: Remove duplicate imports.Imports are duplicated:
java.util.ArrayListat lines 24 and 48java.util.HashMapat lines 25 and 49com.google.gson.Gsonat lines 41 and 52Suggested cleanup
import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.json.JSONObject; ... import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; ... -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import com.google.gson.Gson; -import com.google.gson.JsonArray; - import io.swagger.v3.oas.annotations.Operation;Also applies to: 41-41, 48-54
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/generalOPD/GeneralOPDController.java` around lines 24 - 26, In GeneralOPDController.java remove the duplicate import lines for java.util.ArrayList, java.util.HashMap, and com.google.gson.Gson so each type is imported only once; locate the import block near the top of the GeneralOPDController class and keep a single import statement for ArrayList, HashMap and Gson (remove the extras) and then reformat/organize the import section to avoid further duplicates.src/main/java/com/iemr/hwc/controller/ncdscreening/NCDScreeningController.java (2)
169-186: Consider extracting duplicated response-building logic.The same logic for extracting
savedDrugIDsand building the response map is duplicated insaveBenNCDScreeningDoctorDataandupdateDoctorData. This pattern is also repeated across multiple controllers in this PR.Consider creating a utility method to reduce duplication and ensure consistency:
private String buildDoctorDataResponse(JsonObject jsnOBJ, String message) { List<Long> prescribedDrugIDs = new ArrayList<>(); if (jsnOBJ.has("savedDrugIDs") && !jsnOBJ.get("savedDrugIDs").isJsonNull()) { JsonArray drugIDsArray = jsnOBJ.getAsJsonArray("savedDrugIDs"); for (int j = 0; j < drugIDsArray.size(); j++) { prescribedDrugIDs.add(drugIDsArray.get(j).getAsLong()); } } Map<String, Object> responseData = new HashMap<>(); responseData.put("message", message); responseData.put("prescribedDrugIDs", prescribedDrugIDs); return new Gson().toJson(responseData); }Also applies to: 623-641
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/ncdscreening/NCDScreeningController.java` around lines 169 - 186, Duplicate logic extracting "savedDrugIDs" and building the JSON response appears in saveBenNCDScreeningDoctorData and updateDoctorData (and elsewhere); refactor by adding a single helper method (e.g., buildDoctorDataResponse(JsonObject jsnOBJ, String message) either as a private method in NCDScreeningController or a shared utility) that reads jsnOBJ.getAsJsonArray("savedDrugIDs") into a List<Long>, constructs the Map with "message" and "prescribedDrugIDs", converts it to JSON and returns the string; replace the duplicated blocks in saveBenNCDScreeningDoctorData and updateDoctorData (and other controllers flagged) to call this helper and set response.setResponse(...) with its result to ensure consistency and remove duplication.
24-27: Remove duplicate imports.Several imports are duplicated:
java.util.Mapappears at line 27 and line 59com.google.gson.Gsonappears at line 45 and line 52com.iemr.hwc.service.common.transaction.CommonDoctorServiceImplappears at line 51 and line 60- Line 61 has a wildcard import
org.springframework.web.bind.annotation.*that overlaps with specific imports aboveSuggested cleanup
package com.iemr.hwc.controller.ncdscreening; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.iemr.hwc.data.nurse.CommonUtilityClass; import com.iemr.hwc.service.common.transaction.CommonDoctorServiceImpl; import com.iemr.hwc.service.ncdscreening.NCDSCreeningDoctorService; import com.iemr.hwc.service.ncdscreening.NCDScreeningService; import com.iemr.hwc.utils.exception.IEMRException; import com.iemr.hwc.utils.response.OutputResponse; import io.swagger.v3.oas.annotations.Operation; -import java.util.Map; -import com.iemr.hwc.service.common.transaction.CommonDoctorServiceImpl; -import org.springframework.web.bind.annotation.*;Also applies to: 45-54, 59-61
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/ncdscreening/NCDScreeningController.java` around lines 24 - 27, The import section in NCDScreeningController contains duplicate and overlapping imports (e.g., java.util.Map, com.google.gson.Gson, com.iemr.hwc.service.common.transaction.CommonDoctorServiceImpl) and a wildcard import org.springframework.web.bind.annotation.* that conflicts with specific Spring imports; clean this by removing the repeated import lines, delete the wildcard import and retain only the specific Spring annotations you actually use, and ensure each class (Map, Gson, CommonDoctorServiceImpl, etc.) is imported exactly once so the compiler and IDE warnings are resolved.src/main/java/com/iemr/hwc/controller/pnc/PostnatalCareController.java (1)
38-38: Remove duplicate Gson import.
com.google.gson.Gsonis imported at line 38 and again at line 48.Suggested cleanup
import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; ... import java.util.*; -import com.google.gson.Gson; import com.google.gson.JsonArray;Also applies to: 47-49
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/controller/pnc/PostnatalCareController.java` at line 38, Remove the duplicated import of com.google.gson.Gson in PostnatalCareController: locate the duplicate import statements for Gson (the import lines referencing com.google.gson.Gson) and keep a single import, removing the redundant one so imports are not repeated.src/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.java (1)
1426-1435: Unchecked cast warning forList<Long>extraction.The cast
(List<Long>) drugSaveResult.get("prescribedDrugIDs")is unchecked at compile time. While this is acceptable given the known contract withCommonNurseServiceImpl.saveBenPrescribedDrugsList(...), consider adding a brief comment documenting this assumption for maintainability.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.java` around lines 1426 - 1435, The unchecked cast of drugSaveResult.get("prescribedDrugIDs") to (List<Long>) in NCDScreeningServiceImpl (after calling commonNurseServiceImpl.saveBenPrescribedDrugsList) should be made explicit: add a short comment above the cast documenting the contract/assumption that saveBenPrescribedDrugsList returns a List<Long> under the "prescribedDrugIDs" key, and either (a) apply a targeted `@SuppressWarnings`("unchecked") to the enclosing method/variable to acknowledge the unchecked cast, or (b) replace the cast with a safe check (Object ids = drugSaveResult.get("prescribedDrugIDs"); if (ids instanceof List) { List<?> temp = (List<?>) ids; map/convert entries to Longs }) before populating requestOBJ using Gson; reference the variables/methods drugSaveResult, saveBenPrescribedDrugsList, prescribedDrugIDs, requestOBJ and Gson.
🤖 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/hwc/controller/quickconsult/QuickConsultController.java`:
- Around line 296-311: The response-building block incorrectly reads
"savedDrugIDs" from jsnOBJ causing prescribedDrugIDs to be empty; change it to
read from quickConsultDoctorOBJ like the save path: check
quickConsultDoctorOBJ.has("savedDrugIDs") and
quickConsultDoctorOBJ.getAsJsonArray("savedDrugIDs") to populate the
prescribedDrugIDs list (prescribedDrugIDs variable), then serialize responseData
and call response.setResponse(responseJson) as before; ensure the logic mirrors
the save method's handling of savedDrugIDs.
In `@src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java`:
- Around line 303-306: The field doctorSignatureFlag in class
BeneficiaryFlowStatus is missing accessors; add a public getter and setter named
getDoctorSignatureFlag() returning Boolean and setDoctorSignatureFlag(Boolean
doctorSignatureFlag) to match the existing pattern of other fields so
persistence and service-layer code can read/write it; ensure the methods are
declared in the BeneficiaryFlowStatus class and follow the same visibility and
naming conventions as the other getters/setters.
In `@src/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.java`:
- Around line 465-476: Null-check the Integer 'r' before comparing to 0 to avoid
unboxing NPE: change the condition in ANCServiceImpl (after calling
commonNurseServiceImpl.saveBenPrescribedDrugsList and assigning Integer r) to
test r != null first (e.g., r != null && r > 0) before using r > 0; do the same
fix at the other occurrence noted (around lines 1847-1858) so both places guard
against a null count returned by saveBenPrescribedDrugsList.
- Around line 364-368: In ANCServiceImpl move the doctorSignatureFlag parsing
(the block that reads requestOBJ.has("doctorSignatureFlag") and
requestOBJ.get(...).getAsBoolean()) so it executes only after the requestOBJ
null/invalid check in both the save and update request handling paths; locate
the two places where doctorSignatureFlag is declared/used and ensure you first
verify requestOBJ != null (and any existing invalid-input handling) before
calling requestOBJ.has(...) to avoid a NullPointerException — apply the same
change to the other occurrence of this parsing later in the class (the second
doctorSignatureFlag block).
In
`@src/main/java/com/iemr/hwc/service/common/transaction/CommonDoctorServiceImpl.java`:
- Around line 742-745: The method updateBenFlowtableAfterDocDataSave currently
only applies doctorSignatureFlag in the non-specialist branch; update the
specialist branch so the doctorSignatureFlag argument is forwarded to the
specialist flow-update calls and persisted. Locate the specialist path inside
updateBenFlowtableAfterDocDataSave and pass doctorSignatureFlag into the
flow-update helper methods called there (and update those helper method
signatures where necessary so they accept a Boolean doctorSignatureFlag), then
ensure the flag is used when composing the DB/update payload so specialist
consults persist the signature flag; apply the same change to the other similar
call sites noted in the review (the other specialist flow-update calls
referenced).
In `@src/main/java/com/iemr/hwc/service/covid19/Covid19ServiceImpl.java`:
- Around line 1190-1202: Null-check the Map returned by
saveBenPrescribedDrugsList and its "count" value before using them: verify
drugSaveResult != null, then extract Object countObj =
drugSaveResult.get("count") and ensure countObj != null and is an Integer (or
convert safely) before assigning to r; only evaluate r > 0 after confirming r is
not null. Also keep the existing prescribedDrugIDs handling but guard any
further use of r (e.g., setting prescriptionSuccessFlag) behind the null-safe
check; replicate the same null-safety checks for the other occurrence of
saveBenPrescribedDrugsList handling (the block around prescriptionSuccessFlag
and requestOBJ elsewhere).
- Around line 1077-1081: The extraction of doctorSignatureFlag from requestOBJ
is happening before the null-check for requestOBJ, causing a
NullPointerException; move the doctor's flag read (the doctorSignatureFlag
boolean assignment and its requestOBJ.get/getAsBoolean checks) inside the
existing requestOBJ != null guard in the Covid19ServiceImpl save and update
flows so the null-request validation path runs as intended; update both
occurrences (the one around the doctorSignatureFlag declaration and the second
occurrence referenced at the other block) to only access requestOBJ after
confirming it is non-null.
In `@src/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.java`:
- Around line 947-960: Null-check the Map returned by
commonNurseServiceImpl.saveBenPrescribedDrugsList(...) (drugSaveResult) and
verify it contains a non-null numeric "count" before casting and comparing;
likewise guard prescribedDrugIDs before serializing. Concretely, in
GeneralOPDServiceImpl around where drugSaveResult, r, prescribedDrugIDs and
requestOBJ are used, first check drugSaveResult != null and
drugSaveResult.containsKey("count") and that drugSaveResult.get("count") is a
Number/Integer, then safely assign r; only evaluate r > 0 after that check and
only set prescriptionSuccessFlag when r != null && r > 0. Also ensure
prescribedDrugIDs is checked for null/empty before calling gson.toJsonTree and
handle the error path (e.g., set r = 0 or log) so no NullPointerException is
thrown.
- Around line 816-820: The parsing of the new boolean flag doctorSignatureFlag
currently checks requestOBJ.has(...) before the existing null guard, which can
cause an NPE; move the entire block that reads
requestOBJ.get("doctorSignatureFlag")/getAsBoolean() so it executes only after
the existing requestOBJ != null validation in the same methods (e.g., the save
and update handlers in GeneralOPDServiceImpl), and duplicate the same fix at the
other occurrence where doctorSignatureFlag is read (the second handler
referenced in the review) so both follow the established null-check/validation
flow.
In `@src/main/java/com/iemr/hwc/service/ncdCare/NCDCareServiceImpl.java`:
- Around line 857-861: The doctorSignatureFlag parsing accesses requestOBJ
before the null check and can cause NPE; move the Boolean doctorSignatureFlag =
false and its parsing (the block that checks
requestOBJ.has("doctorSignatureFlag") and calls getAsBoolean()) to after the
existing requestOBJ != null guard in NCDCareServiceImpl so requestOBJ is
validated first, and apply the same change to the other identical parsing block
found later in the class (the second doctorSignatureFlag parsing around the
1343–1347 area) so both instances only read requestOBJ after confirming it is
non-null.
- Around line 1007-1018: The code dereferences Integer r returned from
saveBenPrescribedDrugsList by evaluating r > 0 which will NPE if count is
missing; update the conditional to null-check r before comparing (e.g., change
the if that currently reads "if (r > 0 && r != null)" to check "r != null && r >
0") and apply the same pattern in the other occurrence around lines 1456-1468;
ensure the logic around requestOBJ.add("savedDrugIDs", ...) remains unchanged so
saved IDs still get added when prescribedDrugIDs is non-empty.
In `@src/main/java/com/iemr/hwc/service/neonatal/NeonatalServiceImpl.java`:
- Around line 1059-1068: The code calls saveBenPrescribedDrugsList and ignores
its result; check the returned drugSaveResult (variables r and
prescribedDrugIDs) and fail/abort the NNI update when no drugs were saved.
Specifically, after calling saveBenPrescribedDrugsList(prescribedDrugDetailList)
inspect Integer r = (Integer) drugSaveResult.get("count") and List<Long>
prescribedDrugIDs = (List<Long>) drugSaveResult.get("prescribedDrugIDs"); if r
is null or r <= 0 or prescribedDrugIDs is null/empty, do not proceed to update
the flow/NNI — return an error response or throw an exception so the update does
not succeed; only add savedDrugIDs to requestOBJ and continue when r > 0 and
prescribedDrugIDs contains items.
- Around line 265-269: Guard against a null requestOBJ before calling
requestOBJ.has(...) in NeonatalServiceImpl: update the doctorSignatureFlag logic
to first check requestOBJ != null (or Objects.nonNull(requestOBJ)) and only then
evaluate requestOBJ.has("doctorSignatureFlag") and
requestOBJ.get(...).isJsonNull(); apply the same null-check pattern to the other
occurrence noted (lines around 931-935) so both code paths safely handle a null
payload or return/handle early when requestOBJ is null.
In `@src/main/java/com/iemr/hwc/service/pnc/PNCServiceImpl.java`:
- Around line 317-321: The code in PNCServiceImpl dereferences requestOBJ when
reading doctorSignatureFlag (and similarly at lines 1563-1567) before checking
whether requestOBJ is null, which can throw a NullPointerException; fix by first
verifying requestOBJ != null (or otherwise handling a null requestOBJ) and only
then calling requestOBJ.has("doctorSignatureFlag") and
requestOBJ.get(...).getAsBoolean(); update the doctorSignatureFlag parsing block
(and the analogous block at 1563-1567) to perform the null check first and
provide a safe default when requestOBJ is null.
- Around line 425-436: The code uses Integer r = (Integer)
drugSaveResult.get("count") and then tests it with if (r > 0 && r != null) which
can throw NPE because r > 0 is evaluated first; change the null-check order so
you verify r != null before any comparison (e.g., if (r != null && r > 0)) where
this pattern appears in PNCServiceImpl around the block that calls
commonNurseServiceImpl.saveBenPrescribedDrugsList and for the similar occurrence
later (the block at the 1674-1685 region); ensure the same safe null-first check
is applied before assigning prescriptionSuccessFlag or using r.
In
`@src/main/java/com/iemr/hwc/service/quickConsultation/QuickConsultationServiceImpl.java`:
- Around line 420-432: The code assumes
commonNurseServiceImpl.saveBenPrescribedDrugsList(...) always returns a non-null
Map with a non-null "count"; add null checks: verify drugSaveResult != null and
that drugSaveResult.get("count") != null before casting to Integer (r) and
evaluating r > 0, and only then set prescriptionSuccessFlag; similarly guard
extraction and JSON serialization of prescribedDrugIDs (ensure the list is
non-null) before adding to quickConsultDoctorOBJ; apply the same null-guard
fixes to the other call site that also invokes saveBenPrescribedDrugsList.
- Around line 517-526: gson.fromJson(...) can return null causing
Arrays.asList(complaintsArray) to NPE; modify the flow in
QuickConsultationServiceImpl where you call getBenChiefComplaints and parse with
gson.fromJson (BenChiefComplaint[] complaintsArray) to first check if
complaintsArray is null and, if so, initialize benChiefComplaints to
Collections.emptyList() (or new ArrayList<>()), otherwise call
Arrays.asList(complaintsArray); then continue using benChiefComplaints for the
null/empty check and put into resMap as before (references:
getBenChiefComplaints, gson.fromJson, complaintsArray, Arrays.asList,
benChiefComplaints).
In `@src/main/java/com/iemr/hwc/service/registrar/RegistrarServiceImpl.java`:
- Around line 823-826: Remove the raw System.out.println debug dumps that print
the parsed JSONObject and the HttpEntity (the lines that reference JSONObject
obj and the request created by RestTemplateUtil.createRequestEntity), since they
may leak Authorization/JWT/cookie headers and sensitive beneficiary data;
instead either delete these print statements entirely or replace them with a
proper logger call at debug level that logs only non-sensitive, sanitized
information (do not log Authorization or the full HttpEntity content).
---
Outside diff comments:
In
`@src/main/java/com/iemr/hwc/repo/benFlowStatus/BeneficiaryFlowStatusRepo.java`:
- Around line 236-276: The three specialist update methods
(updateBenFlowStatusAfterDoctorActivitySpecialist,
updateBenFlowStatusAfterDoctorActivitySpecialistANC,
updateBenFlowStatusAfterDoctorActivityTCSpecialist) are missing a
doctorSignatureFlag parameter and do not update t.doctor_signature_flag in their
JPQL; add a new `@Param`("doctorSignatureFlag") Short doctorSignatureFlag to each
method signature and include "t.doctor_signature_flag = :doctorSignatureFlag" in
their `@Query` UPDATE clauses so the repository stores the passed flag consistent
with updateBenFlowStatusAfterDoctorActivity.
In `@src/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.java`:
- Around line 1187-1209: The method getBenANCNurseData(...) resolves
visitCode/benVisitId in multiple places causing mixed data when visitCode is
null; determine the canonical visit identifier once (e.g., if visitCode==null
use benVisitId, otherwise use visitCode) and store it in local variables (e.g.,
resolvedVisitCode or resolvedBenVisitId and a boolean useBenVisitId), then use
that single resolution for all downstream calls
(ancNurseServiceImpl.getANCCareDetails*, getANCWomenVaccineDetails*, and the
history/vitals/examination/CDSS calls that currently use visitCode) so every
part of the nurse payload is fetched consistently using the same identifier.
Ensure all callers reference these resolved variables rather than re-checking
visitCode/benVisitId.
In
`@src/main/java/com/iemr/hwc/service/benFlowStatus/CommonBenStatusFlowServiceImpl.java`:
- Around line 292-305: The update unconditionally writes doctorSignatureFlag
into beneficiaryFlowStatusRepo.updateBenFlowStatusAfterDoctorActivity, which
lets newer callers that default this field to false overwrite an existing
signature; change the code in CommonBenStatusFlowServiceImpl so that before
calling updateBenFlowStatusAfterDoctorActivity you resolve doctorSignatureFlag:
if the incoming doctorSignatureFlag is null/absent, fetch the current value from
the repository (e.g., via a getter like
beneficiaryFlowStatusRepo.getDoctorSignatureFlag(benFlowID) or an equivalent
method) and pass that preserved value to updateBenFlowStatusAfterDoctorActivity;
otherwise pass the provided flag. Ensure you reference doctorSignatureFlag and
updateBenFlowStatusAfterDoctorActivity when making the change.
In
`@src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.java`:
- Around line 3233-3264: The method saveBenPrescribedDrugsList currently sets r
= 1 for the empty-list path which falsely reports one saved row; change the
logic so r reflects the actual persisted row count (0 when
prescribedDrugDetailList is empty) and only set r =
prescribedDrugDetailListRS.size() after saveAll; ensure prescribedDrugIDs is
populated from prescribedDrugDetailListRS as already done; if callers need the
previous sentinel behavior add a separate boolean (e.g., "success") instead of
returning count=1.
---
Minor comments:
In `@src/main/java/com/iemr/hwc/controller/covid19/CovidController.java`:
- Around line 372-389: The update path in CovidController duplicates the save
path bug by extracting "savedDrugIDs" directly from the input JsonObject
(jsnOBJ) instead of using the service/update result; in the update flow replace
the input-derived extraction (the block that builds prescribedDrugIDs from
jsnOBJ.getAsJsonArray("savedDrugIDs")) with the IDs returned by the update
service call (the same approach used to fix saveBenCovidDoctorData), and ensure
the responseData.put("prescribedDrugIDs", ...) uses the service's output list
before serializing and calling response.setResponse(...).
In
`@src/main/java/com/iemr/hwc/controller/registrar/main/RegistrarController.java`:
- Around line 328-330: In the RegistrarController catch block handling ES
Advance Search (the catch(Exception e) where logger.error(...) and
response.setError(...) are called), stop exposing e.getMessage() to clients:
keep the server-side logging (logger.error("Error in ES Advance Search: {}",
e.getMessage(), e)) so the exception is recorded, but change the
response.setError(5000, ...) call to return a fixed generic message (e.g.,
"Error while searching beneficiary") without including e.getMessage() or any
internal details.
In
`@src/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.java`:
- Around line 3112-3127: The diagnosis concatenation logic differs between
saveBenPrescription and updatePrescription causing trailing separators for null
entries; extract the append/serialize logic into a single helper (e.g., a
private method serializeDiagnosis(List<Diagnosis> or
serializeTermAndConcept(Diagnosis obj, StringBuilder pdTerm, StringBuilder
pdConceptID)) and call it from both saveBenPrescription and updatePrescription
so both use the same rules (skip null terms/conceptIDs and only insert " || "
between real entries). Update references to pdTerm/pdConceptID building in both
methods to use that helper so stored diagnosis fields remain identical on create
and update.
In
`@src/main/java/com/iemr/hwc/service/family_planning/FamilyPlanningServiceImpl.java`:
- Around line 951-953: The null-check and comparison on variable r are reversed
causing a possible NPE; in FamilyPlanningServiceImpl replace the condition "if
(r > 0 && r != null)" with a null-first guard (e.g., check r != null before r >
0) so that prescriptionSuccessFlag is only assigned when r is non-null and
greater than zero; update the conditional surrounding assignment to
prescriptionSuccessFlag accordingly.
In
`@src/main/java/com/iemr/hwc/service/ncdscreening/NCDSCreeningDoctorServiceImpl.java`:
- Around line 227-229: The null-check and comparison order is unsafe: in
NCDSCreeningDoctorServiceImpl where variable r is evaluated, change the
condition from "r > 0 && r != null" to check null first (e.g., "r != null && r >
0") or use Objects.nonNull(r) before performing the numeric comparison, then set
prescriptionSuccessFlag = r only when the null-safe condition passes.
In
`@src/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.java`:
- Around line 1437-1439: The null-check for the Integer variable r is after the
numeric comparison which can cause an NPE; in NCDScreeningServiceImpl change the
condition used where r is evaluated (the if block that assigns
prescriptionSuccessFlag) to check for null first (e.g., r != null && r > 0 or
Objects.nonNull(r) && r > 0) so you only evaluate r > 0 when r is non-null
before assigning prescriptionSuccessFlag = r.
---
Nitpick comments:
In `@src/main/java/com/iemr/hwc/controller/anc/AntenatalCareController.java`:
- Around line 565-581: The comment indentation in AntenatalCareController's
block that extracts drug IDs is inconsistent (there is an extra leading space
before the comment "// Extract drug IDs from JsonObject"); fix by removing the
extra leading space so the comment aligns with surrounding code in the method
(the block containing prescribedDrugIDs, drugIDsArray loop, and responseData
creation), ensuring consistent indentation/formatting across the
extract-and-response section.
In
`@src/main/java/com/iemr/hwc/controller/cancerscreening/CancerScreeningController.java`:
- Around line 129-145: Extract the duplicated logic that reads "savedDrugIDs"
from a JsonObject and builds the response map into a single reusable utility
method (e.g., buildDrugResponseData(JsonObject jsnOBJ, String message)) and
replace the repeated blocks in saveBenCancerScreeningDoctorData and
updateCancerScreeningDoctorData with a call to that helper; the helper should
create the List<Long> prescribedDrugIDs by checking jsnOBJ.has("savedDrugIDs")
&& !jsnOBJ.get("savedDrugIDs").isJsonNull(), iterate the JsonArray to add longs,
then return a Map<String,Object> containing "message" and "prescribedDrugIDs"
which the controllers serialize and set on response.
- Around line 600-616: The block that extracts savedDrugIDs into
prescribedDrugIDs and builds the response (using prescribedDrugIDs,
savedDrugIDs, jsnOBJ and response.setResponse) duplicates logic already present
in the save method; refactor by extracting this into a reusable private helper
(e.g., a method like extractPrescribedDrugIdsAndBuildResponse or
extractSavedDrugIds) that accepts the JsonObject (jsnOBJ) and returns the
List<Long> or the response JSON, then call that helper from both the current
update flow and the save method to remove duplication and centralize the JSON
extraction and response construction.
In `@src/main/java/com/iemr/hwc/controller/generalOPD/GeneralOPDController.java`:
- Around line 24-26: In GeneralOPDController.java remove the duplicate import
lines for java.util.ArrayList, java.util.HashMap, and com.google.gson.Gson so
each type is imported only once; locate the import block near the top of the
GeneralOPDController class and keep a single import statement for ArrayList,
HashMap and Gson (remove the extras) and then reformat/organize the import
section to avoid further duplicates.
In
`@src/main/java/com/iemr/hwc/controller/ncdscreening/NCDScreeningController.java`:
- Around line 169-186: Duplicate logic extracting "savedDrugIDs" and building
the JSON response appears in saveBenNCDScreeningDoctorData and updateDoctorData
(and elsewhere); refactor by adding a single helper method (e.g.,
buildDoctorDataResponse(JsonObject jsnOBJ, String message) either as a private
method in NCDScreeningController or a shared utility) that reads
jsnOBJ.getAsJsonArray("savedDrugIDs") into a List<Long>, constructs the Map with
"message" and "prescribedDrugIDs", converts it to JSON and returns the string;
replace the duplicated blocks in saveBenNCDScreeningDoctorData and
updateDoctorData (and other controllers flagged) to call this helper and set
response.setResponse(...) with its result to ensure consistency and remove
duplication.
- Around line 24-27: The import section in NCDScreeningController contains
duplicate and overlapping imports (e.g., java.util.Map, com.google.gson.Gson,
com.iemr.hwc.service.common.transaction.CommonDoctorServiceImpl) and a wildcard
import org.springframework.web.bind.annotation.* that conflicts with specific
Spring imports; clean this by removing the repeated import lines, delete the
wildcard import and retain only the specific Spring annotations you actually
use, and ensure each class (Map, Gson, CommonDoctorServiceImpl, etc.) is
imported exactly once so the compiler and IDE warnings are resolved.
In `@src/main/java/com/iemr/hwc/controller/pnc/PostnatalCareController.java`:
- Line 38: Remove the duplicated import of com.google.gson.Gson in
PostnatalCareController: locate the duplicate import statements for Gson (the
import lines referencing com.google.gson.Gson) and keep a single import,
removing the redundant one so imports are not repeated.
In
`@src/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.java`:
- Line 38: Remove the duplicate import of com.google.gson.Gson in
QuickConsultController.java: locate the repeated import statements for Gson (the
import of class Gson) and delete the redundant one so only a single import
com.google.gson.Gson; remains; ensure no other imports around (lines importing
Gson) are duplicated to avoid compilation warnings.
In `@src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java`:
- Around line 44-48: The file BeneficiaryFlowStatus contains duplicated import
statements (com.google.gson.annotations.Expose,
com.iemr.hwc.annotation.sqlInjectionSafe.SQLInjectionSafe,
com.iemr.hwc.data.login.MasterVan,
com.iemr.hwc.data.masterdata.registrar.GenderMaster) — remove the redundant
second set so each import appears only once; locate the duplicate block in the
BeneficiaryFlowStatus class and delete it, keeping the original import
declarations intact.
In `@src/main/java/com/iemr/hwc/data/ncdcare/NCDCareDiagnosis.java`:
- Around line 407-409: Remove the redundant post-construction assignments to the
audit fields: delete the calls to cOBJ.setCreatedBy((String) obj[9]) and
cOBJ.setCreatedDate((Timestamp) obj[10]) since the NCDCareDiagnosis constructor
(the block that maps obj[9] and obj[10] to createdBy/createdDate around lines
382-398) already initializes these fields; leave the constructor initialization
as-is and remove only the duplicate setter invocations following construction.
In
`@src/main/java/com/iemr/hwc/service/adolescent/AdolescentAndChildCareServiceImpl.java`:
- Around line 1058-1067: The unchecked cast of
drugSaveResult.get("prescribedDrugIDs") to List<Long> can produce compiler
warnings; update the code in AdolescentAndChildCareServiceImpl where you call
commonNurseServiceImpl.saveBenPrescribedDrugsList and assign to
prescribedDrugIDs so it safely handles types (e.g., retrieve into Object
drugIDsObj, check instanceof List before casting and fall back to an empty
List<Long>), or if you intentionally accept the unchecked cast, annotate the
enclosing method with `@SuppressWarnings`("unchecked"); ensure
requestOBJ.add("savedDrugIDs", ...) still uses a List<Long> variable after the
safe check.
In
`@src/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.java`:
- Around line 1426-1435: The unchecked cast of
drugSaveResult.get("prescribedDrugIDs") to (List<Long>) in
NCDScreeningServiceImpl (after calling
commonNurseServiceImpl.saveBenPrescribedDrugsList) should be made explicit: add
a short comment above the cast documenting the contract/assumption that
saveBenPrescribedDrugsList returns a List<Long> under the "prescribedDrugIDs"
key, and either (a) apply a targeted `@SuppressWarnings`("unchecked") to the
enclosing method/variable to acknowledge the unchecked cast, or (b) replace the
cast with a safe check (Object ids = drugSaveResult.get("prescribedDrugIDs"); if
(ids instanceof List) { List<?> temp = (List<?>) ids; map/convert entries to
Longs }) before populating requestOBJ using Gson; reference the
variables/methods drugSaveResult, saveBenPrescribedDrugsList, prescribedDrugIDs,
requestOBJ and Gson.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0cd5e7d2-23bb-411a-8845-bc71b54aafea
📒 Files selected for processing (34)
pom.xmlsrc/main/environment/common_ci.propertiessrc/main/environment/common_docker.propertiessrc/main/environment/common_example.propertiessrc/main/java/com/iemr/hwc/controller/anc/AntenatalCareController.javasrc/main/java/com/iemr/hwc/controller/cancerscreening/CancerScreeningController.javasrc/main/java/com/iemr/hwc/controller/covid19/CovidController.javasrc/main/java/com/iemr/hwc/controller/generalOPD/GeneralOPDController.javasrc/main/java/com/iemr/hwc/controller/health/HealthController.javasrc/main/java/com/iemr/hwc/controller/ncdCare/NCDCareController.javasrc/main/java/com/iemr/hwc/controller/ncdscreening/NCDScreeningController.javasrc/main/java/com/iemr/hwc/controller/pnc/PostnatalCareController.javasrc/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.javasrc/main/java/com/iemr/hwc/controller/registrar/main/RegistrarController.javasrc/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.javasrc/main/java/com/iemr/hwc/data/ncdcare/NCDCareDiagnosis.javasrc/main/java/com/iemr/hwc/repo/benFlowStatus/BeneficiaryFlowStatusRepo.javasrc/main/java/com/iemr/hwc/repo/nurse/ncdcare/NCDCareDiagnosisRepo.javasrc/main/java/com/iemr/hwc/service/adolescent/AdolescentAndChildCareServiceImpl.javasrc/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.javasrc/main/java/com/iemr/hwc/service/benFlowStatus/CommonBenStatusFlowServiceImpl.javasrc/main/java/com/iemr/hwc/service/cancerScreening/CSServiceImpl.javasrc/main/java/com/iemr/hwc/service/common/transaction/CommonDoctorServiceImpl.javasrc/main/java/com/iemr/hwc/service/common/transaction/CommonNurseServiceImpl.javasrc/main/java/com/iemr/hwc/service/covid19/Covid19ServiceImpl.javasrc/main/java/com/iemr/hwc/service/family_planning/FamilyPlanningServiceImpl.javasrc/main/java/com/iemr/hwc/service/generalOPD/GeneralOPDServiceImpl.javasrc/main/java/com/iemr/hwc/service/ncdCare/NCDCareServiceImpl.javasrc/main/java/com/iemr/hwc/service/ncdscreening/NCDSCreeningDoctorServiceImpl.javasrc/main/java/com/iemr/hwc/service/ncdscreening/NCDScreeningServiceImpl.javasrc/main/java/com/iemr/hwc/service/neonatal/NeonatalServiceImpl.javasrc/main/java/com/iemr/hwc/service/pnc/PNCServiceImpl.javasrc/main/java/com/iemr/hwc/service/quickConsultation/QuickConsultationServiceImpl.javasrc/main/java/com/iemr/hwc/service/registrar/RegistrarServiceImpl.java
| List<Long> prescribedDrugIDs = new ArrayList<>(); | ||
| if (jsnOBJ.has("savedDrugIDs") && !jsnOBJ.get("savedDrugIDs").isJsonNull()) { | ||
| JsonArray drugIDsArray = jsnOBJ.getAsJsonArray("savedDrugIDs"); | ||
| for (int j = 0; j < drugIDsArray.size(); j++) { | ||
| prescribedDrugIDs.add(drugIDsArray.get(j).getAsLong()); | ||
| } | ||
| } | ||
|
|
||
| // Create response with message and IDs | ||
| Map<String, Object> responseData = new HashMap<>(); | ||
| responseData.put("message", "Data updated successfully"); | ||
| responseData.put("prescribedDrugIDs", prescribedDrugIDs); | ||
|
|
||
| Gson gson = new Gson(); | ||
| String responseJson = gson.toJson(responseData); | ||
| response.setResponse(responseJson); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify which object the service modifies when saving drug IDs
# Check the QuickConsultationServiceImpl to see where savedDrugIDs is populated
ast-grep --pattern $'requestOBJ.add("savedDrugIDs", $_)'
# Also search for how updateGeneralOPDQCDoctorData handles drug saving
rg -n "savedDrugIDs" --type java -C 3Repository: PSMRI/HWC-API
Length of output: 33630
🏁 Script executed:
# Check the updateGeneralOPDQCDoctorData method in QuickConsultController to see where quickConsultDoctorOBJ comes from
sed -n '280,320p' src/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.java
# Also check the service method signature to see what it returns
rg -n "updateGeneralOPDQCDoctorData" src/main/java/com/iemr/hwc/service/quickConsultation/ -A 5 -B 2Repository: PSMRI/HWC-API
Length of output: 2723
🏁 Script executed:
# Check the updateGeneralOPDQCDoctorData implementation to see if it modifies quickConsultDoctorOBJ with savedDrugIDs
sed -n '591,700p' src/main/java/com/iemr/hwc/service/quickConsultation/QuickConsultationServiceImpl.javaRepository: PSMRI/HWC-API
Length of output: 4664
🏁 Script executed:
# Check the save method (around line 143) to see how it reads savedDrugIDs
sed -n '135,155p' src/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.javaRepository: PSMRI/HWC-API
Length of output: 1042
Fix inconsistency: read savedDrugIDs from quickConsultDoctorOBJ instead of jsnOBJ.
The service populates savedDrugIDs on quickConsultDoctorOBJ during update (same as save), but this code reads from jsnOBJ (the outer parsed request). This always returns an empty list. The save method (line 141) correctly reads from quickConsultDoctorOBJ—the update method should do the same.
🐛 Suggested fix
if (null != result && result > 0) {
List<Long> prescribedDrugIDs = new ArrayList<>();
- if (jsnOBJ.has("savedDrugIDs") && !jsnOBJ.get("savedDrugIDs").isJsonNull()) {
- JsonArray drugIDsArray = jsnOBJ.getAsJsonArray("savedDrugIDs");
+ if (quickConsultDoctorOBJ.has("savedDrugIDs") && !quickConsultDoctorOBJ.get("savedDrugIDs").isJsonNull()) {
+ JsonArray drugIDsArray = quickConsultDoctorOBJ.getAsJsonArray("savedDrugIDs");
for (int j = 0; j < drugIDsArray.size(); j++) {
prescribedDrugIDs.add(drugIDsArray.get(j).getAsLong());
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| List<Long> prescribedDrugIDs = new ArrayList<>(); | |
| if (jsnOBJ.has("savedDrugIDs") && !jsnOBJ.get("savedDrugIDs").isJsonNull()) { | |
| JsonArray drugIDsArray = jsnOBJ.getAsJsonArray("savedDrugIDs"); | |
| for (int j = 0; j < drugIDsArray.size(); j++) { | |
| prescribedDrugIDs.add(drugIDsArray.get(j).getAsLong()); | |
| } | |
| } | |
| // Create response with message and IDs | |
| Map<String, Object> responseData = new HashMap<>(); | |
| responseData.put("message", "Data updated successfully"); | |
| responseData.put("prescribedDrugIDs", prescribedDrugIDs); | |
| Gson gson = new Gson(); | |
| String responseJson = gson.toJson(responseData); | |
| response.setResponse(responseJson); | |
| List<Long> prescribedDrugIDs = new ArrayList<>(); | |
| if (quickConsultDoctorOBJ.has("savedDrugIDs") && !quickConsultDoctorOBJ.get("savedDrugIDs").isJsonNull()) { | |
| JsonArray drugIDsArray = quickConsultDoctorOBJ.getAsJsonArray("savedDrugIDs"); | |
| for (int j = 0; j < drugIDsArray.size(); j++) { | |
| prescribedDrugIDs.add(drugIDsArray.get(j).getAsLong()); | |
| } | |
| } | |
| // Create response with message and IDs | |
| Map<String, Object> responseData = new HashMap<>(); | |
| responseData.put("message", "Data updated successfully"); | |
| responseData.put("prescribedDrugIDs", prescribedDrugIDs); | |
| Gson gson = new Gson(); | |
| String responseJson = gson.toJson(responseData); | |
| response.setResponse(responseJson); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/com/iemr/hwc/controller/quickconsult/QuickConsultController.java`
around lines 296 - 311, The response-building block incorrectly reads
"savedDrugIDs" from jsnOBJ causing prescribedDrugIDs to be empty; change it to
read from quickConsultDoctorOBJ like the save path: check
quickConsultDoctorOBJ.has("savedDrugIDs") and
quickConsultDoctorOBJ.getAsJsonArray("savedDrugIDs") to populate the
prescribedDrugIDs list (prescribedDrugIDs variable), then serialize responseData
and call response.setResponse(responseJson) as before; ensure the logic mirrors
the save method's handling of savedDrugIDs.
|
|
||
| @Expose | ||
| @Column(name = "doctor_signature_flag") | ||
| private Boolean doctorSignatureFlag = false; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for getter/setter or Lombok annotations
echo "=== Checking for doctorSignatureFlag accessors ==="
rg -n "getDoctorSignatureFlag|setDoctorSignatureFlag" --type=java
echo "=== Checking for Lombok annotations on BeneficiaryFlowStatus ==="
rg -nB5 "class BeneficiaryFlowStatus" --type=java | head -20Repository: PSMRI/HWC-API
Length of output: 737
🏁 Script executed:
#!/bin/bash
# Get file stats first
wc -l src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java
# Read the full file to understand the class structure
cat -n src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.javaRepository: PSMRI/HWC-API
Length of output: 29527
Add getter/setter methods for doctorSignatureFlag.
The field is persisted and exposed via @Expose but lacks accessor methods. The class does not use Lombok annotations, and all other fields follow a consistent pattern of having explicit getters/setters. Service layer code will fail when attempting to access this field.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/iemr/hwc/data/benFlowStatus/BeneficiaryFlowStatus.java`
around lines 303 - 306, The field doctorSignatureFlag in class
BeneficiaryFlowStatus is missing accessors; add a public getter and setter named
getDoctorSignatureFlag() returning Boolean and setDoctorSignatureFlag(Boolean
doctorSignatureFlag) to match the existing pattern of other fields so
persistence and service-layer code can read/write it; ensure the methods are
declared in the BeneficiaryFlowStatus class and follow the same visibility and
naming conventions as the other getters/setters.
| Boolean doctorSignatureFlag = false; | ||
| if (requestOBJ.has("doctorSignatureFlag") | ||
| && !requestOBJ.get("doctorSignatureFlag").isJsonNull()) { | ||
| doctorSignatureFlag = requestOBJ.get("doctorSignatureFlag").getAsBoolean(); | ||
| } |
There was a problem hiding this comment.
Move doctorSignatureFlag parsing behind the request null check.
Both save/update paths now call requestOBJ.has(...) before the existing requestOBJ != null guard, so a null request will fail with a NullPointerException instead of taking the invalid-input path.
🛠️ Suggested fix
- Boolean doctorSignatureFlag = false;
- if (requestOBJ.has("doctorSignatureFlag")
+ boolean doctorSignatureFlag = false;
+ if (requestOBJ != null && requestOBJ.has("doctorSignatureFlag")
&& !requestOBJ.get("doctorSignatureFlag").isJsonNull()) {
doctorSignatureFlag = requestOBJ.get("doctorSignatureFlag").getAsBoolean();
}Also applies to: 1734-1738
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.java` around lines 364
- 368, In ANCServiceImpl move the doctorSignatureFlag parsing (the block that
reads requestOBJ.has("doctorSignatureFlag") and
requestOBJ.get(...).getAsBoolean()) so it executes only after the requestOBJ
null/invalid check in both the save and update request handling paths; locate
the two places where doctorSignatureFlag is declared/used and ensure you first
verify requestOBJ != null (and any existing invalid-input handling) before
calling requestOBJ.has(...) to avoid a NullPointerException — apply the same
change to the other occurrence of this parsing later in the class (the second
doctorSignatureFlag block).
| Map<String, Object> drugSaveResult = commonNurseServiceImpl | ||
| .saveBenPrescribedDrugsList(prescribedDrugDetailList); | ||
| Integer r = (Integer) drugSaveResult.get("count"); | ||
| List<Long> prescribedDrugIDs = (List<Long>) drugSaveResult.get("prescribedDrugIDs"); | ||
|
|
||
| // Store IDs in JsonObject | ||
| if (prescribedDrugIDs != null && !prescribedDrugIDs.isEmpty()) { | ||
| Gson gson = new Gson(); | ||
| requestOBJ.add("savedDrugIDs", gson.toJsonTree(prescribedDrugIDs)); | ||
| } | ||
|
|
||
| if (r > 0 && r != null) { |
There was a problem hiding this comment.
Check the prescribed-drug count before unboxing it.
if (r > 0 && r != null) evaluates r > 0 first. If saveBenPrescribedDrugsList(...) returns a null/missing count, this path throws before the transaction can fail cleanly.
🛠️ Suggested fix
Map<String, Object> drugSaveResult = commonNurseServiceImpl
.saveBenPrescribedDrugsList(prescribedDrugDetailList);
-Integer r = (Integer) drugSaveResult.get("count");
-List<Long> prescribedDrugIDs = (List<Long>) drugSaveResult.get("prescribedDrugIDs");
+Integer r = drugSaveResult != null ? (Integer) drugSaveResult.get("count") : null;
+List<Long> prescribedDrugIDs = drugSaveResult != null
+ ? (List<Long>) drugSaveResult.get("prescribedDrugIDs")
+ : null;
@@
-if (r > 0 && r != null) {
+if (r != null && r > 0) {
prescriptionSuccessFlag = r;
}Also applies to: 1847-1858
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/iemr/hwc/service/anc/ANCServiceImpl.java` around lines 465
- 476, Null-check the Integer 'r' before comparing to 0 to avoid unboxing NPE:
change the condition in ANCServiceImpl (after calling
commonNurseServiceImpl.saveBenPrescribedDrugsList and assigning Integer r) to
test r != null first (e.g., r != null && r > 0) before using r > 0; do the same
fix at the other occurrence noted (around lines 1847-1858) so both places guard
against a null count returned by saveBenPrescribedDrugsList.
| public int updateBenFlowtableAfterDocDataSave(CommonUtilityClass commonUtilityClass, Boolean isTestPrescribed, | ||
| Boolean isMedicinePrescribed, TeleconsultationRequestOBJ tcRequestOBJ) throws IEMRException { | ||
| Boolean isMedicinePrescribed, TeleconsultationRequestOBJ tcRequestOBJ, Boolean doctorSignatureFlag) | ||
| throws IEMRException { | ||
| short pharmaFalg; |
There was a problem hiding this comment.
Propagate doctorSignatureFlag on specialist flows too.
The new argument is only used in the non-specialist branch. Any specialist request that includes doctorSignatureFlag still goes through flow-update methods with no signature parameter, so specialist consultations never persist the flag on either save or update.
Also applies to: 817-820, 842-845, 881-883, 929-931, 976-978
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/com/iemr/hwc/service/common/transaction/CommonDoctorServiceImpl.java`
around lines 742 - 745, The method updateBenFlowtableAfterDocDataSave currently
only applies doctorSignatureFlag in the non-specialist branch; update the
specialist branch so the doctorSignatureFlag argument is forwarded to the
specialist flow-update calls and persisted. Locate the specialist path inside
updateBenFlowtableAfterDocDataSave and pass doctorSignatureFlag into the
flow-update helper methods called there (and update those helper method
signatures where necessary so they accept a Boolean doctorSignatureFlag), then
ensure the flag is used when composing the DB/update payload so specialist
consults persist the signature flag; apply the same change to the other similar
call sites noted in the review (the other specialist flow-update calls
referenced).
| Boolean doctorSignatureFlag = false; | ||
| if (requestOBJ.has("doctorSignatureFlag") | ||
| && !requestOBJ.get("doctorSignatureFlag").isJsonNull()) { | ||
| doctorSignatureFlag = requestOBJ.get("doctorSignatureFlag").getAsBoolean(); | ||
| } |
There was a problem hiding this comment.
Parse doctorSignatureFlag only after confirming the request is non-null.
Both methods now dereference requestOBJ before the existing null check, which turns a null request into a NullPointerException.
🛠️ Suggested fix
- Boolean doctorSignatureFlag = false;
- if (requestOBJ.has("doctorSignatureFlag")
+ boolean doctorSignatureFlag = false;
+ if (requestOBJ != null && requestOBJ.has("doctorSignatureFlag")
&& !requestOBJ.get("doctorSignatureFlag").isJsonNull()) {
doctorSignatureFlag = requestOBJ.get("doctorSignatureFlag").getAsBoolean();
}Also applies to: 1563-1567
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/iemr/hwc/service/pnc/PNCServiceImpl.java` around lines 317
- 321, The code in PNCServiceImpl dereferences requestOBJ when reading
doctorSignatureFlag (and similarly at lines 1563-1567) before checking whether
requestOBJ is null, which can throw a NullPointerException; fix by first
verifying requestOBJ != null (or otherwise handling a null requestOBJ) and only
then calling requestOBJ.has("doctorSignatureFlag") and
requestOBJ.get(...).getAsBoolean(); update the doctorSignatureFlag parsing block
(and the analogous block at 1563-1567) to perform the null check first and
provide a safe default when requestOBJ is null.
| Map<String, Object> drugSaveResult = commonNurseServiceImpl | ||
| .saveBenPrescribedDrugsList(prescribedDrugDetailList); | ||
| Integer r = (Integer) drugSaveResult.get("count"); | ||
| List<Long> prescribedDrugIDs = (List<Long>) drugSaveResult.get("prescribedDrugIDs"); | ||
|
|
||
| // Store IDs in JsonObject | ||
| if (prescribedDrugIDs != null && !prescribedDrugIDs.isEmpty()) { | ||
| Gson gson = new Gson(); | ||
| requestOBJ.add("savedDrugIDs", gson.toJsonTree(prescribedDrugIDs)); | ||
| } | ||
| if (r > 0 && r != null) { | ||
| prescriptionSuccessFlag = r; |
There was a problem hiding this comment.
Null-check the prescribed-drug count before using it.
if (r > 0 && r != null) still evaluates r > 0 first. If the new map payload comes back without count, this path throws in the middle of the prescription flow.
🛠️ Suggested fix
Map<String, Object> drugSaveResult = commonNurseServiceImpl
.saveBenPrescribedDrugsList(prescribedDrugDetailList);
-Integer r = (Integer) drugSaveResult.get("count");
-List<Long> prescribedDrugIDs = (List<Long>) drugSaveResult.get("prescribedDrugIDs");
+Integer r = drugSaveResult != null ? (Integer) drugSaveResult.get("count") : null;
+List<Long> prescribedDrugIDs = drugSaveResult != null
+ ? (List<Long>) drugSaveResult.get("prescribedDrugIDs")
+ : null;
@@
-if (r > 0 && r != null) {
+if (r != null && r > 0) {
prescriptionSuccessFlag = r;
}Also applies to: 1674-1685
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/iemr/hwc/service/pnc/PNCServiceImpl.java` around lines 425
- 436, The code uses Integer r = (Integer) drugSaveResult.get("count") and then
tests it with if (r > 0 && r != null) which can throw NPE because r > 0 is
evaluated first; change the null-check order so you verify r != null before any
comparison (e.g., if (r != null && r > 0)) where this pattern appears in
PNCServiceImpl around the block that calls
commonNurseServiceImpl.saveBenPrescribedDrugsList and for the similar occurrence
later (the block at the 1674-1685 region); ensure the same safe null-first check
is applied before assigning prescriptionSuccessFlag or using r.
| // Use the modified method to get both count and IDs | ||
| Map<String, Object> drugSaveResult = commonNurseServiceImpl | ||
| .saveBenPrescribedDrugsList(prescribedDrugDetailList); | ||
| Integer r = (Integer) drugSaveResult.get("count"); | ||
| List<Long> prescribedDrugIDs = (List<Long>) drugSaveResult.get("prescribedDrugIDs"); | ||
|
|
||
| // Store the drug IDs in the JsonObject for later retrieval in controller | ||
| if (prescribedDrugIDs != null && !prescribedDrugIDs.isEmpty()) { | ||
| Gson gson = new Gson(); | ||
| quickConsultDoctorOBJ.add("savedDrugIDs", gson.toJsonTree(prescribedDrugIDs)); | ||
| } | ||
| if (r > 0 && r != null) { | ||
| prescriptionSuccessFlag = r; |
There was a problem hiding this comment.
Guard the new Map-based drug save result before using count.
Both save and update assume saveBenPrescribedDrugsList(...) always returns a non-null map with a non-null "count". On any failure path, r > 0 will NPE and mask the real persistence error.
Also applies to: 660-672
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/com/iemr/hwc/service/quickConsultation/QuickConsultationServiceImpl.java`
around lines 420 - 432, The code assumes
commonNurseServiceImpl.saveBenPrescribedDrugsList(...) always returns a non-null
Map with a non-null "count"; add null checks: verify drugSaveResult != null and
that drugSaveResult.get("count") != null before casting to Integer (r) and
evaluating r > 0, and only then set prescriptionSuccessFlag; similarly guard
extraction and JSON serialization of prescribedDrugIDs (ensure the list is
non-null) before adding to quickConsultDoctorOBJ; apply the same null-guard
fixes to the other call site that also invokes saveBenPrescribedDrugsList.
| String benChiefComplaintsJson = commonNurseServiceImpl.getBenChiefComplaints(benRegID, visitCode); | ||
| BenChiefComplaint[] complaintsArray = gson.fromJson(benChiefComplaintsJson, BenChiefComplaint[].class); | ||
| List<BenChiefComplaint> benChiefComplaints = Arrays.asList(complaintsArray); | ||
|
|
||
| BenChiefComplaint[] complaintsArray = gson.fromJson(benChiefComplaintsJson, BenChiefComplaint[].class); | ||
| List<BenChiefComplaint> benChiefComplaints = Arrays.asList(complaintsArray); | ||
|
|
||
| if (null != benVisitDetailsOBJ) { | ||
| resMap.put("benVisitDetails", benVisitDetailsOBJ); | ||
| } | ||
|
|
||
| if (benChiefComplaints != null && !benChiefComplaints.isEmpty()) { | ||
| resMap.put("BenChiefComplaints", benChiefComplaints); | ||
| } | ||
| if(cdssObj != null) { | ||
| if (benChiefComplaints != null && !benChiefComplaints.isEmpty()) { | ||
| resMap.put("BenChiefComplaints", benChiefComplaints); |
There was a problem hiding this comment.
Handle missing chief-complaint payload before calling Arrays.asList(...).
gson.fromJson(...) can return null when there are no complaints, and Arrays.asList(complaintsArray) will then throw before the later emptiness check runs. That makes the doctor-side visit-details screen fail for beneficiaries with an empty complaint set.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@src/main/java/com/iemr/hwc/service/quickConsultation/QuickConsultationServiceImpl.java`
around lines 517 - 526, gson.fromJson(...) can return null causing
Arrays.asList(complaintsArray) to NPE; modify the flow in
QuickConsultationServiceImpl where you call getBenChiefComplaints and parse with
gson.fromJson (BenChiefComplaint[] complaintsArray) to first check if
complaintsArray is null and, if so, initialize benChiefComplaints to
Collections.emptyList() (or new ArrayList<>()), otherwise call
Arrays.asList(complaintsArray); then continue using benChiefComplaints for the
null/empty check and put into resMap as before (references:
getBenChiefComplaints, gson.fromJson, complaintsArray, Arrays.asList,
benChiefComplaints).
| JSONObject obj = new JSONObject(requestObj); | ||
| System.out.println("obj="+obj); | ||
| HttpEntity<Object> request = RestTemplateUtil.createRequestEntity(requestObj, Authorization); | ||
| System.out.println("test create request="+request); |
There was a problem hiding this comment.
Remove the raw stdout dumps here.
request comes from RestTemplateUtil.createRequestEntity(...), which adds Authorization/JWT/cookie headers. Printing the parsed search object and the raw HttpEntity to stdout risks leaking credentials and beneficiary search data into logs.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/main/java/com/iemr/hwc/service/registrar/RegistrarServiceImpl.java`
around lines 823 - 826, Remove the raw System.out.println debug dumps that print
the parsed JSONObject and the HttpEntity (the lines that reference JSONObject
obj and the request created by RestTemplateUtil.createRequestEntity), since they
may leak Authorization/JWT/cookie headers and sensitive beneficiary data;
instead either delete these print statements entirely or replace them with a
proper logger call at debug level that logs only non-sensitive, sanitized
information (do not log Authorization or the full HttpEntity content).


📋 Description
JIRA ID:
Please provide a summary of the change and the motivation behind it. Include relevant context and details.
✅ Type of Change
ℹ️ 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
Release Notes
New Features
Improvements
Chores