Skip to content

Incentive changes 3.8.0#209

Open
SauravBizbRolly wants to merge 76 commits intorelease-3.8.0from
incentive_changes_3.8.0
Open

Incentive changes 3.8.0#209
SauravBizbRolly wants to merge 76 commits intorelease-3.8.0from
incentive_changes_3.8.0

Conversation

@SauravBizbRolly
Copy link
Collaborator

@SauravBizbRolly SauravBizbRolly commented Feb 27, 2026

📋 Description

JIRA ID:

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


✅ 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

    • Added support for file uploads and image attachments across multiple health activities (delivery outcomes, death reports, maternal health, immunization).
    • Introduced enhanced incentive tracking system with support for new activity types including leprosy screening, VHND meetings, and cluster meetings.
    • Added multipart/form-data support to incentive update endpoint.
  • Chores

    • Updated project version from 3.7.0 to 3.8.0.
    • Refactored internal code structure and removed unused code.

SauravBizbRolly and others added 30 commits February 5, 2026 11:45
…d_PB

Incentive for Completing treatment of PB (Paucibacillary) leprosy pat…
…incentive_changes_3.8.0

# Conflicts:
#	src/main/java/com/iemr/flw/service/MaaMeetingService.java
#	src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java
@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Important

Review skipped

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

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

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request updates the codebase to version 3.8.0, renames the M_User domain entity to User, refactors repository queries to remove date-range filtering, expands DTOs with new fields, and significantly enhances the incentive processing system with new service implementations and multi-branched update logic.

Changes

Cohort / File(s) Summary
Version Update
pom.xml
Maven project version bumped from 3.7.0 to 3.8.0.
Domain Entity Refactoring: M_User → User
src/main/java/com/iemr/flw/domain/iemr/User.java
Class renamed from M_User to User with constructor updates; table mapping changed from "m_User" to "m_user"; redundant imports removed.
Domain Entity Schema Changes
src/main/java/com/iemr/flw/domain/iemr/IncentivePendingActivity.java, src/main/java/com/iemr/flw/domain/iemr/ScreeningKalaAzar.java, src/main/java/com/iemr/flw/domain/iemr/DeliveryOutcome.java
IncentivePendingActivity: replaced moduleName field with mincentiveId; ScreeningKalaAzar: updated column names to snake_case (userID→user_id, diseaseTypeID→disease_type_id); DeliveryOutcome: removed @JsonFormat annotations.
DTO Enhancements
src/main/java/com/iemr/flw/dto/iemr/CdrDTO.java, src/main/java/com/iemr/flw/dto/iemr/DeliveryOutcomeDTO.java, src/main/java/com/iemr/flw/dto/iemr/MdsrDTO.java, src/main/java/com/iemr/flw/dto/iemr/PendingActivityDTO.java, src/main/java/com/iemr/flw/dto/iemr/TBScreeningDTO.java
CdrDTO: added cdrImage field; DeliveryOutcomeDTO: updated date format patterns and added annotations to multiple timestamp fields; MdsrDTO: added three file fields (mdsr1File, mdsr2File, mdsrDeathCertFile); PendingActivityDTO: renamed Images to images, added activityName; TBScreeningDTO: removed explicit getter/setters in favor of Lombok generation.
Controller Updates
src/main/java/com/iemr/flw/controller/AshaProfileController.java, src/main/java/com/iemr/flw/controller/DeathReportsController.java, src/main/java/com/iemr/flw/controller/IncentiveController.java, src/main/java/com/iemr/flw/controller/MaternalHealthController.java
AshaProfileController: removed unused imports; DeathReportsController: minor Gson formatting; IncentiveController: updated updateIncentive to consume multipart/form-data and use @ModelAttribute, adjusted error codes from 5000 to 500; MaternalHealthController: removed class-level Authorization header constraint, improved delivery outcome result checking.
Repository Layer Refactoring
src/main/java/com/iemr/flw/repo/identity/BeneficiaryRepo.java, src/main/java/com/iemr/flw/repo/iemr/CdrRepo.java, src/main/java/com/iemr/flw/repo/iemr/DeliveryOutcomeRepo.java, src/main/java/com/iemr/flw/repo/iemr/EmployeeMasterRepo.java, src/main/java/com/iemr/flw/repo/iemr/IncentivePendingActivityRepository.java, src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java, src/main/java/com/iemr/flw/repo/iemr/MdsrRepo.java, src/main/java/com/iemr/flw/repo/iemr/PNCVisitRepo.java, src/main/java/com/iemr/flw/repo/iemr/TBScreeningRepo.java
Replaced custom JPQL queries with Spring Data derived queries; removed date-range parameters from multiple methods (getBenDataWithinDates, getAllMdsrByAshaId, getPNCForPW, etc.); updated EmployeeMasterRepo to use User instead of M_User; replaced IncentivePendingActivityRepository lookup from userId+moduleName to mincentiveId; added new finder methods for CreatedBy filtering.
Service Interface Updates
src/main/java/com/iemr/flw/service/EmployeeMasterInter.java, src/main/java/com/iemr/flw/service/IncentiveLogicService.java, src/main/java/com/iemr/flw/service/UwinSessionService.java
EmployeeMasterInter: updated return types from M_User to User; IncentiveLogicService: new interface defining six incentive methods (leprosy variants, VHND, cluster, VHSNC); UwinSessionService: added updateSession method.
Core Service Implementations
src/main/java/com/iemr/flw/service/impl/AshaProfileImpl.java, src/main/java/com/iemr/flw/service/impl/EmployeeMasterImpl.java, src/main/java/com/iemr/flw/service/impl/NotificationSchedulerService.java, src/main/java/com/iemr/flw/service/impl/SmsSchedulerService.java
Updated type usage from M_User to User; adjusted repository method calls (findByUserID→findUserByUserID); minor import cleanup and variable type changes.
Incentive Logic Implementation
src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java, src/main/java/com/iemr/flw/service/impl/UpdateIncentivePendindDocService.java
IncentiveLogicImpl: new service implementing six incentive methods with state-driven activity mapping, duplicate detection, and logging; UpdateIncentivePendindDocService: new service for marking incentive records eligible and creating pending activity records.
Service Layer Enhancements
src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java, src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java, src/main/java/com/iemr/flw/service/impl/DeathReportsServiceImpl.java, src/main/java/com/iemr/flw/service/impl/DeliveryOutcomeServiceImpl.java, src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java, src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java, src/main/java/com/iemr/flw/service/impl/MaaMeetingService.java, src/main/java/com/iemr/flw/service/impl/MaternalHealthServiceImpl.java, src/main/java/com/iemr/flw/service/impl/SammelanServiceImpl.java, src/main/java/com/iemr/flw/service/impl/TBScreeningServiceImpl.java, src/main/java/com/iemr/flw/service/impl/UwinSessionServiceImpl.java, src/main/java/com/iemr/flw/service/impl/VillageLevelFormServiceImpl.java
Significant incentive processing enhancements: added file upload handling with base64 conversion, introduced dependency on UpdateIncentivePendindDocService and IncentiveLogicService, refactored updateIncentive to multi-branch enum-driven logic, added methods for processing images and managing pending activities; removed date-range filtering from retrieval methods; improved null-safety and error handling with logging; updated repository calls to match new signatures.
Utility and Configuration
src/main/java/com/iemr/flw/utils/JwtAuthenticationUtil.java, src/main/java/com/iemr/flw/utils/redis/RedisConfig.java
JwtAuthenticationUtil: updated all M_User references to User, changed Redis caching and DB fetch to use User type, updated repository method call to findUserByUserID; RedisConfig: updated Jackson2JsonRedisSerializer type parameter from M_User to User.
Enums
src/main/java/com/iemr/flw/masterEnum/GroupName.java, src/main/java/com/iemr/flw/masterEnum/IncentiveName.java
GroupName: formatting only; IncentiveName: new public enum with multiple constants organized by category (Child Health, Immunization, Maternal Health, etc.), each mapped to a GroupName via constructor and getter.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 From M_User to User, the refactoring hops,
New incentive logic blooms in every shop,
Queries simplified, schemas aligned with care,
File uploads and DTOs dancing in the air,
Version 3.8 hops forward with pride!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The pull request title "Incentive changes 3.8.0" is vague and generic. It refers to a broad category of changes (incentives) and a version number, but does not clearly convey the primary or most important change from the substantial changeset. Consider a more descriptive title that highlights the main structural or behavioral change, such as "Refactor incentive handling with new eligibility tracking and file upload integration" or "Update incentive workflow to support pending activity records and multipart form data".
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch incentive_changes_3.8.0

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 27, 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: 20

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 (2)
src/main/java/com/iemr/flw/service/impl/SammelanServiceImpl.java (1)

