Skip to content

Incentive for Completing treatment of PB (Paucibacillary) leprosy pat…#193

Merged
SauravBizbRolly merged 1 commit intoincentive_test_amrit_demofrom
feature/incentive_leprosy_confirmed_PB
Feb 6, 2026
Merged

Incentive for Completing treatment of PB (Paucibacillary) leprosy pat…#193
SauravBizbRolly merged 1 commit intoincentive_test_amrit_demofrom
feature/incentive_leprosy_confirmed_PB

Conversation

@SauravBizbRolly
Copy link
Collaborator

@SauravBizbRolly SauravBizbRolly commented Feb 5, 2026

…ients

📋 Description

JIRA ID: AMM-2085

Incentive for Completing treatment of PB (Paucibacillary) leprosy patients

✅ Type of Change

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

ℹ️ Additional Information

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

Summary by CodeRabbit

  • New Features

    • Automatic incentive processing when leprosy treatment is confirmed.
    • Endpoints now accept JWT tokens to enable token-aware operations and user attribution.
  • Refactor

    • Save operations run within transactional scope and include improved logging.
  • Other

    • Minor formatting and non-functional cleanups across disease-control services.

@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

Important

Review skipped

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

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

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

  • 🔍 Trigger a full review
📝 Walkthrough

Walkthrough

The 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

Cohort / File(s) Summary
Token Parameter Addition
src/main/java/com/iemr/flw/controller/DiseaseControlController.java, src/main/java/com/iemr/flw/service/DiseaseControlService.java, src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java
Updated method signatures to accept JwtToken header parameter and propagate token through service layers for leprosy operations and chronic disease visits.
New Incentive Logic
src/main/java/com/iemr/flw/service/IncentiveLogicService.java, src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java
Created new service interface and implementation to handle incentive processing for confirmed leprosy cases, including user state determination, group selection, and incentive record persistence with error handling.

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
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 Hopping through tokens and incentives we go,
Leprosy cases now trigger the show,
JWT wisdom guides state and decision,
Incentive rewards with precision and vision,
Spring wires dance in this new code we sow!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main objective of the pull request: adding incentive functionality for PB leprosy treatment completion. It directly corresponds to the primary changes across multiple files implementing this feature.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/incentive_leprosy_confirmed_PB

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@SauravBizbRolly
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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 @Service annotation 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 redundant public modifier.

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);
 }

Comment on lines 145 to 151
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));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n "@RequestHeader.*JwtToken" --type java -C 3

Repository: PSMRI/FLW-API

Length of output: 5527


🏁 Script executed:

rg -n "@RequestHeader.*required\s*=\s*false" --type java -C 2

Repository: 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 2

Repository: PSMRI/FLW-API

Length of output: 1550


🏁 Script executed:

sed -n '166,168p; 266,268p' src/main/java/com/iemr/flw/controller/DiseaseControlController.java

Repository: 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.

Comment on lines 105 to 249
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;
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

@SauravBizbRolly SauravBizbRolly changed the base branch from release-3.8.0 to incentive_test_amrit_demo February 6, 2026 09:54
@SauravBizbRolly SauravBizbRolly changed the base branch from incentive_test_amrit_demo to release-3.8.0 February 6, 2026 09:55
@SauravBizbRolly SauravBizbRolly changed the base branch from release-3.8.0 to incentive_test_amrit_demo February 6, 2026 10:19
@SauravBizbRolly SauravBizbRolly merged commit 9292e4a into incentive_test_amrit_demo Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant