Incentive for Completing treatment of PB (Paucibacillary) leprosy pat…#193
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
📝 WalkthroughWalkthroughThe changes add JWT token authentication support to leprosy disease control operations and introduce a new incentive processing system. The token is extracted from HTTP headers, passed through service layers, and used to determine user state for incentive group selection and incentive record creation. Changes
Sequence Diagram(s)sequenceDiagram
participant Controller as DiseaseControlController
participant Service as DiseaseControlServiceImpl
participant Incentive as IncentiveLogicImpl
participant JWT as JwtUtil
participant UserService as UserService
participant DB as Database
Controller->>Service: saveLeprosy(leprosyDTO, token)
Service->>DB: persist Leprosy record
DB-->>Service: return saved record
alt Confirmed PB Leprosy
Service->>Incentive: incentiveForLeprosyConfirmed(benId, startDate, endDate, token)
Incentive->>JWT: extract user state from token
JWT-->>Incentive: user state
Incentive->>Incentive: determine incentive group based on state
Incentive->>DB: lookup IncentiveActivity
DB-->>Incentive: activity details
Incentive->>DB: check if IncentiveActivityRecord exists
alt Record not exists
Incentive->>DB: create and persist IncentiveActivityRecord
DB-->>Incentive: record saved
end
end
Service-->>Controller: return 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 unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java`:
- Around line 291-298: The string comparison and null-safety need fixing in the
block that handles ScreeningLeprosy after
diseaseLeprosyRepository.save(saveLeprosyData(...)); replace the current chained
calls with null-safe checks: verify screeningLeprosy is non-null, use
Boolean.TRUE.equals(screeningLeprosy.getIsConfirmed()) to avoid unboxing NPE,
and compare type with a null-safe case-insensitive check (e.g., call
screeningLeprosy.getTypeOfLeprosy() into a local var, check it != null, then use
equalsIgnoreCase("PB (Paucibacillary)") or compare to a normalized lower-case
constant) before calling
incentiveLogicService.incentiveForLeprosyConfirmed(...); ensure you also trim
the type string to avoid whitespace mismatches.
In `@src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java`:
- Around line 81-88: The saveIncentive method can NPE when startDate or endDate
is null; add null checks at the top of saveIncentive(IncentiveActivity activity,
Long benId, Date startDate, Date endDate, String token) to validate startDate
and endDate before calling startDate.getTime()/endDate.getTime(). If either is
null, handle gracefully (e.g., log via process logger or use the existing
logger, and return early or throw a clear IllegalArgumentException) so
downstream calls like new Timestamp(startDate.getTime()),
findRecordByActivityIdCreatedDateBenId(...), and jwtUtil.extractUsername(token)
never operate on null dates; keep behavior consistent with how
DiseaseControlServiceImpl.saveLeprosy expects nulls to be handled.
In `@src/main/java/com/iemr/flw/service/IncentiveLogicService.java`:
- Around line 7-8: Remove the Spring stereotype from the interface: delete the
`@Service` annotation on the IncentiveLogicService interface and ensure the
implementation class (IncentiveLogicImpl) is annotated with `@Service` (or
`@Component`) instead; update IncentiveLogicImpl to carry the annotation so Spring
picks up the bean while keeping the interface annotation-free.
src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/main/java/com/iemr/flw/controller/DiseaseControlController.java`:
- Around line 145-151: The saveLeprosy endpoint currently requires a JwtToken
header while its sibling methods (saveMalaria, saveKalaAzar, saveAESJE,
saveFilaria, saveLeprosyFollowUP, saveMobilizationMosquitoNet) do not, causing
an inconsistent API contract; decide the intended behavior and make it
consistent: either mark the JwtToken header as optional by changing
`@RequestHeader`(value = "JwtToken") to `@RequestHeader`(value = "JwtToken",
required = false) in saveLeprosy (and saveVisit if applicable), or add the same
required JwtToken parameter to all other save* controller methods (saveMalaria,
saveKalaAzar, saveAESJE, saveFilaria, saveLeprosyFollowUP,
saveMobilizationMosquitoNet) and pass the token through to diseaseControlService
where needed; update method signatures for each referenced method (e.g.,
saveLeprosy, saveVisit, saveMalaria, etc.) and adjust any service calls that
expect the token accordingly to maintain compile-time consistency.
In `@src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java`:
- Around line 105-160: saveIncentive may throw an NPE when converting
activity.getRate() to Long; update the IncentiveLogicImpl.saveIncentive method
to defensively handle a null rate from IncentiveActivity.getRate() before
calling IncentiveActivityRecord.setAmount — e.g., compute a safeLong =
(activity.getRate() != null ? activity.getRate().longValue() : 0L) or otherwise
default/validate and then call record.setAmount(safeLong); ensure the null-check
happens before saving and logging so the saved record always has a non-null
amount.
In `@src/main/java/com/iemr/flw/service/impl/MaternalHealthServiceImpl.java`:
- Line 10: Remove the unused import of IncentiveService from the
MaternalHealthServiceImpl file; locate the import line referencing
IncentiveService in the class that already uses IncentivesRepo and
IncentiveRecordRepo and delete it (or comment it out if it was intentionally
added for future work), ensuring there are no references to IncentiveService
elsewhere in MaternalHealthServiceImpl before committing.
🧹 Nitpick comments (2)
src/main/java/com/iemr/flw/service/IncentiveLogicService.java (2)
4-4: Remove unused import.The
@Serviceannotation import is not used on this interface. Based on learnings: "In the PSMRI/FLW-API project, the Service annotation should be placed on implementation classes rather than interfaces."Proposed fix
package com.iemr.flw.service; import com.iemr.flw.domain.iemr.IncentiveActivityRecord; -import org.springframework.stereotype.Service; import java.util.Date;
9-9: Remove redundantpublicmodifier.Interface methods are implicitly public. Based on learnings: "In the PSMRI/FLW-API project, interface methods should not have the redundant 'public' modifier as they are implicitly public."
Proposed fix
public interface IncentiveLogicService { - public IncentiveActivityRecord incentiveForLeprosyConfirmed(Long benId, Date treatmentStartDate, Date treatmentEndDate, String token); + IncentiveActivityRecord incentiveForLeprosyConfirmed(Long benId, Date treatmentStartDate, Date treatmentEndDate, String token); }
| public ResponseEntity<Map<String, Object>> saveLeprosy(@RequestBody LeprosyDTO leprosyDTO,@RequestHeader(value = "JwtToken") String token) { | ||
| Map<String, Object> response = new HashMap<>(); | ||
| try { | ||
| if(leprosyDTO!=null){ | ||
| response.put("status", "Success"); | ||
| response.put("statusCode", 200); | ||
| response.put("data", diseaseControlService.saveLeprosy(leprosyDTO)); | ||
| response.put("data", diseaseControlService.saveLeprosy(leprosyDTO,token)); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
rg -n "@RequestHeader.*JwtToken" --type java -C 3Repository: PSMRI/FLW-API
Length of output: 5527
🏁 Script executed:
rg -n "@RequestHeader.*required\s*=\s*false" --type java -C 2Repository: PSMRI/FLW-API
Length of output: 39
🏁 Script executed:
rg -n "public.*saveLeprosy|public.*saveVisit|public.*save" src/main/java/com/iemr/flw/controller/DiseaseControlController.java -A 2Repository: PSMRI/FLW-API
Length of output: 1550
🏁 Script executed:
sed -n '166,168p; 266,268p' src/main/java/com/iemr/flw/controller/DiseaseControlController.javaRepository: PSMRI/FLW-API
Length of output: 435
Inconsistent authentication requirement: JwtToken header required only for this endpoint.
Within DiseaseControlController, only saveLeprosy and saveVisit require the @RequestHeader(value = "JwtToken") parameter. Other save methods (saveMalaria, saveKalaAzar, saveAESJE, saveFilaria, saveLeprosyFollowUP, saveMobilizationMosquitoNet) do not require this header, making this a breaking change relative to sibling endpoints.
Clarify the intent: Is the JwtToken parameter required for this endpoint, or should it be optional with required = false? If required, ensure consistency across all save endpoints in this controller.
🤖 Prompt for AI Agents
In `@src/main/java/com/iemr/flw/controller/DiseaseControlController.java` around
lines 145 - 151, The saveLeprosy endpoint currently requires a JwtToken header
while its sibling methods (saveMalaria, saveKalaAzar, saveAESJE, saveFilaria,
saveLeprosyFollowUP, saveMobilizationMosquitoNet) do not, causing an
inconsistent API contract; decide the intended behavior and make it consistent:
either mark the JwtToken header as optional by changing `@RequestHeader`(value =
"JwtToken") to `@RequestHeader`(value = "JwtToken", required = false) in
saveLeprosy (and saveVisit if applicable), or add the same required JwtToken
parameter to all other save* controller methods (saveMalaria, saveKalaAzar,
saveAESJE, saveFilaria, saveLeprosyFollowUP, saveMobilizationMosquitoNet) and
pass the token through to diseaseControlService where needed; update method
signatures for each referenced method (e.g., saveLeprosy, saveVisit,
saveMalaria, etc.) and adjust any service calls that expect the token
accordingly to maintain compile-time consistency.
| private IncentiveActivityRecord saveIncentive( | ||
| IncentiveActivity activity, | ||
| Long benId, | ||
| Date startDate, | ||
| Date endDate, | ||
| String token) { | ||
|
|
||
| try { | ||
|
|
||
| if (activity == null || benId == null || startDate == null || endDate == null) { | ||
| logger.warn("Invalid input for saving incentive"); | ||
| return null; | ||
| } | ||
|
|
||
| Timestamp startTimestamp = new Timestamp(startDate.getTime()); | ||
| Timestamp endTimestamp = new Timestamp(endDate.getTime()); | ||
|
|
||
| Integer userId = jwtUtil.extractUserId(token); | ||
| String username = jwtUtil.extractUsername(token); | ||
|
|
||
| // 🔍 duplicate check | ||
| IncentiveActivityRecord existing = incentiveRecordRepo | ||
| .findRecordByActivityIdCreatedDateBenId( | ||
| activity.getId(), startTimestamp, benId); | ||
|
|
||
| if (existing != null) { | ||
| logger.info("Incentive already exists for benId: {}, activityId: {}", | ||
| benId, activity.getId()); | ||
| return existing; | ||
| } | ||
|
|
||
| // 🆕 create record | ||
| IncentiveActivityRecord record = new IncentiveActivityRecord(); | ||
| record.setActivityId(activity.getId()); | ||
| record.setCreatedDate(startTimestamp); | ||
| record.setUpdatedDate(startTimestamp); | ||
| record.setStartDate(startTimestamp); | ||
| record.setEndDate(endTimestamp); | ||
| record.setCreatedBy(username); | ||
| record.setUpdatedBy(username); | ||
| record.setBenId(benId); | ||
| record.setAshaId(userId); | ||
| record.setName(activity.getName()); | ||
| record.setAmount(Long.valueOf(activity.getRate())); | ||
|
|
||
| record = incentiveRecordRepo.save(record); | ||
|
|
||
| logger.info("Leprosy Incentive saved successfully for benId: {}", benId); | ||
|
|
||
| return record; | ||
|
|
||
| } catch (Exception e) { | ||
| logger.error("Save Leprosy Incentive Exception: ", e); | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
Potential NPE if activity.getRate() returns null.
Line 148 calls Long.valueOf(activity.getRate()). If getRate() returns a null Integer, this will throw a NullPointerException. Consider adding a null check or defaulting to 0.
Proposed defensive fix
record.setAshaId(userId);
record.setName(activity.getName());
- record.setAmount(Long.valueOf(activity.getRate()));
+ record.setAmount(activity.getRate() != null ? Long.valueOf(activity.getRate()) : 0L);🤖 Prompt for AI Agents
In `@src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java` around lines
105 - 160, saveIncentive may throw an NPE when converting activity.getRate() to
Long; update the IncentiveLogicImpl.saveIncentive method to defensively handle a
null rate from IncentiveActivity.getRate() before calling
IncentiveActivityRecord.setAmount — e.g., compute a safeLong =
(activity.getRate() != null ? activity.getRate().longValue() : 0L) or otherwise
default/validate and then call record.setAmount(safeLong); ensure the null-check
happens before saving and logging so the saved record always has a non-null
amount.
| import com.iemr.flw.masterEnum.GroupName; | ||
| import com.iemr.flw.repo.identity.BeneficiaryRepo; | ||
| import com.iemr.flw.repo.iemr.*; | ||
| import com.iemr.flw.service.IncentiveService; |
There was a problem hiding this comment.
Unused import: IncentiveService.
This import is added but not used anywhere in MaternalHealthServiceImpl. The file already uses IncentivesRepo and IncentiveRecordRepo for incentive-related operations. If this was intended for future use, consider removing it to keep the codebase clean.
Proposed fix
-import com.iemr.flw.service.IncentiveService;🤖 Prompt for AI Agents
In `@src/main/java/com/iemr/flw/service/impl/MaternalHealthServiceImpl.java` at
line 10, Remove the unused import of IncentiveService from the
MaternalHealthServiceImpl file; locate the import line referencing
IncentiveService in the class that already uses IncentivesRepo and
IncentiveRecordRepo and delete it (or comment it out if it was intentionally
added for future work), ensuring there are no references to IncentiveService
elsewhere in MaternalHealthServiceImpl before committing.
…ients
📋 Description
JIRA ID: AMM-2085
Incentive for Completing treatment of PB (Paucibacillary) leprosy patients
✅ 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
New Features
Refactor
Other