39-39: ⚠️ Potential issue | 🟠 Major

Thread safety issue: instance field record shared across requests.

The SammelanRecord record instance field can be overwritten by concurrent requests in a Spring singleton service, leading to race conditions. Use a local variable instead.

🔧 Proposed fix
-    private SammelanRecord record;

Then in submitSammelan, the variable is already declared locally on line 65, so just remove the instance field declaration.

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

In `@src/main/java/com/iemr/flw/service/impl/SammelanServiceImpl.java` at line 39,
The instance field `record` on SammelanServiceImpl introduces a thread-safety
bug because the singleton service can be shared across requests; remove the
class-level declaration `private SammelanRecord record;` and rely on the
existing local `record` variable already declared inside the `submitSammelan`
method so each request uses its own stack-local SammelanRecord instead of a
shared field.
src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java (1)

36-36: ⚠️ Potential issue | 🟡 Minor

Fix incorrect logger class reference.

The logger is initialized with ChildCareServiceImpl.class instead of the current class. This will cause misleading log output.

🐛 Proposed fix
-    private final Logger logger = LoggerFactory.getLogger(ChildCareServiceImpl.class);
+    private final Logger logger = LoggerFactory.getLogger(IncentiveServiceImpl.class);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java` at line
36, The logger in IncentiveServiceImpl is created with the wrong class
reference; update the Logger initialization (variable logger using
LoggerFactory.getLogger(...)) to use IncentiveServiceImpl.class instead of
ChildCareServiceImpl.class so log entries correctly identify the current class
(adjust the declaration in IncentiveServiceImpl to call
LoggerFactory.getLogger(IncentiveServiceImpl.class)).
🟡 Minor comments (3)
src/main/java/com/iemr/flw/service/impl/DeliveryOutcomeServiceImpl.java-111-112 (1)

111-112: ⚠️ Potential issue | 🟡 Minor

Missing null check: user may be null if userId not found.

If getUserNamedByUserId returns null for an unknown userId, the query will proceed with a null parameter, potentially returning unexpected results or empty data without proper feedback.

🛡️ Proposed null check
             String user = userRepo.getUserNamedByUserId(dto.getAshaId());
+            if (user == null) {
+                logger.warn("No user found for ashaId: {}", dto.getAshaId());
+                return List.of();
+            }
             List<DeliveryOutcome> deliveryOutcomeList = deliveryOutcomeRepo.getDeliveryOutcomeByAshaId(user,dto.getFromDate(),dto.getToDate());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/DeliveryOutcomeServiceImpl.java`
around lines 111 - 112, In DeliveryOutcomeServiceImpl,
userRepo.getUserNamedByUserId(dto.getAshaId()) can return null; add a null-check
after calling userRepo.getUserNamedByUserId (referencing getUserNamedByUserId
and dto.getAshaId) and handle it before calling
deliveryOutcomeRepo.getDeliveryOutcomeByAshaId(user,...). If user is null,
either log and throw a clear exception (e.g., IllegalArgumentException or a
custom NotFound exception) or return an empty List<DeliveryOutcome> so the
downstream query is not invoked with a null parameter; ensure the chosen
behavior is consistent with the service's error handling and update the method
return accordingly.
src/main/java/com/iemr/flw/dto/iemr/DeliveryOutcomeDTO.java-13-14 (1)

13-14: ⚠️ Potential issue | 🟡 Minor

Date format inconsistent with project standard.

The pattern "MMM d yyyy h:mm:ss a" differs from the project's standardized format "MMM dd, yyyy h:mm:ss a":

  • Single d vs dd (missing leading zero for single-digit days)
  • Missing comma after the year

This inconsistency applies to all four @JsonFormat annotations in this file (lines 13, 26, 31, 34).

🔧 Proposed fix
-    `@JsonFormat`(pattern = "MMM d yyyy h:mm:ss a")
+    `@JsonFormat`(pattern = "MMM dd, yyyy h:mm:ss a")
     private Timestamp dateOfDelivery;

Apply the same fix to dateOfDischarge, createdDate, and updatedDate.

Based on learnings: "The standardized date format across the FLW-API codebase is 'MMM dd, yyyy h:mm:ss a'".

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

In `@src/main/java/com/iemr/flw/dto/iemr/DeliveryOutcomeDTO.java` around lines 13
- 14, Update the `@JsonFormat` annotations in DeliveryOutcomeDTO to use the
project-standard pattern "MMM dd, yyyy h:mm:ss a" so dates include leading
zeroes and the comma; specifically change the pattern on the fields
dateOfDelivery, dateOfDischarge, createdDate, and updatedDate in class
DeliveryOutcomeDTO to "MMM dd, yyyy h:mm:ss a".
src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java-230-256 (1)

230-256: ⚠️ Potential issue | 🟡 Minor

Inconsistent return values make error handling difficult.

The method returns different values for different failure scenarios:

  • null for missing activity/pending activity (Lines 231, 243, 250, 255)
  • "Invalid request" / "Invalid incentive name" for input validation (Lines 209, 217)
  • e.getMessage() for exceptions (Line 384)
  • "Incentive update successfully" for success

Consider using a consistent response pattern or throwing exceptions for error cases to help callers distinguish between different failure modes.

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

In `@src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java` around
lines 230 - 256, The method in IncentiveServiceImpl uses inconsistent return
values (null, strings like "Invalid request"/"Invalid incentive name", exception
messages, and success text) which complicates error handling; replace the
multiple null/string returns in the block that checks incentiveActivity,
optionalPendingActivity
(incentivePendingActivityRepository.findByMincentiveIdAndActivityId),
existingActivity, and pendingActivityDTO.getImages() with a consistent error
handling strategy—either throw well-typed exceptions (e.g.,
InvalidRequestException / NotFoundException) at each failure point or return a
standardized response DTO (e.g., OperationResult with status, message, and
optional data); update the method's signature accordingly and ensure callers of
this method handle the new exception types or the standardized response instead
of relying on null/string values.
🧹 Nitpick comments (23)
src/main/java/com/iemr/flw/repo/iemr/PNCVisitRepo.java (1)

9-9: Remove unused import.

The java.sql.Timestamp import is no longer used after removing the date parameters from getPNCForPW.

🧹 Proposed fix
-import java.sql.Timestamp;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/repo/iemr/PNCVisitRepo.java` at line 9, Remove the
unused import of java.sql.Timestamp from the PNCVisitRepo file: open the class
PNCVisitRepo and delete the import line "import java.sql.Timestamp;" (this
import is no longer needed after removing date parameters from getPNCForPW),
then recompile to ensure no other references to Timestamp remain.
src/main/java/com/iemr/flw/service/impl/NotificationSchedulerService.java (2)

30-36: Consider removing stale commented-out code.

This commented block references the old M_User type which has been renamed. If this code is no longer needed, consider removing it entirely to improve maintainability. If it may be needed later, update it to use User to avoid confusion.

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

In `@src/main/java/com/iemr/flw/service/impl/NotificationSchedulerService.java`
around lines 30 - 36, The commented-out block in NotificationSchedulerService
references the outdated M_User type and legacy request handling (lines with
M_User, cookieUtil, employeeMasterInter,
maternalHealthService.sendAncDueTomorrowNotifications); remove this stale
commented code entirely if it's no longer needed, or if you intend to keep it,
update references to the current User type and modern request retrieval so the
comment reflects valid, compileable usage (e.g., replace M_User with User and
ensure cookieUtil / employeeMasterInter usage matches current APIs); commit the
cleaned-up NotificationSchedulerService to avoid confusion.

58-61: Variable naming could be more consistent; however, the code is functionally correct.

The variable m_user follows the old naming convention from the previous M_User type. Since the type is now User, renaming to user would improve consistency throughout the codebase. The getUserID() method is properly generated by Lombok's @Data annotation on the User class and works correctly.

♻️ Optional naming cleanup
-        for(User m_user: employeeMasterInter.getAllUsers()){
-            childCareService.getTomorrowImmunizationReminders(m_user.getUserID());
+        for(User user : employeeMasterInter.getAllUsers()){
+            childCareService.getTomorrowImmunizationReminders(user.getUserID());

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

In `@src/main/java/com/iemr/flw/service/impl/NotificationSchedulerService.java`
around lines 58 - 61, The loop variable uses an outdated name `m_user` even
though the type is now `User`; rename `m_user` to `user` in the loop that
iterates `employeeMasterInter.getAllUsers()` and update its usages (e.g., the
call to `childCareService.getTomorrowImmunizationReminders(m_user.getUserID())`)
to use `user.getUserID()` so naming is consistent with the `User` type and code
style.
src/main/java/com/iemr/flw/domain/iemr/ScreeningKalaAzar.java (1)

106-107: Inconsistent column naming convention.

The column beneficiary_statusId uses camelCase while the rest of the file (including the newly updated columns) follows snake_case convention. Consider renaming this to beneficiary_status_id for consistency across the entity.

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

In `@src/main/java/com/iemr/flw/domain/iemr/ScreeningKalaAzar.java` around lines
106 - 107, The `@Column` annotation on the ScreeningKalaAzar entity field
beneficiaryStatusId uses inconsistent camelCase "beneficiary_statusId"; update
the `@Column`(name = "...") value to the snake_case "beneficiary_status_id" to
match the file's convention and ensure ORM mapping consistency for the
ScreeningKalaAzar class and any queries or DTOs that reference
beneficiaryStatusId.
src/main/java/com/iemr/flw/dto/iemr/CdrDTO.java (1)

3-3: Unused import: jakarta.persistence.Column is not used in this DTO.

This import appears to be unnecessary since no @Column annotations are present in this class.

🧹 Proposed cleanup
 package com.iemr.flw.dto.iemr;
 
-import jakarta.persistence.Column;
 import lombok.Data;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/dto/iemr/CdrDTO.java` at line 3, The import
jakarta.persistence.Column in CdrDTO is unused and should be removed; open the
CdrDTO class and delete the unused import statement (the one importing
jakarta.persistence.Column) so the file no longer contains an unnecessary import
and compiles/linters no longer flag it.
src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java (2)

27-38: Consider renaming for clarity: this method uses date range, not exact date match.

The method name findRecordByActivityIdCreatedDateBenId is overloaded three times with different semantics. This version uses BETWEEN for a date range, while others use exact match. Consider a distinct name like findRecordByActivityIdCreatedDateRangeBenId to avoid confusion.

♻️ Proposed rename for clarity
-    IncentiveActivityRecord findRecordByActivityIdCreatedDateBenId(
+    IncentiveActivityRecord findRecordByActivityIdCreatedDateRangeBenId(
             `@Param`("id") Long id,
             `@Param`("startDate") Timestamp startDate,
             `@Param`("endDate") Timestamp endDate,
             `@Param`("benId") Long benId,
             `@Param`("ashaId") Integer ashaId
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java` around lines
27 - 38, The repository method name findRecordByActivityIdCreatedDateBenId is
ambiguous because it uses a BETWEEN date range; rename it to
findRecordByActivityIdCreatedDateRangeBenId (or similar) in the
IncentiveRecordRepo interface, update the method declaration signature there and
any callers/tests that reference the old name, and run a compile/test to ensure
all references are updated and Spring Data still picks up the `@Query` on the
renamed method.

20-21: Redundant method: findById(Long id) is already provided by JpaRepository.

JpaRepository<IncentiveActivityRecord, Long> already inherits findById(Long id) from CrudRepository. This explicit declaration is unnecessary unless you intend to override behavior.

🧹 Proposed cleanup
-    Optional<IncentiveActivityRecord> findById(Long id);
-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java` around lines
20 - 21, The explicit declaration of findById(Long id) in the
IncentiveRecordRepo interface is redundant because
JpaRepository<IncentiveActivityRecord, Long> already provides it; remove the
findById(Long id) method declaration from the IncentiveRecordRepo interface (or,
if you intended custom behavior, implement a custom repository method instead
and do not shadow the inherited findById). Ensure the interface relies on the
inherited JpaRepository methods and delete the Optional<IncentiveActivityRecord>
findById(Long id); line to clean up the repo.
src/main/java/com/iemr/flw/service/impl/DeliveryOutcomeServiceImpl.java (1)

118-118: Use parameterized logging instead of string concatenation.

String concatenation in logger calls is evaluated even when the log level is disabled, causing unnecessary overhead.

♻️ Proposed fix
-            logger.error("DeliveryOutcome Exception:"+e.getMessage());
+            logger.error("DeliveryOutcome Exception: {}", e.getMessage(), e);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/DeliveryOutcomeServiceImpl.java` at
line 118, The logger call in DeliveryOutcomeServiceImpl currently concatenates
the exception message (logger.error("DeliveryOutcome
Exception:"+e.getMessage())), which forces string allocation even when logging
is disabled; change it to use parameterized logging by supplying a message
template and passing e (and/or e.getMessage()) as parameters so the logging
framework can avoid building the string when the level is disabled and still
capture the Throwable for the stack trace; update the invocation that uses the
logger variable in the DeliveryOutcomeServiceImpl class where the local
exception variable e is available.
src/main/java/com/iemr/flw/service/impl/UpdateIncentivePendindDocService.java (3)

42-44: Redundant null check on newly instantiated object.

The incentivePendingActivity object is instantiated on line 37 and can never be null at line 42. This check is dead code.

♻️ Proposed fix
     public void updatePendingActivity(Integer userId, Long recordId, Long activityId, Long mIncentiveId) {
         IncentivePendingActivity incentivePendingActivity = new IncentivePendingActivity();
         incentivePendingActivity.setActivityId(activityId);
         incentivePendingActivity.setRecordId(recordId);
         incentivePendingActivity.setUserId(userId);
         incentivePendingActivity.setMincentiveId(mIncentiveId);
-        if (incentivePendingActivity != null) {
-            incentivePendingActivityRepository.save(incentivePendingActivity);
-        }
-
+        incentivePendingActivityRepository.save(incentivePendingActivity);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/iemr/flw/service/impl/UpdateIncentivePendindDocService.java`
around lines 42 - 44, The null check around incentivePendingActivity is
redundant because the object is instantiated earlier in the method; remove the
if (incentivePendingActivity != null) { ... } wrapper and directly call
incentivePendingActivityRepository.save(incentivePendingActivity) (in
UpdateIncentivePendindDocService) to simplify the code and eliminate dead code.

12-12: Typo in class name: "Pendind" should be "Pending".

The class name UpdateIncentivePendindDocService contains a typo. Consider renaming to UpdateIncentivePendingDocService for clarity and maintainability.

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

In
`@src/main/java/com/iemr/flw/service/impl/UpdateIncentivePendindDocService.java`
at line 12, Rename the class UpdateIncentivePendindDocService to
UpdateIncentivePendingDocService everywhere: update the class declaration, the
file name, any constructors, logger/static references, Spring component/bean
names or annotations referencing the old class, and all imports/usages
(including tests) to the new identifier so compilation and dependency injection
continue to work.

13-17: Unused autowired dependencies.

incentivesRepo and userRepo are autowired but never used in this class. Remove them to reduce unnecessary coupling and improve clarity.

♻️ Proposed fix
 `@Service`
 public class UpdateIncentivePendindDocService {
-    `@Autowired`
-    private IncentivesRepo incentivesRepo;
-
-    `@Autowired`
-    private UserServiceRoleRepo userRepo;
-
     `@Autowired`
     private IncentiveRecordRepo recordRepo;

     `@Autowired`
     private IncentivePendingActivityRepository incentivePendingActivityRepository;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/com/iemr/flw/service/impl/UpdateIncentivePendindDocService.java`
around lines 13 - 17, Remove the unused `@Autowired` fields in
UpdateIncentivePendindDocService: delete the private IncentivesRepo
incentivesRepo and private UserServiceRoleRepo userRepo declarations (and their
`@Autowired` annotations) since they are never referenced; after removing them,
also remove any now-unused import statements for IncentivesRepo and
UserServiceRoleRepo to keep the class clean.
src/main/java/com/iemr/flw/domain/iemr/User.java (1)

138-146: Remove stale TODO comments in constructors.

The TODO comments "Auto-generated constructor stub" are IDE-generated placeholders that should be removed for cleaner code.

♻️ Proposed fix
     public User() {
-        // TODO Auto-generated constructor stub
     }

     public User(Integer userID, String userName) {
-        // TODO Auto-generated constructor stub
         this.userID = userID;
         this.userName = userName;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/domain/iemr/User.java` around lines 138 - 146,
Remove the stale "TODO Auto-generated constructor stub" comments from the two
User constructors; specifically edit the no-arg constructor public User() and
the two-arg constructor public User(Integer userID, String userName) to delete
those placeholder comments so the constructors contain only their intended
initialization (or remain empty) without IDE TODO clutter.
src/main/java/com/iemr/flw/controller/IncentiveController.java (1)

119-124: Inconsistent error codes within the same controller.

Error codes changed from 5000 to 500 for this endpoint, but other endpoints in this controller (lines 43-48, 70-75, 96-101) still use 5000. Consider aligning error codes for consistency.

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

In `@src/main/java/com/iemr/flw/controller/IncentiveController.java` around lines
119 - 124, In IncentiveController, several response.setError calls in the shown
method use HTTP code 500 while other endpoints in the same controller use 5000;
update the response.setError invocations in this method (the branches that
currently call response.setError(500, "...") and the catch block
response.setError(500, "...")) to use 5000 so the error codes match the rest of
the controller; keep the existing logger.error(...) unchanged except ensure any
message text remains the same while the response.setError numeric argument is
changed to 5000.
src/main/java/com/iemr/flw/service/impl/SammelanServiceImpl.java (1)

151-152: Logger does not capture exception stack trace.

Using logger.info("...: ", e) with a trailing comma but no placeholder {} will not log the exception properly. Use logger.error with proper formatting for exceptions.

♻️ Proposed fix
         } catch (Exception e) {
-            logger.info("SammelanRecord save Record: ", e);
+            logger.error("SammelanRecord save Record: {}", e.getMessage(), e);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/SammelanServiceImpl.java` around
lines 151 - 152, In SammelanServiceImpl's catch block where you currently call
logger.info("SammelanRecord save Record: ", e), replace that call to use
logger.error and pass the exception as the throwable parameter so the full stack
trace is emitted (e.g., change the logging invocation in the catch block that
handles the save flow to use logger.error("SammelanRecord save Record", e)).
Ensure you update the logging level from info to error and pass the exception
object as the second argument so the logger prints the stack trace.
src/main/java/com/iemr/flw/dto/iemr/TBScreeningDTO.java (1)

40-40: Consider correcting sympotomatic before this DTO contract solidifies.

If clients can be migrated, prefer symptomatic; otherwise keep backward compatibility with an explicit JSON alias/property mapping.

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

In `@src/main/java/com/iemr/flw/dto/iemr/TBScreeningDTO.java` at line 40, The DTO
field sympotomatic in TBScreeningDTO is misspelled; either rename it to
symptomatic (update the private field, its getter/setter, and all usages) if
clients can migrate, or preserve backward compatibility by keeping the corrected
field name but annotating it with Jackson JSON mapping (e.g., `@JsonProperty` or
`@JsonAlias` referencing "sympotomatic") so incoming/outgoing JSON still supports
the old name; update tests and any serialization/deserialization sites that
reference sympotomatic accordingly.
src/main/java/com/iemr/flw/service/UwinSessionService.java (1)

11-11: Keep service contract DTO-oriented for boundary consistency.

Returning UwinSession here leaks persistence shape while the rest of the interface is DTO-based. Prefer an update response DTO.

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

In `@src/main/java/com/iemr/flw/service/UwinSessionService.java` at line 11, The
service method updateSession in UwinSessionService currently returns the
persistence entity UwinSession which leaks internal model; change its signature
to return a DTO (e.g., UwinSessionResponseDTO or UpdateUwinSessionResponseDTO)
and update all implementations/tests to map the persisted UwinSession to that
DTO before returning; specifically modify the interface method declaration
updateSession(UwinSessionRequestDTO req, Long recordId, Long activityId) to
return the chosen DTO type, update import and mapper usage in classes
implementing UwinSessionService, and adjust callers to consume the DTO instead
of the entity.
src/main/java/com/iemr/flw/service/IncentiveLogicService.java (1)

4-4: Remove unused @Service import.

This is an interface, so the @Service annotation import is unused. The annotation belongs on the implementation class (IncentiveLogicImpl), not the interface.

🔧 Proposed fix
 package com.iemr.flw.service;
 
 import com.iemr.flw.domain.iemr.IncentiveActivityRecord;
-import org.springframework.stereotype.Service;
 
 import java.util.Date;

Based on learnings: "In the PSMRI/FLW-API project, the Service annotation should be placed on implementation classes rather than interfaces."

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

In `@src/main/java/com/iemr/flw/service/IncentiveLogicService.java` at line 4,
Remove the unused import of org.springframework.stereotype.Service from the
IncentiveLogicService interface; the `@Service` annotation belongs on the
implementation class, so ensure IncentiveLogicImpl is annotated with `@Service`
(or already has it) and then delete the import line from IncentiveLogicService
to avoid unused imports and clarify that the interface has no Spring stereotype.
src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java (2)

63-70: Consider autowiring interfaces instead of implementations.

Autowiring concrete implementations (ChildCareServiceImpl, DeathReportsServiceImpl) tightly couples this class. If corresponding interfaces exist (e.g., ChildCareService, DeathReportsService), prefer injecting those for better testability and flexibility.

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

In `@src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java` around
lines 63 - 70, In IncentiveServiceImpl the fields childCareService and
deathReportsService are autowired to concrete classes (ChildCareServiceImpl,
DeathReportsServiceImpl); change those field types to their corresponding
interfaces (e.g., ChildCareService and DeathReportsService), update the
`@Autowired` declarations to use the interface types, adjust imports, and ensure
the Spring beans implement those interfaces (so injection still works and tests
can mock the interfaces).

326-328: Redundant null checks.

pendingActivityDTO is already checked at Line 208, and incentiveName is assigned at Line 215 (would have returned if invalid). The null checks here are redundant.

♻️ Simplify condition
-                if (pendingActivityDTO != null
-                        && incentiveName != null
-                        && IncentiveName.CHILD_DEATH_REPORTING.name().equals(incentiveName.name())) {
+                if (IncentiveName.CHILD_DEATH_REPORTING.name().equals(incentiveName.name())) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java` around
lines 326 - 328, The if condition in IncentiveServiceImpl redundantly checks
pendingActivityDTO and incentiveName even though pendingActivityDTO is validated
earlier and incentiveName is assigned/validated; simplify the condition by
removing those null checks and directly check the enum value (e.g., replace "if
(pendingActivityDTO != null && incentiveName != null &&
IncentiveName.CHILD_DEATH_REPORTING.name().equals(incentiveName.name()))" with a
direct enum comparison such as "if (incentiveName ==
IncentiveName.CHILD_DEATH_REPORTING)" to both simplify and avoid unnecessary
name() calls).
src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java (1)

939-948: Remove tautological null check.

The if (incentivePendingActivity != null) check at Line 945 is always true because the object was just created at Line 940.

♻️ Proposed fix
     private void updatePendingActivity(Integer userId, Long recordId, Long activityId, Long mIncentiveId) {
         IncentivePendingActivity incentivePendingActivity = new IncentivePendingActivity();
         incentivePendingActivity.setActivityId(activityId);
         incentivePendingActivity.setRecordId(recordId);
         incentivePendingActivity.setUserId(userId);
         incentivePendingActivity.setMincentiveId(mIncentiveId);
-        if (incentivePendingActivity != null) {
-            incentivePendingActivityRepository.save(incentivePendingActivity);
-        }
+        incentivePendingActivityRepository.save(incentivePendingActivity);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java` around
lines 939 - 948, The null check in updatePendingActivity is tautological because
IncentivePendingActivity incentivePendingActivity is instantiated just above;
remove the if (incentivePendingActivity != null) guard and always call
incentivePendingActivityRepository.save(incentivePendingActivity) after setting
activityId, recordId, userId and mincentiveId to simplify the method and avoid
dead code.
src/main/java/com/iemr/flw/service/MaaMeetingService.java (2)

197-207: Remove tautological null check.

The if (incentivePendingActivity != null) check at Line 203 is always true because the object was just created at Line 198.

♻️ Proposed fix
     private void updatePendingActivity(Integer userId, Long recordId, Long activityId, Long mIncentiveId) {
         IncentivePendingActivity incentivePendingActivity = new IncentivePendingActivity();
         incentivePendingActivity.setActivityId(activityId);
         incentivePendingActivity.setRecordId(recordId);
         incentivePendingActivity.setUserId(userId);
         incentivePendingActivity.setMincentiveId(mIncentiveId);
-        if (incentivePendingActivity != null) {
-            incentivePendingActivityRepository.save(incentivePendingActivity);
-        }
+        incentivePendingActivityRepository.save(incentivePendingActivity);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/MaaMeetingService.java` around lines 197 -
207, The null check in updatePendingActivity is tautological because a new
IncentivePendingActivity is instantiated just before it; remove the if
(incentivePendingActivity != null) block and call
incentivePendingActivityRepository.save(incentivePendingActivity) directly after
setting activityId, recordId, userId, and mincentiveId to simplify the method
and avoid dead code.

114-149: Consider extracting common update logic to reduce duplication.

updateMeetingFromFileUpload duplicates most of the field-update logic from updateMeeting (Lines 84-106). Consider extracting the common logic to a private helper method.

♻️ Example refactor
private void applyUpdatesFromRequest(MaaMeeting meeting, MaaMeetingRequestDTO req) throws JsonProcessingException {
    if (req.getMeetingDate() != null) meeting.setMeetingDate(req.getMeetingDate());
    if (req.getPlace() != null) meeting.setPlace(req.getPlace());
    if (req.getParticipants() != null) meeting.setParticipants(req.getParticipants());
    if (req.getAshaId() != null) meeting.setAshaId(req.getAshaId());
    if (req.getCreatedBY() != null) meeting.setCreatedBy(req.getCreatedBY());
    
    if (req.getMeetingImages() != null && req.getMeetingImages().length > 0) {
        List<String> base64Images = Arrays.stream(req.getMeetingImages())
                .filter(file -> file != null && !file.isEmpty())
                .map(this::convertToBase64)
                .collect(Collectors.toList());
        meeting.setMeetingImagesJson(objectMapper.writeValueAsString(base64Images));
    }
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/MaaMeetingService.java` around lines 114 -
149, The updateMeetingFromFileUpload method duplicates field-update logic from
updateMeeting—extract the common updates into a private helper (e.g., private
void applyUpdatesFromRequest(MaaMeeting meeting, MaaMeetingRequestDTO req)
throws JsonProcessingException) that sets meetingDate, place, participants,
ashaId, createdBy and handles meetingImages ->
meeting.setMeetingImagesJson(objectMapper.writeValueAsString(...)) using
convertToBase64; update both updateMeeting and updateMeetingFromFileUpload to
call applyUpdatesFromRequest, preserve the JsonProcessingException in the
signature, and keep the existing checkAndUpdateIncentive(incentiveRecordId) call
when meetingImagesJson is present before repository.save(existingMeeting).
src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java (1)

329-344: Redundant nested isConfirmed check.

This block is already inside if (screeningLeprosy.getIsConfirmed()) at Line 295, so the check at Line 329 is always true. Consider removing the redundant condition or restructuring the logic.

♻️ Proposed simplification
                         }
 
-                        if (screeningLeprosy.getIsConfirmed()) {
-                            IncentiveActivityRecord incentiveActivityRecord =
-                                    incentiveLogicService.incentiveForIdentificationLeprosy(
-                                            screeningLeprosy.getBenId(),
-                                            screeningLeprosy.getTreatmentStartDate(),
-                                            screeningLeprosy.getTreatmentEndDate(),
-                                            diseaseControlDTO.getUserId());
-
-                            if (incentiveActivityRecord != null) {
-                                logger.info("Incentive processed for Screening Leprosy  successfully. RecordId={}",
-                                        incentiveActivityRecord.getId());
-                            } else {
-                                logger.info("Incentive not created");
-                            }
-
-                        }
+                        // Identification incentive for confirmed cases
+                        IncentiveActivityRecord identificationRecord =
+                                incentiveLogicService.incentiveForIdentificationLeprosy(
+                                        screeningLeprosy.getBenId(),
+                                        screeningLeprosy.getTreatmentStartDate(),
+                                        screeningLeprosy.getTreatmentEndDate(),
+                                        diseaseControlDTO.getUserId());
+
+                        if (identificationRecord != null) {
+                            logger.info("Incentive processed for Screening Leprosy successfully. RecordId={}",
+                                    identificationRecord.getId());
+                        } else {
+                            logger.info("Incentive not created");
+                        }
                     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java`
around lines 329 - 344, Inside DiseaseControlServiceImpl remove the redundant
nested check of screeningLeprosy.getIsConfirmed() around the incentive creation:
the inner if block that calls
incentiveLogicService.incentiveForIdentificationLeprosy(...) and logs the result
is already guarded by an outer if (screeningLeprosy.getIsConfirmed()), so delete
the inner condition and keep its body (the call to
incentiveForIdentificationLeprosy and subsequent logging) so the incentive logic
executes once when the outer condition is true.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7789011 and 03b610b.

📒 Files selected for processing (48)
  • pom.xml
  • src/main/java/com/iemr/flw/controller/AshaProfileController.java
  • src/main/java/com/iemr/flw/controller/DeathReportsController.java
  • src/main/java/com/iemr/flw/controller/IncentiveController.java
  • src/main/java/com/iemr/flw/controller/MaternalHealthController.java
  • src/main/java/com/iemr/flw/domain/iemr/DeliveryOutcome.java
  • src/main/java/com/iemr/flw/domain/iemr/IncentivePendingActivity.java
  • src/main/java/com/iemr/flw/domain/iemr/ScreeningKalaAzar.java
  • src/main/java/com/iemr/flw/domain/iemr/User.java
  • src/main/java/com/iemr/flw/dto/iemr/CdrDTO.java
  • src/main/java/com/iemr/flw/dto/iemr/DeliveryOutcomeDTO.java
  • src/main/java/com/iemr/flw/dto/iemr/MdsrDTO.java
  • src/main/java/com/iemr/flw/dto/iemr/PendingActivityDTO.java
  • src/main/java/com/iemr/flw/dto/iemr/TBScreeningDTO.java
  • src/main/java/com/iemr/flw/masterEnum/GroupName.java
  • src/main/java/com/iemr/flw/masterEnum/IncentiveName.java
  • src/main/java/com/iemr/flw/repo/identity/BeneficiaryRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/CdrRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/DeliveryOutcomeRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/EmployeeMasterRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/IncentivePendingActivityRepository.java
  • src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/MdsrRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/PNCVisitRepo.java
  • src/main/java/com/iemr/flw/repo/iemr/TBScreeningRepo.java
  • src/main/java/com/iemr/flw/service/EmployeeMasterInter.java
  • src/main/java/com/iemr/flw/service/IncentiveLogicService.java
  • src/main/java/com/iemr/flw/service/MaaMeetingService.java
  • src/main/java/com/iemr/flw/service/UwinSessionService.java
  • src/main/java/com/iemr/flw/service/impl/AshaProfileImpl.java
  • src/main/java/com/iemr/flw/service/impl/BeneficiaryServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/ChildCareServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/DeathReportsServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/DeliveryOutcomeServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/EmployeeMasterImpl.java
  • src/main/java/com/iemr/flw/service/impl/IncentiveLogicImpl.java
  • src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/MaternalHealthServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/NotificationSchedulerService.java
  • src/main/java/com/iemr/flw/service/impl/SammelanServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/SmsSchedulerService.java
  • src/main/java/com/iemr/flw/service/impl/TBScreeningServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/UpdateIncentivePendindDocService.java
  • src/main/java/com/iemr/flw/service/impl/UwinSessionServiceImpl.java
  • src/main/java/com/iemr/flw/service/impl/VillageLevelFormServiceImpl.java
  • src/main/java/com/iemr/flw/utils/JwtAuthenticationUtil.java
  • src/main/java/com/iemr/flw/utils/redis/RedisConfig.java
💤 Files with no reviewable changes (2)
  • src/main/java/com/iemr/flw/controller/AshaProfileController.java
  • src/main/java/com/iemr/flw/domain/iemr/DeliveryOutcome.java

Comment on lines +33 to +40
@Query("SELECT t FROM RMNCHMBeneficiaryaddress t " +
"WHERE t.createdDate BETWEEN :fromDate AND :toDate " +
"AND t.createdBy = :userName")
Page<RMNCHMBeneficiaryaddress> getBenDataWithinDates(
@Param("userName") String userName,
@Param("fromDate") Timestamp fromDate,
@Param("toDate") Timestamp toDate,
Pageable pageable);
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

Date-range semantics changed; same-day records can be dropped.

Line 34 now compares full timestamps (BETWEEN :fromDate AND :toDate) instead of date-only values. If toDate is passed as YYYY-MM-DD 00:00:00, rows later on that same day are excluded. This is a behavior regression from the prior date-truncated query.

💡 Suggested fix (preserve date-only filtering in JPQL)
-    `@Query`("SELECT t FROM RMNCHMBeneficiaryaddress t " +
-            "WHERE t.createdDate BETWEEN :fromDate AND :toDate " +
-            "AND t.createdBy = :userName")
+    `@Query`("SELECT t FROM RMNCHMBeneficiaryaddress t " +
+            "WHERE FUNCTION('DATE', t.createdDate) BETWEEN FUNCTION('DATE', :fromDate) AND FUNCTION('DATE', :toDate) " +
+            "AND t.createdBy = :userName")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/repo/identity/BeneficiaryRepo.java` around lines
33 - 40, The JPQL BETWEEN currently compares full timestamps in the query on
RMNCHMBeneficiaryaddress (method getBenDataWithinDates), causing rows later the
same day to be dropped when toDate is midnight; fix by using date-only
comparison or an exclusive end bound: either change the JPQL to compare the date
portion (e.g. use function('date', t.createdDate) BETWEEN :fromDate AND :toDate
and accept LocalDate params) or rewrite the predicate to use inclusive start and
exclusive end (t.createdDate >= :fromDate AND t.createdDate < :toDatePlusOne)
and add a toDatePlusOne parameter computed by adding one day to the provided
toDate; update the method signature/parameters accordingly.

@Query(" SELECT c FROM CDR c WHERE c.createdBy = :userId and c.createdDate >= :fromDate and c.createdDate <= :toDate")
List<CDR> getAllCdrByBenId(@Param("userId") String userId,
@Param("fromDate") Timestamp fromDate, @Param("toDate") Timestamp toDate);
List<CDR>findByCreatedBy(String userName);
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:

#!/bin/bash
# Search for old method references and new method usage

echo "=== Searching for old method 'getAllCdrByBenId' ==="
rg -n 'getAllCdrByBenId' --type java

echo "=== Searching for new method 'findByCreatedBy' ==="
rg -n 'findByCreatedBy' --type java

echo "=== Searching for CdrRepo usage (excluding CdrRepo.java itself) ==="
rg -n 'CdrRepo' --type java --glob '!CdrRepo.java'

echo "=== Checking imports of CdrRepo ==="
rg -n 'import.*CdrRepo' --type java

Repository: PSMRI/FLW-API

Length of output: 1079


🏁 Script executed:

#!/bin/bash
# Check the context of findByCreatedBy usage in DeathReportsServiceImpl

echo "=== Context around line 187 in DeathReportsServiceImpl ==="
sed -n '180,195p' src/main/java/com/iemr/flw/service/impl/DeathReportsServiceImpl.java

echo "=== Broader context to understand the method flow ==="
sed -n '170,220p' src/main/java/com/iemr/flw/service/impl/DeathReportsServiceImpl.java

echo "=== Check if old method had any documentation ==="
rg -B5 -A10 'getAllCdrByBenId' --type java

Repository: PSMRI/FLW-API

Length of output: 2324


Address unbounded result set risk and verify filtering logic change is intentional.

This is a breaking change, and callers have been updated. However, the issue is more significant than initially stated:

  1. Filtering logic fundamentally changed: The method previously filtered by beneficiary ID + date range (getAllCdrByBenId); it now filters only by user who created the record (findByCreatedBy). This changes the semantics of what data is retrieved.

  2. Unbounded result set: With no date bounds or pagination applied, findByCreatedBy could return all CDR records created by a user, potentially causing performance degradation or memory issues for users with large record volumes.

  3. Intentional refactoring: This pattern is consistently applied across multiple repositories (MdsrRepo, DeliveryOutcomeRepo, MdaFormSubmissionRepository), suggesting a deliberate design decision.

Verify that the change in filtering logic (from beneficiary-based + date range to user-based only) aligns with actual requirements, and consider adding pagination or result limits to prevent unbounded queries.

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

In `@src/main/java/com/iemr/flw/repo/iemr/CdrRepo.java` at line 17, The new
repository method findByCreatedBy(String userName) changed semantics from the
previous beneficiary+date filtering (getAllCdrByBenId) and can return an
unbounded result set; confirm intended behavior and either restore the original
beneficiary + date-range signature (e.g., reintroduce getAllCdrByBenId with
benId, startDate, endDate) or make findByCreatedBy bounded by adding pagination
or explicit date params (e.g., change to Page<CDR> findByCreatedBy(String
userName, Pageable pageable) or add startDate/endDate args), then update all
callers to use the corrected method and ensure tests reflect the intended filter
semantics.

@Query(" SELECT m FROM MDSR m WHERE m.createdBy = :userId and m.createdDate >= :fromDate and m.createdDate <= :toDate")
List<MDSR> getAllMdsrByAshaId(@Param("userId") String userId,
@Param("fromDate") Timestamp fromDate, @Param("toDate") Timestamp toDate);
List<MDSR> findByCreatedBy(String userName);
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:

#!/bin/bash
set -euo pipefail

# First, let's find the repository interface definition
echo "=== Repository Interface Definition ==="
rg -nP --type=java '\binterface\s+MdsrRepo\b' -A 10

echo -e "\n=== Method Signatures in MdsrRepo ==="
rg -nP --type=java '\bfindByCreatedBy\s*\(' --type=java

echo -e "\n=== Call Sites for findByCreatedBy ==="
rg -nP --type=java -C 3 'mdsrRepo\.findByCreatedBy\s*\('

echo -e "\n=== Searching for any Pageable imports and usage patterns ==="
rg -nP --type=java 'import.*Pageable|org\.springframework\.data\.domain' 

echo -e "\n=== Checking for date-based filtering near findByCreatedBy calls ==="
rg -nP --type=java -C 5 'findByCreatedBy\s*\('

Repository: PSMRI/FLW-API

Length of output: 11665


Add pagination to unbounded findByCreatedBy() fetch

Line 17 returns all records for a user without bounds, which loads entire result set into memory and can cause memory spikes and slow response times for users with large historical datasets. This is especially problematic for death report queries that should be time-bound.

At the call site (DeathReportsServiceImpl:206), the results are converted directly with no downstream filtering or pagination applied. Add a Pageable parameter to bound the query at the repository level, consistent with pagination patterns used elsewhere in the codebase.

Suggested fix
+import org.springframework.data.domain.Pageable;
 import java.util.List;
@@
-    List<MDSR> findByCreatedBy(String userName);
+    List<MDSR> findByCreatedBy(String userName, Pageable pageable);
📝 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.

Suggested change
List<MDSR> findByCreatedBy(String userName);
import org.springframework.data.domain.Pageable;
import java.util.List;
// ... other code ...
List<MDSR> findByCreatedBy(String userName, Pageable pageable);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/repo/iemr/MdsrRepo.java` at line 17, The
repository method findByCreatedBy currently returns an unbounded List and must
be changed to support paging: update the MdsrRepo signature to accept a Pageable
(e.g., change to Page<MDSR> findByCreatedBy(String userName, Pageable pageable))
and update the call site in DeathReportsServiceImpl (around line 206) to pass a
Pageable (or construct one from request parameters) and to handle the returned
Page (use page.getContent(), totalElements, etc. as needed) so results are
bounded and consistent with existing pagination patterns.

Comment on lines +15 to +16
@Query(value = "SELECT pnc FROM PNCVisit pnc WHERE pnc.createdBy = :userId and pnc.isActive = true")
List<PNCVisit> getPNCForPW(@Param("userId") String userId);
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 -A 5 'getPNCForPW' --type java

Repository: PSMRI/FLW-API

Length of output: 1224


🏁 Script executed:

#!/bin/bash
# Get context around the usage in MaternalHealthServiceImpl
rg -n -B 10 -A 10 'getPNCForPW' src/main/java/com/iemr/flw/service/impl/MaternalHealthServiceImpl.java | head -50

# Also check if there's a controller method calling this service method
rg -n 'getPNCForPW|getAllPNCVisits|getPNC' --type java src/main/java/com/iemr/flw/controller/ 2>/dev/null || echo "No controller references found"

Repository: PSMRI/FLW-API

Length of output: 1196


🏁 Script executed:

#!/bin/bash
# Get full controller method implementation
rg -n -A 20 'public String getPNCVisitDetails' src/main/java/com/iemr/flw/controller/MaternalHealthController.java

echo "---"

# Find GetBenRequestHandler definition
rg -n -A 10 'class GetBenRequestHandler' --type java

Repository: PSMRI/FLW-API

Length of output: 2280


Implement date-range filtering and pagination to prevent unbounded result sets.

The query returns all active PNC visits for a user without date bounds. More critically, the GetBenRequestHandler DTO provides fromDate, toDate, and pageNo fields, but the service method ignores these parameters entirely, discarding the caller's intent to filter and paginate results. This could lead to significant performance degradation and memory pressure if users accumulate many historical records.

Apply date filtering in the repository query or service layer using the DTO's fromDate and toDate fields, and implement pagination using pageNo to keep result sets bounded.

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

In `@src/main/java/com/iemr/flw/repo/iemr/PNCVisitRepo.java` around lines 15 - 16,
The repository method getPNCForPW currently returns all active PNCVisit rows for
a user without applying the GetBenRequestHandler.fromDate/toDate or pagination
(pageNo); change the repo to accept date range and pagination (e.g., add
parameters for fromDate and toDate and a Pageable or return Page<PNCVisit>)
and/or replace the `@Query` with a derived query such as
findByCreatedByAndIsActiveAndVisitDateBetween or a JPQL query that filters by
:fromDate and :toDate; then update the service method that calls getPNCForPW to
pass GetBenRequestHandler.fromDate, toDate and a PageRequest built from pageNo
so results are bounded and filtered by date before returning to callers.

Comment on lines +18 to +19
@Query(value = "SELECT tbs FROM TBScreening tbs WHERE tbs.userId = :userId")
List<TBScreening> getByUserId(@Param("userId") Integer userId);
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

User-only TB query is now unbounded and may return full history.

This change removes time-window scoping and can significantly increase data volume and latency for long-tenure users.

Suggested bounded query restoration
-    `@Query`(value = "SELECT tbs FROM TBScreening tbs WHERE tbs.userId = :userId")
-    List<TBScreening> getByUserId(`@Param`("userId") Integer userId);
+    `@Query`(value = "SELECT tbs FROM TBScreening tbs WHERE tbs.userId = :userId AND tbs.visitDate BETWEEN :fromDate AND :toDate")
+    List<TBScreening> getByUserId(`@Param`("userId") Integer userId,
+                                  `@Param`("fromDate") Timestamp fromDate,
+                                  `@Param`("toDate") Timestamp toDate);
📝 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.

Suggested change
@Query(value = "SELECT tbs FROM TBScreening tbs WHERE tbs.userId = :userId")
List<TBScreening> getByUserId(@Param("userId") Integer userId);
`@Query`(value = "SELECT tbs FROM TBScreening tbs WHERE tbs.userId = :userId AND tbs.visitDate BETWEEN :fromDate AND :toDate")
List<TBScreening> getByUserId(`@Param`("userId") Integer userId,
`@Param`("fromDate") Timestamp fromDate,
`@Param`("toDate") Timestamp toDate);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/repo/iemr/TBScreeningRepo.java` around lines 18 -
19, The repository method getByUserId in TBScreeningRepo now returns an
unbounded history; change the Query to restrict results by a time window: add
parameters (e.g., `@Param`("start"), `@Param`("end")) to the method signature and
modify the JPQL to include a date filter such as "AND tbs.screeningDate BETWEEN
:start AND :end" (or use the entity's appropriate timestamp field like createdAt
if different), and update callers to pass the start/end dates so queries are
bounded to the desired time range.

Comment on lines +69 to +72
}catch (Exception e){
logger.error("TBScreening Exception:"+e.getMessage());
}
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 | 🟠 Major

Do not swallow fetch exceptions by returning null.

This path hides real failures and can misclassify errors downstream. Log the full exception and propagate/translate it explicitly.

Suggested error-handling fix
-        }catch (Exception e){
-            logger.error("TBScreening Exception:"+e.getMessage());
-        }
-       return null;
+        } catch (Exception e) {
+            logger.error("TBScreening exception while fetching records", e);
+            throw new RuntimeException("Failed to fetch TB screening records", e);
+        }
📝 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.

Suggested change
}catch (Exception e){
logger.error("TBScreening Exception:"+e.getMessage());
}
return null;
} catch (Exception e) {
logger.error("TBScreening exception while fetching records", e);
throw new RuntimeException("Failed to fetch TB screening records", e);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/TBScreeningServiceImpl.java` around
lines 69 - 72, The catch block in TBScreeningServiceImpl currently swallows
exceptions and returns null; replace this by logging the full exception (use
logger.error with the Throwable, e.g., logger.error("TBScreening Exception", e))
and then propagate the error instead of returning null—either rethrow the same
exception or wrap it in an appropriate unchecked/checked application exception
(e.g., throw new RuntimeException("Failed to fetch TB screening", e)) so callers
can distinguish failure from an empty result.

Comment on lines +117 to +120
// Update fields if present in request
if (req.getPlace() != null) session.setPlace(req.getPlace());
if (req.getParticipants() != null) session.setParticipants(req.getParticipants());
if (req.getDate() != null) session.setDate(req.getDate());
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

Apply the same validation rules in updateSession as saveSession.

updateSession currently accepts future dates/backdated dates and out-of-range participants, while saveSession rejects them.

Suggested fix
+    private void validateSessionUpdate(UwinSessionRequestDTO req) {
+        Timestamp now = Timestamp.from(Instant.now());
+        if (req.getDate() != null) {
+            if (req.getDate().after(now)) {
+                throw new RuntimeException("Date cannot be in future");
+            }
+            if (req.getDate().toLocalDateTime().isBefore(LocalDateTime.now().minusMonths(2))) {
+                throw new RuntimeException("Backdate not allowed beyond 2 months");
+            }
+        }
+        if (req.getParticipants() != null && (req.getParticipants() < 0 || req.getParticipants() > 999)) {
+            throw new RuntimeException("Participants count must be between 0–999");
+        }
+    }
+
     public UwinSession updateSession(UwinSessionRequestDTO req, Long recordId, Long activityId) throws Exception {
+        validateSessionUpdate(req);
         Optional<UwinSession> optionalUwinSession = repo.findById(recordId);
         ...
     }
📝 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.

Suggested change
// Update fields if present in request
if (req.getPlace() != null) session.setPlace(req.getPlace());
if (req.getParticipants() != null) session.setParticipants(req.getParticipants());
if (req.getDate() != null) session.setDate(req.getDate());
private void validateSessionUpdate(UwinSessionRequestDTO req) {
Timestamp now = Timestamp.from(Instant.now());
if (req.getDate() != null) {
if (req.getDate().after(now)) {
throw new RuntimeException("Date cannot be in future");
}
if (req.getDate().toLocalDateTime().isBefore(LocalDateTime.now().minusMonths(2))) {
throw new RuntimeException("Backdate not allowed beyond 2 months");
}
}
if (req.getParticipants() != null && (req.getParticipants() < 0 || req.getParticipants() > 999)) {
throw new RuntimeException("Participants count must be between 0–999");
}
}
public UwinSession updateSession(UwinSessionRequestDTO req, Long recordId, Long activityId) throws Exception {
validateSessionUpdate(req);
Optional<UwinSession> optionalUwinSession = repo.findById(recordId);
// ... existing method logic ...
// Update fields if present in request
if (req.getPlace() != null) session.setPlace(req.getPlace());
if (req.getParticipants() != null) session.setParticipants(req.getParticipants());
if (req.getDate() != null) session.setDate(req.getDate());
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/UwinSessionServiceImpl.java` around
lines 117 - 120, The updateSession method currently skips the date and
participants validation that saveSession enforces; replicate the same
validations from saveSession in updateSession (or extract them into a shared
validateSessionRequest(RequestType) helper and call it from both) so that
updateSession rejects future dates, backdated/out-of-range dates and
participants outside the allowed range before applying session.setDate(...) or
session.setParticipants(...); ensure you reuse the same checks and exception
types/messages used in saveSession (or call the shared validator) so behavior
and error responses remain consistent.

Comment on lines +191 to +193
if(session.getAttachmentsJson()!=null){
record.setIsEligible(true);
recordRepo.save(record);
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

Eligibility should require actual attachments, not just non-null JSON.

attachmentsJson can be "[]", which still marks records eligible in these checks.

Suggested fix
+    private boolean hasRealAttachments(String attachmentsJson) {
+        return attachmentsJson != null && !"[]".equals(attachmentsJson);
+    }
...
-                if(session.getAttachmentsJson()!=null){
+                if (hasRealAttachments(session.getAttachmentsJson())) {
                     record.setIsEligible(true);
...
-                if(session.getAttachmentsJson()!=null){
+                if (hasRealAttachments(session.getAttachmentsJson())) {
                     record.setIsEligible(true);

Also applies to: 222-223

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

In `@src/main/java/com/iemr/flw/service/impl/UwinSessionServiceImpl.java` around
lines 191 - 193, The current eligibility check marks records eligible if
session.getAttachmentsJson() is non-null even when it is an empty array string
like "[]"; update the logic where record.setIsEligible(true) and
recordRepo.save(record) are called (both occurrences using
session.getAttachmentsJson()) to parse or inspect the attachmentsJson value and
only set eligibility when it contains at least one attachment (e.g., check that
the JSON is not empty array or length>2, or parse into a collection and verify
size>0) before calling record.setIsEligible(true) and saving via
recordRepo.save(record).

Comment on lines 226 to 228
updateIncentivePendindDocService.updatePendingActivity(session.getAshaId(),session.getId(),record.getId(),incentiveActivityCH.getId());
}
recordRepo.save(record);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Save the record before using its ID in pending-doc linkage.

Line 226 passes record.getId() before persistence, so pending-doc updates can receive a null recordId.

Suggested fix
-                if(session.getAttachmentsJson()!=null){
-                    record.setIsEligible(true);
-                }else {
-                    record.setIsEligible(false);
-                    updateIncentivePendindDocService.updatePendingActivity(session.getAshaId(),session.getId(),record.getId(),incentiveActivityCH.getId());
-                }
-                recordRepo.save(record);
+                if (session.getAttachmentsJson() != null) {
+                    record.setIsEligible(true);
+                    recordRepo.save(record);
+                } else {
+                    record.setIsEligible(false);
+                    IncentiveActivityRecord saved = recordRepo.save(record);
+                    updateIncentivePendindDocService.updatePendingActivity(
+                            session.getAshaId(), session.getId(), saved.getId(), incentiveActivityCH.getId());
+                }
📝 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.

Suggested change
updateIncentivePendindDocService.updatePendingActivity(session.getAshaId(),session.getId(),record.getId(),incentiveActivityCH.getId());
}
recordRepo.save(record);
if (session.getAttachmentsJson() != null) {
record.setIsEligible(true);
recordRepo.save(record);
} else {
record.setIsEligible(false);
IncentiveActivityRecord saved = recordRepo.save(record);
updateIncentivePendindDocService.updatePendingActivity(
session.getAshaId(), session.getId(), saved.getId(), incentiveActivityCH.getId());
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/com/iemr/flw/service/impl/UwinSessionServiceImpl.java` around
lines 226 - 228, The call to
updateIncentivePendindDocService.updatePendingActivity uses record.getId()
before the record is persisted, which can pass a null ID; change the order in
UwinSessionServiceImpl so you call recordRepo.save(record) first (or capture the
returned savedRecord from recordRepo.save and use savedRecord.getId()), then
call updateIncentivePendindDocService.updatePendingActivity(session.getAshaId(),
session.getId(), savedRecord.getId(), incentiveActivityCH.getId()) to ensure a
non-null persisted recordId is passed.

Comment on lines +153 to +158
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");

LocalDate localDate = LocalDate.parse(vhncForm.getVhncDate(), formatter);

Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
incentiveLogicService.incentiveForAttendingVhsnc(0L,date,date,Math.toIntExact(vhncForm.getUserId()));
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

Make form save + incentive creation atomic.

These blocks run after persistence; if parsing or incentive logic throws, you can end up with saved form data but missing incentive record.

Suggested hardening
+import org.springframework.transaction.annotation.Transactional;
...
-    private Boolean saveVhncFormData(VhncFormDTO vhncFormDTO, Integer userID) {
+    `@Transactional`
+    private Boolean saveVhncFormData(VhncFormDTO vhncFormDTO, Integer userID) {
         VhncForm vhncForm = new VhncForm();
         ...
-        vhncFormRepo.save(vhncForm);
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
-        LocalDate localDate = LocalDate.parse(vhncForm.getVhncDate(), formatter);
-        Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+        Date date = parseFormDate(vhncForm.getVhncDate());
+        vhncFormRepo.save(vhncForm);
         incentiveLogicService.incentiveForAttendingVhsnc(0L, date, date, Math.toIntExact(vhncForm.getUserId()));
         return true;
     }
+
+    private Date parseFormDate(String formDate) {
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
+        LocalDate localDate = LocalDate.parse(formDate, formatter);
+        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
+    }

Also applies to: 178-183, 245-250

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

In `@src/main/java/com/iemr/flw/service/impl/VillageLevelFormServiceImpl.java`
around lines 153 - 158, The form save and subsequent incentive creation
(incentiveLogicService.incentiveForAttendingVhsnc) must be made atomic: ensure
the persistence of vhncForm and the Date parsing/LocalDate.parse and the call to
incentiveLogicService occur inside a single transactional boundary (e.g.,
annotate the enclosing service method in VillageLevelFormServiceImpl with
`@Transactional` or use TransactionTemplate) so that any parsing or incentive
logic exceptions roll back the saved form; apply the same transactional change
to the other blocks that call incentiveForAttendingVhsnc (the blocks around
LocalDate.parse/use of DateTimeFormatter at the locations flagged 178-183 and
245-250) so both save and incentive creation succeed or both are rolled back.

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