diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index 764ebeaf..57b4e3b4 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -49,6 +49,9 @@ public class DiseaseControlController { @Autowired private DiseaseControlService diseaseControlService; + @Autowired + private ObjectMapper objectMapper; + @RequestMapping(value = "malaria/saveAll", method = RequestMethod.POST, consumes = "application/json", produces = "application/json",headers = "Authorization") public ResponseEntity> saveMalaria(@RequestBody MalariaDTO malariaDTO) { @@ -375,4 +378,72 @@ public ResponseEntity> getVisitDetails( } + @RequestMapping(value = "generalCheckUp/getAll", method = RequestMethod.POST) + public ResponseEntity> getGeneralCheckUp(@RequestBody GetBenRequestHandler getBenRequestHandler,@RequestHeader(value = "JwtToken") String token) { + + Map response = new LinkedHashMap<>(); + + try { + List result = + diseaseControlService.getGeneralCheckUp(token); + + if (result != null && !result.isEmpty()) { + response.put("statusCode", HttpStatus.OK.value()); + response.put("data", result); + return ResponseEntity.ok(response); + } else { + response.put("statusCode", HttpStatus.NOT_FOUND.value()); + response.put("message", "No records found"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + + } catch (Exception e) { + logger.error("Error fetching Chronic Disease Visit :", e); + response.put("statusCode", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("errorMessage", e.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + + @RequestMapping(value = "generalCheckUp/saveAll", method = RequestMethod.POST) + public ResponseEntity> savGeneralCheckUp( + @RequestBody List requestList,@RequestHeader(value = "JwtToken") String token) { + + Map response = new LinkedHashMap<>(); + logger.info("####################################################"); + try { + logger.info("General Checkup Save Request: {}", + objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(requestList)); + } catch (Exception e) { + logger.error("Failed to convert request to JSON", e); + } + logger.info("####################################################"); + + try { + List savedList = + diseaseControlService.saveGeneralCheckUp(requestList,token); + + if (savedList != null && !savedList.isEmpty()) { + response.put("statusCode", HttpStatus.OK.value()); + response.put("message", "Data saved successfully"); + response.put("data", savedList); + return ResponseEntity.ok(response); + } else { + response.put("statusCode", HttpStatus.BAD_REQUEST.value()); + response.put("message", "No data saved"); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + } catch (Exception e) { + logger.error("Error saving Chronic Disease Visit :", e); + response.put("statusCode", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("errorMessage", e.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + + } \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/controller/GeneralCheckUpFollowUpController.java b/src/main/java/com/iemr/flw/controller/GeneralCheckUpFollowUpController.java new file mode 100644 index 00000000..ca450d67 --- /dev/null +++ b/src/main/java/com/iemr/flw/controller/GeneralCheckUpFollowUpController.java @@ -0,0 +1,121 @@ +/* +* AMRIT – Accessible Medical Records via Integrated Technology +* Integrated EHR (Electronic Health Records) Solution +* +* Copyright (C) "Piramal Swasthya Management and Research Institute" +* +* This file is part of AMRIT. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +* +/* +* AMRIT – Accessible Medical Records via Integrated Technology +*/ +package com.iemr.flw.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iemr.flw.dto.identity.GetBenRequestHandler; +import com.iemr.flw.dto.iemr.*; +import com.iemr.flw.service.DiseaseControlService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping(value = "/generalCheckUpFollowUp",headers = "Authorization") +public class GeneralCheckUpFollowUpController { + private final Logger logger = LoggerFactory.getLogger(GeneralCheckUpFollowUpController.class); + + @Autowired + private DiseaseControlService diseaseControlService; + + @Autowired + private ObjectMapper objectMapper; + + + + @RequestMapping(value = "getAll", method = RequestMethod.POST) + public ResponseEntity> getGeneralCheckUpFollowUp(@RequestBody GetBenRequestHandler getBenRequestHandler,@RequestHeader(value = "JwtToken") String token) { + + Map response = new LinkedHashMap<>(); + + try { + List result = + diseaseControlService.getGeneralCheckUpFollowUp(token); + + if (result != null && !result.isEmpty()) { + response.put("statusCode", HttpStatus.OK.value()); + response.put("data", result); + return ResponseEntity.ok(response); + } else { + response.put("statusCode", HttpStatus.NOT_FOUND.value()); + response.put("message", "No records found"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response); + } + + } catch (Exception e) { + logger.error("Error fetching Chronic Disease Visit :", e); + response.put("statusCode", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("errorMessage", e.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + + + @RequestMapping(value = "saveAll", method = RequestMethod.POST) + public ResponseEntity> savGeneralCheckUpFollowUp( + @RequestBody List requestList,@RequestHeader(value = "JwtToken") String token) { + + Map response = new LinkedHashMap<>(); + logger.info("####################################################"); + try { + logger.info("General Checkup Save Request: {}", + objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(requestList)); + } catch (Exception e) { + logger.error("Failed to convert request to JSON", e); + } + logger.info("####################################################"); + + try { + List savedList = + diseaseControlService.saveGeneralCheckUpFollowUp(requestList,token); + + if (savedList != null && !savedList.isEmpty()) { + response.put("statusCode", HttpStatus.OK.value()); + response.put("message", "Data saved successfully"); + response.put("data", savedList); + return ResponseEntity.ok(response); + } else { + response.put("statusCode", HttpStatus.BAD_REQUEST.value()); + response.put("message", "No data saved"); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response); + } + + } catch (Exception e) { + logger.error("Error saving Chronic Disease Visit :", e); + response.put("statusCode", HttpStatus.INTERNAL_SERVER_ERROR.value()); + response.put("errorMessage", e.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java new file mode 100644 index 00000000..ec9f9c64 --- /dev/null +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java @@ -0,0 +1,72 @@ +package com.iemr.flw.domain.iemr; + +import java.sql.Timestamp; +import java.time.LocalDate; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Table(name = "general_check_up", schema = "db_iemr") +@Data +public class GeneralCheckUp { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "ben_id") + private Long benId; + + @Column(name = "household_id") + private Long householdId; + + @Column(name = "asha_id", nullable = false) + private Integer ashaId; + + @Column(name = "checkup_date", nullable = false) + private LocalDate checkupDate; + + @Column(name = "problem_type", length = 200) + private String problemType; + + @Column(name = "problems", columnDefinition = "json") + private String problems; + + @Column(name = "checkup_id", length = 50, unique = true) + private String checkupId; + + @Column(name = "problem_type_label", length = 200) + private String problemTypeLabel; + + @Column(name = "other_text", length = 500) + private String otherText; + + @Column(name = "priority", length = 20) + private String priority; + + + @Column(name = "referral_reason", length = 500) + private String referralReason; + + @Column(name = "referral_date") + private LocalDate referralDate; + + @Column(name = "created_by", length = 100) + private String createdBy; + + @Column(name = "created_date", insertable = false, updatable = false) + private Timestamp createdDate; + + @Column(name = "synced_date") + private Timestamp syncedDate; + + @Column(name = "updated_date", insertable = false, updatable = false) + private Timestamp updatedDate; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java new file mode 100644 index 00000000..95247238 --- /dev/null +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java @@ -0,0 +1,57 @@ +package com.iemr.flw.domain.iemr; + +import jakarta.persistence.*; +import lombok.Data; + +import java.sql.Timestamp; +import java.time.LocalDate; + +@Entity +@Table(name = "general_checkup_followup", schema = "db_iemr") +@Data +public class GeneralCheckUpFollowUp { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "ben_id") + private Long benId; + + @Column(name = "household_id") + private Long householdId; + + @Column(name = "asha_id", nullable = false) + private Integer ashaId; + + @Column(name = "follow_up_date", nullable = false) + private LocalDate followUpDate; + + @Column(name = "followup_status", length = 200) + private String followupStatus; + + @Column(name = "referred_to", columnDefinition = "json") + private String referredTo; + + @Column(name = "created_by", length = 100) + private String createdBy; + + @Column(name = "created_date", insertable = false, updatable = false) + private Timestamp createdDate; + + @Column(name = "synced_date") + private Timestamp syncedDate; + + @Column(name = "updated_date", insertable = false, updatable = false) + private Timestamp updatedDate; + + @Column(name = "referralReason") + private String referralReason; + + @Column(name = "referredOnDate") + private LocalDate referredOnDate; + + @Column(name = "other_follow_up") + private String otherFollowUp; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/domain/iemr/TBSuspected.java b/src/main/java/com/iemr/flw/domain/iemr/TBSuspected.java index be27aaa5..370fe276 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/TBSuspected.java +++ b/src/main/java/com/iemr/flw/domain/iemr/TBSuspected.java @@ -82,6 +82,9 @@ public class TBSuspected { @Column(name = "is_tb_confirmed") private Boolean isTBConfirmed; + @Column(name = "is_recommended_for_tpt") + private Boolean isRecommendedForTpt; + @Column(name = "is_drtb_confirmed") private Boolean isDRTBConfirmed; diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java new file mode 100644 index 00000000..da0594c3 --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java @@ -0,0 +1,12 @@ +package com.iemr.flw.dto.iemr; + +import lombok.Data; + +@Data +public class GeneralCheckUpDto { + private Long id; + private Long beneficiaryId; + private Long houseHoldId; + private String visitDate; + private GeneralCheckUpListDto fields; +} diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java new file mode 100644 index 00000000..9840e0d0 --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java @@ -0,0 +1,16 @@ +package com.iemr.flw.dto.iemr; + +import lombok.Data; + +import java.time.LocalDate; + +@Data +public class GeneralCheckUpFollowUpDto { + private Long id; + private Long beneficiaryId; + private Long houseHoldId; + private String visitDate; + private String referralReason; + private LocalDate referredOnDate; + private GeneralCheckUpFollowUpListDto fields; +} diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java new file mode 100644 index 00000000..07bf2d49 --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java @@ -0,0 +1,22 @@ +package com.iemr.flw.dto.iemr; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class GeneralCheckUpFollowUpListDto { + @JsonProperty("follow_up_date") + private String followUpDate; + + @JsonProperty("followup_status") + private String followupStatus; + + @JsonProperty("referred_to") + private String referredTo; + + @JsonProperty("other_follow_up") + private String otherFollowUp; + +} diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java new file mode 100644 index 00000000..27f58e69 --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java @@ -0,0 +1,51 @@ +package com.iemr.flw.dto.iemr; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class GeneralCheckUpListDto { + @JsonProperty("check_up_date") + private String check_up_date; + + @JsonProperty("problem_type") + private String problemType; + + @JsonProperty("problems_g6") + private String problemsG6; + + @JsonProperty("other_text") + private String otherTextLegacy; + + private String checkupId; + + private Integer ashaId; + + private String checkupDate; + + private String problemTypeId; + + private String problemTypeLabel; + + private List problems; + + private String otherText; + + private String priority; + + private Integer masterVersion; + + private String referralReason; + + private String referralDate; + + private String createdBy; + + private Long createdDate; + + private Long updatedDate; + + +} diff --git a/src/main/java/com/iemr/flw/dto/iemr/ProblemDto.java b/src/main/java/com/iemr/flw/dto/iemr/ProblemDto.java new file mode 100644 index 00000000..44de6eab --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/ProblemDto.java @@ -0,0 +1,11 @@ +package com.iemr.flw.dto.iemr; + +import lombok.Data; + +@Data +public class ProblemDto { + + private String problemId; + + private String label; +} \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/dto/iemr/TBSuspectedDTO.java b/src/main/java/com/iemr/flw/dto/iemr/TBSuspectedDTO.java index 23e568ef..ec31fa56 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/TBSuspectedDTO.java +++ b/src/main/java/com/iemr/flw/dto/iemr/TBSuspectedDTO.java @@ -36,4 +36,5 @@ public class TBSuspectedDTO { private Boolean isDRTBConfirmed; private Boolean referred; private String followUps; + private Boolean isRecommendedForTpt; } diff --git a/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java b/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java index 25a0b652..a475476a 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java @@ -45,8 +45,14 @@ public interface BenReferDetailsRepo extends JpaRepository findLatestByBeneficiaryRegIDs(@Param("benRegIDs") List benRegIDs); + List findByCreatedBy(String userName); + @Query(value = "SELECT COUNT(*) FROM db_iemr.t_benreferdetails WHERE CreatedBy = :userName AND revisitDate >= :startDate AND revisitDate < :endDate", nativeQuery = true) + Long countMonthlyReferralsByDateRange(@Param("userName") String userName, @Param("startDate") java.sql.Timestamp startDate, @Param("endDate") java.sql.Timestamp endDate); + @Query(value = """ SELECT COUNT(*) FROM db_iemr.t_benreferdetails diff --git a/src/main/java/com/iemr/flw/repo/iemr/CbacIemrDetailsRepo.java b/src/main/java/com/iemr/flw/repo/iemr/CbacIemrDetailsRepo.java index 5e93dfad..82a96c80 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/CbacIemrDetailsRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/CbacIemrDetailsRepo.java @@ -37,6 +37,9 @@ public interface CbacIemrDetailsRepo extends CrudRepository findByCreatedBy(String userName); + @Query("SELECT c.beneficiaryRegId, c.createdDate FROM CbacDetailsImer c WHERE c.createdBy = :userName AND c.beneficiaryRegId IS NOT NULL AND c.createdDate IS NOT NULL") + List findBenRegIdAndCreatedDateByCreatedBy(@Param("userName") String userName); + @Query(value = "SELECT BeneficiaryID FROM db_identity.m_beneficiaryregidmapping " + "WHERE BenRegId = :benRegId AND Deleted = 0", nativeQuery = true) Long getBeneficiaryId(@Param("benRegId") Long benRegId); diff --git a/src/main/java/com/iemr/flw/repo/iemr/EligibleCoupleRegisterRepo.java b/src/main/java/com/iemr/flw/repo/iemr/EligibleCoupleRegisterRepo.java index 218c5b2b..d9418df0 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/EligibleCoupleRegisterRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/EligibleCoupleRegisterRepo.java @@ -16,6 +16,8 @@ public interface EligibleCoupleRegisterRepo extends JpaRepository findByCreatedBy(String userName); + long countByCreatedBy(String userName); + @Query(" SELECT ecr FROM EligibleCoupleRegister ecr WHERE ecr.createdBy = :userId and ecr.createdDate >= :fromDate and ecr.createdDate <= :toDate") List getECRegRecords(@Param("userId") String userId, @Param("fromDate") Timestamp fromDate, @Param("toDate") Timestamp toDate); diff --git a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java new file mode 100644 index 00000000..cef91526 --- /dev/null +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java @@ -0,0 +1,22 @@ +package com.iemr.flw.repo.iemr; + +import com.iemr.flw.domain.iemr.GeneralCheckUpFollowUp; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +@Repository +public interface GeneralCheckUpFollowUpRepository + extends JpaRepository { + List findByAshaId(Integer userId); + + Optional + findFirstByBenIdAndReferralReasonAndReferredOnDateGreaterThanEqualAndReferredOnDateLessThan( + Long benId, + String referralReason, + LocalDate monthStart, + LocalDate nextMonthStart);} + diff --git a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java new file mode 100644 index 00000000..557f8230 --- /dev/null +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java @@ -0,0 +1,12 @@ +package com.iemr.flw.repo.iemr; + +import com.iemr.flw.domain.iemr.GeneralCheckUp; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface GeneralCheckUpRepo extends JpaRepository { + List findByCreatedBy(String userName); +} diff --git a/src/main/java/com/iemr/flw/repo/iemr/GeneralOpdRepo.java b/src/main/java/com/iemr/flw/repo/iemr/GeneralOpdRepo.java index fe944765..6c7e1b70 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/GeneralOpdRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralOpdRepo.java @@ -25,11 +25,11 @@ package com.iemr.flw.repo.iemr; import com.iemr.flw.domain.iemr.GeneralOpdData; -import io.lettuce.core.dynamic.annotation.Param; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -44,7 +44,7 @@ public interface GeneralOpdRepo extends JpaRepository { WHERE ibfo.visit_category = 'General OPD' AND ibfo.beneficiary_visit_code <> 0 AND ibfo.villageID = :villageID - AND ibfo.created_by =:userName + AND ibfo.created_by = :userName AND (ibfo.deleted IS NULL OR ibfo.deleted = 0) AND (mbrm.Deleted IS NULL OR mbrm.Deleted = 0) ORDER BY ibfo.created_date DESC @@ -57,12 +57,13 @@ SELECT COUNT(*) WHERE ibfo.visit_category = 'General OPD' AND ibfo.beneficiary_visit_code <> 0 AND ibfo.villageID = :villageID + AND ibfo.created_by = :userName AND (ibfo.deleted IS NULL OR ibfo.deleted = 0) AND (mbrm.Deleted IS NULL OR mbrm.Deleted = 0) """, nativeQuery = true) Page findFilteredOutreachData( @Param("villageID") Integer villageID, - Pageable pageable,@Param("userName") String userName); + Pageable pageable, @Param("userName") String userName); } diff --git a/src/main/java/com/iemr/flw/repo/iemr/IFAFormSubmissionRepository.java b/src/main/java/com/iemr/flw/repo/iemr/IFAFormSubmissionRepository.java index 0b1b5ff7..88201f45 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/IFAFormSubmissionRepository.java +++ b/src/main/java/com/iemr/flw/repo/iemr/IFAFormSubmissionRepository.java @@ -11,6 +11,8 @@ public interface IFAFormSubmissionRepository extends JpaRepository { List findByUserId(Integer userName); + + long countByUserId(Integer userId); @Query("SELECT i FROM IFAFormSubmissionData i " + "WHERE i.userId = :userId " + "AND i.visitDate = :visitDate") diff --git a/src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java b/src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java index 74acfa5f..d72c069d 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/IncentiveRecordRepo.java @@ -38,6 +38,21 @@ IncentiveActivityRecord findRecordByActivityIdCreatedDateBenId( Optional findById(Long id); + @Query("SELECT record FROM IncentiveActivityRecord record WHERE record.ashaId = :ashaId ORDER BY record.id DESC") + List findRecordsByAshaOrderByIdDesc(@Param("ashaId") Integer ashaId); + + @Query("SELECT r.activityId FROM IncentiveActivityRecord r WHERE r.activityId IN :activityIds AND r.benId = :benId AND r.ashaId = :ashaId AND r.createdDate >= :startOfMonth AND r.createdDate < :startOfNextMonth") + List findExistingActivityIdsByMonth(@Param("activityIds") List activityIds, @Param("benId") Long benId, @Param("ashaId") Integer ashaId, @Param("startOfMonth") Timestamp startOfMonth, @Param("startOfNextMonth") Timestamp startOfNextMonth); + + @Query("SELECT r.benId, r.startDate FROM IncentiveActivityRecord r WHERE r.activityId = :activityId AND r.ashaId = :ashaId") + List findBenIdAndStartDateByActivityIdAndAshaId(@Param("activityId") Long activityId, @Param("ashaId") Integer ashaId); + + @Query("SELECT r FROM IncentiveActivityRecord r WHERE r.ashaId = :ashaId AND r.isClaimed = true AND r.createdDate >= :startDate AND r.createdDate < :endDate") + List findClaimedRecordsByAshaAndCreatedDateRange(@Param("ashaId") Integer ashaId, @Param("startDate") Timestamp startDate, @Param("endDate") Timestamp endDate); + + @Query("SELECT r FROM IncentiveActivityRecord r WHERE r.ashaId = :ashaId AND r.activityId = :activityId AND r.createdDate >= :startDate AND r.createdDate < :endDate") + List findRecordsByAshaAndActivityAndCreatedDateRange(@Param("ashaId") Integer ashaId, @Param("activityId") Long activityId, @Param("startDate") Timestamp startDate, @Param("endDate") Timestamp endDate); + @Query(value = """ SELECT * diff --git a/src/main/java/com/iemr/flw/repo/iemr/IncentivesRepo.java b/src/main/java/com/iemr/flw/repo/iemr/IncentivesRepo.java index d1cbc7f8..10faf62f 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/IncentivesRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/IncentivesRepo.java @@ -45,6 +45,9 @@ IncentiveActivity findIncentiveMasterById( List findByGroupNotAndIsDeleted(String group, Boolean isDeleted); + @Query("SELECT i FROM IncentiveActivity i WHERE i.name IN :names AND i.isDeleted = false") + List findByNamesAndIsDeletedFalse(@Param("names") List names); + // IncentivesRepo — replaces N calls to findIncentiveMasterById() @Query("SELECT i.id FROM IncentiveActivity i WHERE i.id IN :ids AND i.isDeleted = false AND " + "(:isCG = true AND i.group = 'ACTIVITY' OR :isCG = false AND i.group != 'ACTIVITY')") diff --git a/src/main/java/com/iemr/flw/service/DiseaseControlService.java b/src/main/java/com/iemr/flw/service/DiseaseControlService.java index 65e315dc..363dcb5d 100644 --- a/src/main/java/com/iemr/flw/service/DiseaseControlService.java +++ b/src/main/java/com/iemr/flw/service/DiseaseControlService.java @@ -49,4 +49,9 @@ public interface DiseaseControlService { List saveChronicDiseaseVisit(List requestList,String token) throws IEMRException; List getCdtfVisits(GetBenRequestHandler getBenRequestHandler); + + List saveGeneralCheckUp(List generalCheckUpRequest,String token) throws IEMRException; + List saveGeneralCheckUpFollowUp(List generalCheckUpFollowUpDtos,String token) throws IEMRException; + List getGeneralCheckUp(String token); + List getGeneralCheckUpFollowUp(String token); } \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java index 4cbfeb87..40dec067 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -24,6 +24,8 @@ */ package com.iemr.flw.service.impl; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.iemr.flw.domain.identity.RMNCHBeneficiaryDetailsRmnch; import com.iemr.flw.domain.iemr.*; @@ -94,6 +96,15 @@ public class DiseaseControlServiceImpl implements DiseaseControlService { @Autowired private JwtUtil jwtUtil; + private static final DateTimeFormatter VISIT_DATE_FMT = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + + @Autowired + private GeneralCheckUpRepo generalCheckUpRepo; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired private IncentiveLogicService incentiveLogicService; @@ -102,8 +113,9 @@ public class DiseaseControlServiceImpl implements DiseaseControlService { @Autowired private BeneficiaryRepo beneficiaryRepo; - - +@Autowired + private GeneralCheckUpFollowUpRepository + generalCheckUpFollowUpRepository; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Override @@ -1581,4 +1593,351 @@ public List getCdtfVisits(GetBenRequestHandler getBenReq return dtoList; } + @Override + @Transactional + public List saveGeneralCheckUp(List generalCheckUpRequest, String token) throws IEMRException { + + + if (generalCheckUpRequest == null || generalCheckUpRequest.isEmpty()) { + return Collections.emptyList(); + } + + List entities = new ArrayList<>(); + + for (GeneralCheckUpDto dto : generalCheckUpRequest) { + GeneralCheckUpListDto fields = dto.getFields(); + if (fields == null) { + throw new IllegalArgumentException("fields missing for beneficiary " + dto.getBeneficiaryId()); + } + + GeneralCheckUp entity = new GeneralCheckUp(); + entity.setBenId(dto.getBeneficiaryId()); + entity.setHouseholdId(dto.getHouseHoldId()); + entity.setAshaId(jwtUtil.extractUserId(token)); + entity.setCheckupDate(LocalDate.parse(dto.getVisitDate(), VISIT_DATE_FMT)); + entity.setProblemType(fields.getProblemTypeId()); + entity.setProblemTypeLabel(fields.getProblemTypeLabel()); + entity.setPriority(fields.getPriority()); + entity.setOtherText(fields.getOtherText()); + + try { + entity.setProblems(fields.getProblems() != null + ? objectMapper.writeValueAsString(fields.getProblems()) + : null); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Invalid problems payload for checkup " + + fields.getCheckupId(), e); + } + + entity.setReferralReason(fields.getReferralReason()); + entity.setReferralDate(fields.getReferralDate() != null + ? LocalDate.parse(fields.getReferralDate()) + : null); + entity.setCreatedBy(fields.getCreatedBy()); + entity.setSyncedDate(new Timestamp(System.currentTimeMillis())); + + entities.add(entity); + } + + List saved = generalCheckUpRepo.saveAll(entities); + + for (int i = 0; i < saved.size(); i++) { + generalCheckUpRequest.get(i).setId(saved.get(i).getId()); + } + + return generalCheckUpRequest; + } + + + @Override + @Transactional + public List saveGeneralCheckUpFollowUp( + List dtos, + String token) throws IEMRException { + + if (dtos == null || dtos.isEmpty()) { + return Collections.emptyList(); + } + + try { + Integer userId = jwtUtil.extractUserId(token); + String username = jwtUtil.extractUsername(token); + + List result = new ArrayList<>(); + + for (GeneralCheckUpFollowUpDto dto : dtos) { + + if (dto == null || dto.getFields() == null) { + throw new IllegalArgumentException( + "Follow-up details are required"); + } + + if (dto.getBeneficiaryId() == null) { + throw new IllegalArgumentException( + "Beneficiary ID is required"); + } + + // Referral-specific fields + String referralReason = dto.getReferralReason(); + LocalDate referredOnDate = dto.getReferredOnDate(); + + if (referralReason == null || referralReason.isBlank()) { + throw new IllegalArgumentException( + "Referral reason is required"); + } + + if (referredOnDate == null) { + throw new IllegalArgumentException( + "Referral date is required"); + } + + + + LocalDate monthStart = referredOnDate.withDayOfMonth(1); + LocalDate nextMonthStart = monthStart.plusMonths(1); + + GeneralCheckUpFollowUpListDto fields = dto.getFields(); + + String date = fields.getFollowUpDate(); + + if (date == null || date.isBlank()) { + date = dto.getVisitDate(); + } + + if (date == null || date.isBlank()) { + throw new IllegalArgumentException( + "Follow-up date is required"); + } + + LocalDate followUpDate = + LocalDate.parse(date.substring(0, 10)); + + String status = fields.getFollowupStatus(); + + if (status == null || status.isBlank()) { + throw new IllegalArgumentException( + "Follow-up status is required"); + } + + boolean referredToHigherFacility = + "referred_to_higher_facility" + .equalsIgnoreCase(status); + + if (referredToHigherFacility + && (fields.getReferredTo() == null + || fields.getReferredTo().isBlank())) { + throw new IllegalArgumentException( + "Referred-to facility is required"); + } + + + // Find the existing record for this specific referral. + GeneralCheckUpFollowUp entity = + generalCheckUpFollowUpRepository + .findFirstByBenIdAndReferralReasonAndReferredOnDateGreaterThanEqualAndReferredOnDateLessThan( + dto.getBeneficiaryId(), + referralReason, + monthStart, + nextMonthStart) + .orElseGet(GeneralCheckUpFollowUp::new); + + // Insert if no matching record exists; otherwise update it. + entity.setBenId(dto.getBeneficiaryId()); + entity.setHouseholdId(dto.getHouseHoldId()); + + entity.setReferralReason(referralReason); + entity.setReferredOnDate(referredOnDate); + + entity.setFollowUpDate(followUpDate); + entity.setFollowupStatus(status); + + entity.setReferredTo( + referredToHigherFacility + ? fields.getReferredTo() + : null + ); + + if(fields.getOtherFollowUp()!=null){ + entity.setOtherFollowUp(fields.getOtherFollowUp()); + } + entity.setAshaId(userId); + entity.setCreatedBy(username); + entity.setReferredTo(dto.getFields().getReferredTo()); + + GeneralCheckUpFollowUp savedEntity = + generalCheckUpFollowUpRepository.save(entity); + + // Return the saved record with referral information. + GeneralCheckUpFollowUpDto response = + new GeneralCheckUpFollowUpDto(); + + response.setId(savedEntity.getId()); + response.setBeneficiaryId(savedEntity.getBenId()); + response.setHouseHoldId(savedEntity.getHouseholdId()); + + response.setReferralReason(savedEntity.getReferralReason()); + response.setReferredOnDate( + savedEntity.getReferredOnDate() != null + ? savedEntity.getReferredOnDate() + : null + ); + + GeneralCheckUpFollowUpListDto responseFields = + new GeneralCheckUpFollowUpListDto(); + + responseFields.setFollowUpDate( + savedEntity.getFollowUpDate().toString()); + responseFields.setFollowupStatus( + savedEntity.getFollowupStatus()); + responseFields.setReferredTo(savedEntity.getReferredTo()); + + response.setFields(responseFields); + + result.add(response); + } + + return result; + + } catch (Exception e) { + throw new RuntimeException( + "Error saving General Check-up follow-up", e); + } + } + + @Override + @Transactional() + public List getGeneralCheckUpFollowUp( + String token) { + try { + Integer userId = jwtUtil.extractUserId(token); + + List entities = + generalCheckUpFollowUpRepository.findByAshaId(userId); + + return entities.stream() + .map(entity -> { + GeneralCheckUpFollowUpDto dto = + new GeneralCheckUpFollowUpDto(); + + dto.setId(entity.getId()); + dto.setBeneficiaryId(entity.getBenId()); + dto.setHouseHoldId(entity.getHouseholdId()); + dto.setReferralReason(entity.getReferralReason()); + dto.setReferredOnDate(entity.getReferredOnDate()); + + GeneralCheckUpFollowUpListDto fields = + new GeneralCheckUpFollowUpListDto(); + if(entity.getOtherFollowUp()!=null){ + fields.setOtherFollowUp(entity.getOtherFollowUp()); + } + + fields.setFollowUpDate( + entity.getFollowUpDate() != null + ? entity.getFollowUpDate().toString() + : null); + + fields.setFollowupStatus(entity.getFollowupStatus()); + fields.setReferredTo(entity.getReferredTo()); + + + dto.setFields(fields); + + dto.setVisitDate( + entity.getFollowUpDate() != null + ? entity.getFollowUpDate().toString() + : null); + + return dto; + }) + .collect(Collectors.toList()); + } catch (Exception e) { + // Replace with your project's standard IEMRException constructor. + throw new RuntimeException( + "Error saving General Check-up follow-up", e); + } + + } + + @Override + public List getGeneralCheckUp(String token) { + + logger.info("===== getGeneralCheckUp() called ====="); + logger.info("Received token: {}", token); + + Integer userName = null; + try { + userName = jwtUtil.extractUserId(token); + logger.info("Extracted username from token: {}", userName); + } catch (Exception e) { + logger.error("Error while extracting username from token", e); + } + + List rows = null; + try { + rows = generalCheckUpRepo.findByCreatedBy(userRepo.getUserNamedByUserId(userName)); + logger.info("Records fetched from DB for user [{}]: {}", userName, rows != null ? rows.size() : 0); + } catch (Exception e) { + logger.error("Error while fetching GeneralCheckUp records for user: {}", userName, e); + throw e; + } + + List result = new ArrayList<>(); + + if (rows == null || rows.isEmpty()) { + logger.warn("No GeneralCheckUp records found for user: {}", userName); + return result; + } + + for (GeneralCheckUp e : rows) { + logger.debug("Processing GeneralCheckUp id: {}, checkupId: {}", e.getId(), e.getCheckupId()); + + String visitDate = e.getCheckupDate() != null + ? e.getCheckupDate().format(VISIT_DATE_FMT) : null; + + GeneralCheckUpListDto f = new GeneralCheckUpListDto(); + f.setCheck_up_date(visitDate); + f.setProblemType(e.getProblemType()); + f.setOtherText(e.getOtherText()); + f.setCheckupId(e.getId().toString()); + f.setAshaId(e.getAshaId()); + f.setCheckupDate(e.getCheckupDate() != null ? e.getCheckupDate().toString() : null); // "2026-10-22" + f.setProblemTypeId(e.getProblemType()); + f.setProblemTypeLabel(e.getProblemTypeLabel()); + f.setOtherText(e.getOtherText()); + f.setPriority(e.getPriority()); + f.setReferralReason(e.getReferralReason()); + f.setReferralDate(e.getReferralDate() != null ? e.getReferralDate().toString() : null); + f.setCreatedBy(e.getCreatedBy()); + f.setCreatedDate(e.getCreatedDate() != null ? e.getCreatedDate().getTime() : null); + f.setUpdatedDate(e.getUpdatedDate() != null ? e.getUpdatedDate().getTime() : null); + + // json string -> List + try { + if (e.getProblems() != null) { + f.setProblems(objectMapper.readValue( + e.getProblems(), new TypeReference>() {})); + logger.debug("Successfully parsed problems JSON for id: {}", e.getId()); + } else { + logger.debug("Problems field is null for id: {}", e.getId()); + } + } catch (JsonProcessingException ex) { + logger.error("Invalid problems JSON for id: {}. JSON: {}", e.getId(), e.getProblems(), ex); + throw new IllegalStateException("Invalid problems json for id " + e.getId(), ex); + } + + GeneralCheckUpDto dto = new GeneralCheckUpDto(); + dto.setId(e.getId()); + dto.setBeneficiaryId(e.getBenId()); + dto.setHouseHoldId(e.getHouseholdId()); + dto.setVisitDate(visitDate); + dto.setFields(f); + + result.add(dto); + } + + logger.info("===== getGeneralCheckUp() completed successfully. Total records returned: {} =====", result.size()); + + + return result; + } } \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/service/impl/GeneralOpdServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/GeneralOpdServiceImpl.java index 898aa9c6..156fa0b0 100644 --- a/src/main/java/com/iemr/flw/service/impl/GeneralOpdServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/GeneralOpdServiceImpl.java @@ -25,6 +25,7 @@ package com.iemr.flw.service.impl; import com.iemr.flw.domain.identity.*; +import com.iemr.flw.domain.iemr.BenReferDetails; import com.iemr.flw.domain.iemr.GeneralOpdData; import com.iemr.flw.dto.identity.GetBenRequestHandler; import com.iemr.flw.repo.identity.BeneficiaryRepo; @@ -61,34 +62,30 @@ public class GeneralOpdServiceImpl implements GeneralOpdService { @Override public Page getOutreachData(Integer villageId,String userName) { - int page = 0; // always start from 0 int pageSize = 20; - Page result; - - do { - Pageable pageable = PageRequest.of(page, pageSize); - result = generalOpdRepo.findFilteredOutreachData(villageId, pageable,userName); - result.forEach(generalOpdData->{ - if(benReferDetailsRepo.findInstituteNameByBeneficiaryRegID(generalOpdData.getBeneficiaryRegID())!=null){ - generalOpdData.setVisitCategory(benReferDetailsRepo.findInstituteNameByBeneficiaryRegID(generalOpdData.getBeneficiaryRegID())); - - }else { - generalOpdData.setVisitCategory(""); - - } - if(benReferDetailsRepo.findReasonByBeneficiaryRegID(generalOpdData.getBeneficiaryRegID())!=null){ - generalOpdData.setVisitReason(benReferDetailsRepo.findReasonByBeneficiaryRegID(generalOpdData.getBeneficiaryRegID())); - - }else { - generalOpdData.setVisitReason(""); - - } + Pageable pageable = PageRequest.of(0, pageSize); + Page result = generalOpdRepo.findFilteredOutreachData(villageId, pageable, userName); + + List beneficiaryRegIDs = result.getContent().stream() + .map(GeneralOpdData::getBeneficiaryRegID) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + + if (!beneficiaryRegIDs.isEmpty()) { + Map latestReferralByBeneficiary = new HashMap<>(); + benReferDetailsRepo.findLatestByBeneficiaryRegIDs(beneficiaryRegIDs).forEach(referral -> + latestReferralByBeneficiary.putIfAbsent(referral.getBeneficiaryRegID(), referral)); + + result.forEach(generalOpdData -> { + BenReferDetails referral = latestReferralByBeneficiary.get(generalOpdData.getBeneficiaryRegID()); + generalOpdData.setVisitCategory(referral == null || referral.getReferredToInstituteName() == null + ? "" : referral.getReferredToInstituteName()); + generalOpdData.setVisitReason(referral == null || referral.getReferralReason() == null + ? "" : referral.getReferralReason()); }); - - page++; - } while (result.isEmpty() && page < 50); // 50 = safety limit to avoid infinite loop - + } return result; } -} \ No newline at end of file +} diff --git a/src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java index b89cb137..7fa1ef08 100644 --- a/src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/IncentiveServiceImpl.java @@ -199,197 +199,198 @@ public String getIncentiveMaster(IncentiveRequestDTO incentiveRequestDTO) { } return null; } + @Override public String getAllIncentivesByUserId(GetBenRequestHandler request) { - int page = 0; - int size = 200; // bumped from 20 — fewer round trips for large histories - Page pageResult; - List finalDtos = new ArrayList<>(); + Integer ashaId = request.getAshaId(); - // Fetch user detail ONCE instead of twice - UserServiceRoleDTO userDetail = userService.getUserDetail(request.getAshaId()); - Integer stateCode = userDetail.getStateId(); - String userName = userDetail.getUserName(); + // Fetch user stateId and userName in ONE lightweight query instead of heavy getUserDetail() (which builds facilityData) + List userRoles = userRepo.getUserRole(ashaId); + UserServiceRoleDTO userDetail = (userRoles != null && !userRoles.isEmpty()) + ? userRoles.get(0) + : userService.getUserDetail(ashaId); + Integer stateCode = userDetail != null ? userDetail.getStateId() : null; + String userName = userDetail != null ? userDetail.getUserName() : null; try { - if (stateCode.equals(StateCode.AM.getStateCode())) { - checkMonthlyAshaIncentive(request.getAshaId()); - } - if (stateCode.equals(StateCode.CG.getStateCode())) { - checkMonthlyAshaIncentiveForCg(request.getAshaId()); + if (stateCode != null && stateCode.equals(StateCode.AM.getStateCode())) { + checkMonthlyAshaIncentive(ashaId, userName); + } else if (stateCode != null && stateCode.equals(StateCode.CG.getStateCode())) { + checkMonthlyAshaIncentiveForCg(ashaId, userName); } } catch (Exception e) { logger.error("Error in checkMonthlyAshaIncentive: ", e); } try { - addIncentiveForIronTablets(request.getAshaId()); - incentiveOfNcdReferal(request.getAshaId(), request.getVillageID(),request); + addIncentiveForIronTablets(ashaId, userName, stateCode); + Integer effectiveStateId = request.getVillageID() != null ? request.getVillageID() : stateCode; + incentiveOfNcdReferal(ashaId, effectiveStateId, request, userName); } catch (Exception e) { logger.error("Error in incentiveOfNcdReferal: ", e); } boolean isCG = stateCode != null && stateCode.equals(StateCode.CG.getStateCode()); - do { - Pageable pageable = PageRequest.of(page, size, Sort.by("id").descending()); + // Fetch all records for this ASHA in a single query ordered by id DESC (avoids Page COUNT(DISTINCT) + multi-page round trips) + List entities = recordRepo.findRecordsByAshaOrderByIdDesc(ashaId); - pageResult = recordRepo.findRecordsByAsha(request.getAshaId(), pageable); + if (entities.isEmpty()) { + return new Gson().toJson(Collections.emptyList()); + } - List entities = pageResult.getContent(); + // Bulk fetch valid activity ids + List activityIds = entities.stream() + .map(IncentiveActivityRecord::getActivityId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); - if (entities.isEmpty()) { - return new Gson().toJson(Collections.emptyList()); - } + if (activityIds.isEmpty()) { + return new Gson().toJson(Collections.emptyList()); + } - // Bulk fetch valid activity ids - List activityIds = entities.stream() - .map(IncentiveActivityRecord::getActivityId) - .distinct() - .collect(Collectors.toList()); + Set validActivityIds = isCG + ? incentivesRepo.findValidActivityIds(activityIds, true) + : incentivesRepo.findValidActivityIds(activityIds, false); - Set validActivityIds = isCG - ? incentivesRepo.findValidActivityIds(activityIds, true) - : incentivesRepo.findValidActivityIds(activityIds, false); + entities = entities.stream() + .filter(e -> validActivityIds.contains(e.getActivityId())) + .collect(Collectors.toList()); - entities = entities.stream() - .filter(e -> validActivityIds.contains(e.getActivityId())) - .collect(Collectors.toList()); + if (entities.isEmpty()) { + return new Gson().toJson(Collections.emptyList()); + } - // Bulk fetch beneficiary names - List benIdsToFetch = entities.stream() - .filter(e -> e.getName() == null && e.getBenId() != null && e.getBenId() > 0) - .map(IncentiveActivityRecord::getBenId) - .distinct() - .collect(Collectors.toList()); + // Bulk fetch beneficiary names + List benIdsToFetch = entities.stream() + .filter(e -> e.getName() == null && e.getBenId() != null && e.getBenId() > 0) + .map(IncentiveActivityRecord::getBenId) + .distinct() + .collect(Collectors.toList()); - Map benIdToNameMap = new HashMap<>(); - Map regIdToBenIdMap = new HashMap<>(); + Map benIdToNameMap = new HashMap<>(); + Map regIdToBenIdMap = new HashMap<>(); - if (benIdsToFetch != null && !benIdsToFetch.isEmpty()) { + if (!benIdsToFetch.isEmpty()) { - // First, fetch names using BeneficiaryId - List benDetails = - beneficiaryRepo.findBenNamesByBenIds(benIdsToFetch); + // First, fetch names using BeneficiaryId + List benDetails = + beneficiaryRepo.findBenNamesByBenIds(benIdsToFetch); - Set foundBenIds = new HashSet<>(); + Set foundBenIds = new HashSet<>(); - for (Object[] row : benDetails) { - Long benId = ((Number) row[0]).longValue(); + for (Object[] row : benDetails) { + Long benId = ((Number) row[0]).longValue(); - String first = row[1] != null ? row[1].toString() : ""; - String last = row[2] != null ? row[2].toString() : ""; + String first = row[1] != null ? row[1].toString() : ""; + String last = row[2] != null ? row[2].toString() : ""; - benIdToNameMap.put(benId, (first + " " + last).trim()); - foundBenIds.add(benId); - } + benIdToNameMap.put(benId, (first + " " + last).trim()); + foundBenIds.add(benId); + } - // IDs not found as BeneficiaryId - List unresolvedIds = benIdsToFetch.stream() - .filter(Objects::nonNull) - .filter(id -> !foundBenIds.contains(id)) - .distinct() - .toList(); + // IDs not found as BeneficiaryId + List unresolvedIds = benIdsToFetch.stream() + .filter(Objects::nonNull) + .filter(id -> !foundBenIds.contains(id)) + .distinct() + .toList(); - if (!unresolvedIds.isEmpty()) { + if (!unresolvedIds.isEmpty()) { - // Resolve BenRegId -> BeneficiaryId - List mappings = - beneficiaryRepo.getBenIdsFromRegIds(unresolvedIds); + // Resolve BenRegId -> BeneficiaryId + List mappings = + beneficiaryRepo.getBenIdsFromRegIds(unresolvedIds); - Set resolvedBenIds = new HashSet<>(); + Set resolvedBenIds = new HashSet<>(); - for (Object[] row : mappings) { - Long regId = ((Number) row[0]).longValue(); - Long benId = ((Number) row[1]).longValue(); + for (Object[] row : mappings) { + Long regId = ((Number) row[0]).longValue(); + Long benId = ((Number) row[1]).longValue(); - regIdToBenIdMap.put(regId, benId); - resolvedBenIds.add(benId); - } + regIdToBenIdMap.put(regId, benId); + resolvedBenIds.add(benId); + } - // Fetch names for resolved BeneficiaryIds - if (!resolvedBenIds.isEmpty()) { - List resolvedDetails = - beneficiaryRepo.findBenNamesByBenIds( - new ArrayList<>(resolvedBenIds)); + // Fetch names for resolved BeneficiaryIds + if (!resolvedBenIds.isEmpty()) { + List resolvedDetails = + beneficiaryRepo.findBenNamesByBenIds( + new ArrayList<>(resolvedBenIds)); - for (Object[] row : resolvedDetails) { - Long benId = ((Number) row[0]).longValue(); + for (Object[] row : resolvedDetails) { + Long benId = ((Number) row[0]).longValue(); - String first = row[1] != null ? row[1].toString() : ""; - String last = row[2] != null ? row[2].toString() : ""; + String first = row[1] != null ? row[1].toString() : ""; + String last = row[2] != null ? row[2].toString() : ""; - benIdToNameMap.put(benId, (first + " " + last).trim()); - } + benIdToNameMap.put(benId, (first + " " + last).trim()); } } } - // NEW: Bulk fetch verifier (supervisor) roles — replaces N+1 userRepo.getUserRole() calls - // Bulk fetch verifier (supervisor) roles — replaces N+1 userRepo.getUserRole() calls - List verifierIds = entities.stream() - .filter(e -> e.getName() == null && e.getVerifiedByUserId() != null) - .map(e -> e.getVerifiedByUserId().intValue()) // adjust if getVerifiedByUserId() already returns Integer - .distinct() - .collect(Collectors.toList()); + } - Map verifierRoleMap = new HashMap<>(); - if (!verifierIds.isEmpty()) { - List roles = userRepo.getUserRolesByIds(verifierIds); - for (UserServiceRoleDTO r : roles) { - verifierRoleMap.put(r.getUserId(), r); - } - } + // Bulk fetch verifier (supervisor) roles — replaces N+1 userRepo.getUserRole() calls + List verifierIds = entities.stream() + .filter(e -> e.getName() == null && e.getVerifiedByUserId() != null) + .map(IncentiveActivityRecord::getVerifiedByUserId) + .distinct() + .collect(Collectors.toList()); - // Map entities to DTOs - List dtos = entities.stream().map(entry -> { - if (entry.getName() == null) { - Long originalId = entry.getBenId(); + Map verifierRoleMap = new HashMap<>(); + if (!verifierIds.isEmpty()) { + List roles = userRepo.getUserRolesByIds(verifierIds); + for (UserServiceRoleDTO r : roles) { + verifierRoleMap.put(r.getUserId(), r); + } + } - if (originalId != null && originalId > 0) { + // Map entities to DTOs + List finalDtos = entities.stream().map(entry -> { + if (entry.getName() == null) { + Long originalId = entry.getBenId(); - Long actualBenId = regIdToBenIdMap.getOrDefault( - originalId, originalId); + if (originalId != null && originalId > 0) { - String name = benIdToNameMap.getOrDefault(actualBenId, ""); + Long actualBenId = regIdToBenIdMap.getOrDefault( + originalId, originalId); - entry.setBenId(actualBenId); - entry.setName(name); + String name = benIdToNameMap.getOrDefault(actualBenId, ""); - if (isCG) { - entry.setIsEligible(true); - } + entry.setBenId(actualBenId); + entry.setName(name); - } else { - entry.setName(""); + if (isCG) { + entry.setIsEligible(true); } - if (entry.getVerifiedByUserId() != null) { - UserServiceRoleDTO role = verifierRoleMap.get(entry.getVerifiedByUserId()); - if (role != null) { - entry.setSupervisorRole(role.getRoleName()); - entry.setVerifiedByUserName(role.getName()); - } - } + } else { + entry.setName(""); + } - if (entry.getAshaId() != null) { - if (entry.getCreatedBy() == null) { - entry.setCreatedBy(userName); - } - if (entry.getUpdatedBy() == null) { - entry.setUpdatedBy(userName); - } - if (entry.getIsEligible() == null) { - entry.setIsEligible(true); - } + if (entry.getVerifiedByUserId() != null) { + UserServiceRoleDTO role = verifierRoleMap.get(entry.getVerifiedByUserId()); + if (role != null) { + entry.setSupervisorRole(role.getRoleName()); + entry.setVerifiedByUserName(role.getName()); } } - return modelMapper.map(entry, IncentiveRecordDTO.class); - }).collect(Collectors.toList()); - finalDtos.addAll(dtos); - page++; - - } while (pageResult.hasNext()); + if (entry.getAshaId() != null) { + if (entry.getCreatedBy() == null) { + entry.setCreatedBy(userName); + } + if (entry.getUpdatedBy() == null) { + entry.setUpdatedBy(userName); + } + if (entry.getIsEligible() == null) { + entry.setIsEligible(true); + } + } + } + return modelMapper.map(entry, IncentiveRecordDTO.class); + }).collect(Collectors.toList()); Gson gson = new GsonBuilder().setDateFormat("MMM dd, yyyy h:mm:ss a").create(); return gson.toJson(finalDtos); @@ -420,7 +421,10 @@ public void resetRejectedIncentivesForPreviousMonths() { @Transactional(readOnly = true) public String getAllIncentivesGroupedSummary(GetBenRequestHandler request, Integer userId) { - String roleName = userService.getUserDetail(userId).getRoleName(); + List callerRoles = userRepo.getUserRole(userId); + String roleName = (callerRoles != null && !callerRoles.isEmpty()) + ? callerRoles.get(0).getRoleName() + : userService.getUserDetail(userId).getRoleName(); Integer reqStatus = request.getApprovalStatus(); Integer stateId = userRepo.getUserRole(request.getUserId()).get(0).getStateId(); @@ -428,24 +432,30 @@ public String getAllIncentivesGroupedSummary(GetBenRequestHandler request, Integ logger.info("Request getAllIncentivesGroupedSummary: {}", reqStatus); + LocalDate monthStart = LocalDate.of(request.getYear(), request.getMonth(), 1); + Timestamp startTs = Timestamp.valueOf(monthStart.atStartOfDay()); + Timestamp endTs = Timestamp.valueOf(monthStart.plusMonths(1).atStartOfDay()); + + // Filter by date range and isClaimed=true in DB instead of loading all historical records List records = - recordRepo.findRecordsByAsha(request.getUserId()) + recordRepo.findClaimedRecordsByAshaAndCreatedDateRange(request.getUserId(), startTs, endTs) .stream() - .filter(r -> r.getCreatedDate() != null) - .filter(r -> { - LocalDateTime created = r.getCreatedDate().toLocalDateTime(); - return created.getMonthValue() == request.getMonth() - && created.getYear() == request.getYear(); - }) - .filter(r -> Boolean.TRUE.equals(r.getIsClaimed())) .filter(r -> matchesRequestedStatus(r.getApprovalStatus(), reqStatus)) .collect(Collectors.toList()); + if (records.isEmpty()) { + return new Gson().toJson(Collections.emptyList()); + } + List activityIds = records.stream() .map(IncentiveActivityRecord::getActivityId) + .filter(Objects::nonNull) + .distinct() .collect(Collectors.toList()); - Set validActivityIds = incentivesRepo.findValidActivityIds(activityIds, isCG); + Set validActivityIds = activityIds.isEmpty() + ? Collections.emptySet() + : incentivesRepo.findValidActivityIds(activityIds, isCG); if (validActivityIds == null) { validActivityIds = Collections.emptySet(); } @@ -547,6 +557,12 @@ public String getAllIncentivesGroupedSummary(GetBenRequestHandler request, Integ Map> grouped = records.stream().collect(Collectors.groupingBy(IncentiveActivityRecord::getActivityId)); + // Bulk fetch all IncentiveActivity masters in ONE query instead of N findById() calls in loop + Map activityByIdMap = grouped.isEmpty() + ? Collections.emptyMap() + : incentivesRepo.findAllById(grouped.keySet()).stream() + .collect(Collectors.toMap(IncentiveActivity::getId, Function.identity())); + List> result = new ArrayList<>(); for (Map.Entry> entry : grouped.entrySet()) { @@ -554,7 +570,7 @@ public String getAllIncentivesGroupedSummary(GetBenRequestHandler request, Integ Long activityId = entry.getKey(); List list = entry.getValue(); - IncentiveActivity activity = incentivesRepo.findById(activityId).orElse(null); + IncentiveActivity activity = activityByIdMap.get(activityId); if (activity == null) continue; IncentiveActivityRecord latest = list.stream() @@ -648,19 +664,15 @@ public String getAllIncentivesGroupedActivity(GetBenRequestHandler request) { Timestamp startTs = Timestamp.valueOf(startDate.atStartOfDay()); Timestamp endTs = Timestamp.valueOf(endDate.atStartOfDay()); + // Filter by ashaId, activityId, and date range in DB instead of loading all records for the ASHA List records = - recordRepo.findRecordsByAsha(request.getUserId()) - .stream() - .filter(r -> - r.getActivityId() != null - && Objects.equals( - r.getActivityId(), - request.getActivityId() - ) - && r.getCreatedDate() != null - && !r.getCreatedDate().before(startTs) - && r.getCreatedDate().before(endTs) + recordRepo.findRecordsByAshaAndActivityAndCreatedDateRange( + request.getUserId(), + request.getActivityId(), + startTs, + endTs ) + .stream() .filter(r -> { Integer requestedStatus = @@ -743,7 +755,9 @@ public String getAllIncentivesGroupedActivity(GetBenRequestHandler request) { incentivesRepo.findById(request.getActivityId()).orElse(null); String groupName = activity != null ? activity.getGroup() : ""; - String groupCategoryName = activity != null ? activity.getGroupCategoryName() :activity.getGroup(); + String groupCategoryName = activity != null + ? (activity.getGroupCategoryName() != null ? activity.getGroupCategoryName() : activity.getGroup()) + : ""; String description = activity != null ? activity.getDescription() : ""; // 🔹 Map result @@ -888,11 +902,13 @@ public String updateClaimStatus(Integer ashaId, Integer month, Integer year, Boo if (updated > 0) { + Integer supervisorUserId = dashboardRepo.getSupervisorUserIdByAshaId(ashaId); + Map data = new HashMap<>(); data.put("notification_type", "INCENTIVE_APPROVAL"); data.put("nav_id", "INCENTIVE_HISTORY"); data.put("sender_user_id", String.valueOf(ashaId)); - data.put("receiver_user_id", String.valueOf(dashboardRepo.getSupervisorUserIdByAshaId(ashaId))); + data.put("receiver_user_id", String.valueOf(supervisorUserId)); data.put("month", String.valueOf(month)); data.put("year", String.valueOf(year)); data.put("approval_status", String.valueOf(102)); @@ -912,11 +928,16 @@ public String updateClaimStatus(Integer ashaId, Integer month, Integer year, Boo body, "INCENTIVE_CLAIMED", "INCENTIVE", - dashboardRepo.getSupervisorUserIdByAshaId(ashaId) + supervisorUserId ); + List ashaRoles = userRepo.getUserRole(ashaId); + String ashaName = (ashaRoles != null && !ashaRoles.isEmpty()) + ? ashaRoles.get(0).getName() + : userService.getUserDetail(ashaId).getName(); + String supervisorBody = - userService.getUserDetail(ashaId).getName() + ashaName + " successfully claimed incentive for month of " + Month.of(month).name() + " " @@ -929,7 +950,7 @@ public String updateClaimStatus(Integer ashaId, Integer month, Integer year, Boo supervisorBody, "INCENTIVE_CLAIMED", "INCENTIVE", - dashboardRepo.getSupervisorUserIdByAshaId(ashaId) + supervisorUserId ); } } @@ -942,69 +963,125 @@ public String updateClaimStatus(Integer ashaId, Integer month, Integer year, Boo } } - private void incentiveOfNcdReferal(Integer ashaId, Integer stateId, GetBenRequestHandler request) { + private void incentiveOfNcdReferal(Integer ashaId, Integer stateId, GetBenRequestHandler request, String userName) { try { - String userName = userRepo.getUserNamedByUserId(ashaId); + if (userName == null) { + userName = userRepo.getUserNamedByUserId(ashaId); + } + if (userName == null) { + return; + } String groupName = resolveGroupName(stateId); Map activityMap = incentivesRepo.findIncentiveMasterByNameAndGroup( List.of("NCD_POP_ENUMERATION", "HWC_REFERRAL_10_CASES"), groupName - ).stream().collect(Collectors.toMap(IncentiveActivity::getName, Function.identity())); + ).stream().collect(Collectors.toMap(IncentiveActivity::getName, Function.identity(), (a, b) -> a)); IncentiveActivity ncdPopEnumeration = activityMap.get("NCD_POP_ENUMERATION"); - IncentiveActivity hwcReferralEnumeration = activityMap.get("HWC_REFERRAL_10_CASES"); - CompletableFuture> benReferFuture = - CompletableFuture.supplyAsync(() -> benReferDetailsRepo.findByCreatedBy(userName)); - CompletableFuture> cbacFuture = - CompletableFuture.supplyAsync(() -> cbacIemrDetailsRepo.findByCreatedBy(userName)); - - List cbacDetailsImer = cbacFuture.get(); - - List recordsToSave = new ArrayList<>(); - + // 1. Optimize NCD_POP_ENUMERATION: fetch only (beneficiaryRegId, createdDate) instead of all 65 columns, + // check existing records in 1 bulk query instead of N individual queries, and batch insert. + if (ncdPopEnumeration != null) { + List cbacRows = cbacIemrDetailsRepo.findBenRegIdAndCreatedDateByCreatedBy(userName); + if (cbacRows != null && !cbacRows.isEmpty()) { + List existingRows = recordRepo.findBenIdAndStartDateByActivityIdAndAshaId( + ncdPopEnumeration.getId(), ashaId); + Set existingMonthKeys = new HashSet<>(); + if (existingRows != null) { + for (Object[] row : existingRows) { + Long existingBenId = row[0] != null ? ((Number) row[0]).longValue() : null; + Timestamp existingStart = (Timestamp) row[1]; + if (existingBenId != null && existingStart != null) { + LocalDateTime ldt = existingStart.toLocalDateTime(); + existingMonthKeys.add(existingBenId + "_" + ldt.getYear() + "_" + ldt.getMonthValue()); + } + } + } - if (ncdPopEnumeration != null && !cbacDetailsImer.isEmpty()) { + Timestamp nowTs = Timestamp.valueOf(LocalDateTime.now()); + Long rate = Long.valueOf(ncdPopEnumeration.getRate()); + List recordsToSave = new ArrayList<>(); + + for (Object[] cbacRow : cbacRows) { + if (cbacRow == null || cbacRow[0] == null || cbacRow[1] == null) continue; + Long benId = ((Number) cbacRow[0]).longValue(); + Timestamp createdDate = (Timestamp) cbacRow[1]; + LocalDateTime ldt = createdDate.toLocalDateTime(); + String monthKey = benId + "_" + ldt.getYear() + "_" + ldt.getMonthValue(); + + if (existingMonthKeys.add(monthKey)) { + IncentiveActivityRecord record = new IncentiveActivityRecord(); + record.setActivityId(ncdPopEnumeration.getId()); + record.setCreatedDate(createdDate); + record.setCreatedBy(userName); + record.setStartDate(createdDate); + record.setEndDate(createdDate); + record.setUpdatedDate(nowTs); + record.setUpdatedBy(userName); + record.setBenId(benId); + record.setAshaId(ashaId); + record.setAmount(rate); + recordsToSave.add(record); + } + } - final IncentiveActivity activity = ncdPopEnumeration; - cbacDetailsImer.forEach(cbacDetailsImer1 -> { - if(cbacDetailsImer1!=null){ - addNCDandCBACIncentiveRecord(activity, ashaId, cbacDetailsImer1.getBeneficiaryRegId(), cbacDetailsImer1.getCreatedDate(), userName); + if (!recordsToSave.isEmpty()) { + recordRepo.saveAll(recordsToSave); } - }); + } } + // 2. Optimize HWC_REFERRAL_10_CASES: check if monthly incentive already exists FIRST, + // and use index-friendly date range query instead of MONTH()/YEAR() functions. if (hwcReferralEnumeration != null) { - logger.info("hwcReferralEnumeration: {}", hwcReferralEnumeration.getDescription()); - logger.info("userName={}", userName); - - LocalDate requestDate = request.getFromDate() - .toInstant() - .atZone(ZoneId.systemDefault()) - .toLocalDate(); - - Long referralCount = benReferDetailsRepo.countMonthlyReferrals( - userName, - requestDate.getMonthValue(), - requestDate.getYear() - ); + LocalDate now = LocalDate.now(); + Timestamp startOfMonth = Timestamp.valueOf(now.withDayOfMonth(1).atStartOfDay()); + Timestamp endOfMonth = Timestamp.valueOf(now.withDayOfMonth(now.lengthOfMonth()).atTime(23, 59, 59)); - logger.info("referralCount: {}", referralCount); + IncentiveActivityRecord existingHwcRecord = recordRepo.findRecordByActivityIdCreatedDateBenId( + hwcReferralEnumeration.getId(), + 0L, + ashaId, + startOfMonth, + endOfMonth + ); - if (referralCount >= 10) { - addHwcReferalAshaIncentiveRecord( - hwcReferralEnumeration, - ashaId, - userName + if (existingHwcRecord == null) { + LocalDate requestDate = (request != null && request.getFromDate() != null) + ? request.getFromDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate() + : now; + LocalDate reqMonthFirst = requestDate.withDayOfMonth(1); + Timestamp reqStart = Timestamp.valueOf(reqMonthFirst.atStartOfDay()); + Timestamp reqEnd = Timestamp.valueOf(reqMonthFirst.plusMonths(1).atStartOfDay()); + + Long referralCount = benReferDetailsRepo.countMonthlyReferralsByDateRange( + userName, + reqStart, + reqEnd ); - } - } - // ---- Single batch insert instead of N individual saves ---- - if (!recordsToSave.isEmpty()) { - recordRepo.saveAll(recordsToSave); + logger.info("referralCount: {}", referralCount); + + if (referralCount != null && referralCount >= 10) { + Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now()); + IncentiveActivityRecord record = new IncentiveActivityRecord(); + record.setActivityId(hwcReferralEnumeration.getId()); + record.setCreatedDate(timestamp); + record.setCreatedBy(userName); + record.setStartDate(timestamp); + record.setEndDate(timestamp); + record.setUpdatedDate(timestamp); + record.setUpdatedBy(userName); + record.setBenId(0L); + record.setAshaId(ashaId); + record.setIsEligible(true); + record.setIsDefaultActivity(false); + record.setAmount(Long.valueOf(hwcReferralEnumeration.getRate())); + recordRepo.save(record); + } + } } } catch (Exception e) { @@ -1012,39 +1089,8 @@ private void incentiveOfNcdReferal(Integer ashaId, Integer stateId, GetBenReques } } - // Helper — record banana - private void addNCDandCBACIncentiveRecord(IncentiveActivity activity, Integer ashaId, - Long benId, Timestamp createdDate, String userName) { - - String lockKey = activity.getId() + "_" + benId + "_" + createdDate; - - Object lock = lockMap.computeIfAbsent(lockKey, k -> new Object()); - synchronized (lock){ - IncentiveActivityRecord incentiveActivityRecord = recordRepo.findRecordByActivityIdCreatedDateBenId(activity.getId(),createdDate,benId,ashaId); - if(incentiveActivityRecord==null){ - Timestamp now = Timestamp.valueOf(LocalDateTime.now()); - IncentiveActivityRecord record = new IncentiveActivityRecord(); - record.setActivityId(activity.getId()); - record.setCreatedDate(createdDate); - record.setCreatedBy(userName); - record.setStartDate(createdDate); - record.setEndDate(createdDate); - record.setUpdatedDate(now); - record.setUpdatedBy(userName); - record.setBenId(benId); - record.setAshaId(ashaId); - record.setAmount(Long.valueOf(activity.getRate())); - recordRepo.save(record); - } - lockMap.remove(lockKey, lock); - - } - - - } - private String resolveGroupName(Integer stateId) { - if (stateId.equals(StateCode.CG.getStateCode())) { + if (stateId != null && stateId.equals(StateCode.CG.getStateCode())) { logger.info("State id: {}", StateCode.CG.getStateCode()); return GroupName.ACTIVITY.getDisplayName(); } @@ -1052,198 +1098,159 @@ private String resolveGroupName(Integer stateId) { return GroupName.NCD.getDisplayName(); } - private void checkMonthlyAshaIncentive(Integer ashaId) { - + private void checkMonthlyAshaIncentive(Integer ashaId, String userName) { try { - String userName = userRepo.getUserNamedByUserId(ashaId); - - IncentiveActivity MOBILEBILLREIMB_ACTIVITY = incentivesRepo.findIncentiveMasterByNameAndGroup("MOBILE_BILL_REIMB", GroupName.OTHER_INCENTIVES.getDisplayName()); - IncentiveActivity ADDITIONAL_ASHA_INCENTIVE = incentivesRepo.findIncentiveMasterByNameAndGroup("ADDITIONAL_ASHA_INCENTIVE", GroupName.ADDITIONAL_INCENTIVE.getDisplayName()); - IncentiveActivity ASHA_MONTHLY_ROUTINE = incentivesRepo.findIncentiveMasterByNameAndGroup("ASHA_MONTHLY_ROUTINE", GroupName.ASHA_MONTHLY_ROUTINE.getDisplayName()); - if (MOBILEBILLREIMB_ACTIVITY != null) { - addMonthlyAshaIncentiveRecord(MOBILEBILLREIMB_ACTIVITY, ashaId, userName,false); - } - if (ADDITIONAL_ASHA_INCENTIVE != null) { - addMonthlyAshaIncentiveRecord(ADDITIONAL_ASHA_INCENTIVE, ashaId, userName,false); - + if (userName == null) { + userName = userRepo.getUserNamedByUserId(ashaId); } - - if (ASHA_MONTHLY_ROUTINE != null) { - addMonthlyAshaIncentiveRecord(ASHA_MONTHLY_ROUTINE, ashaId, userName,false); - + List candidates = incentivesRepo.findByNamesAndIsDeletedFalse( + List.of("MOBILE_BILL_REIMB", "ADDITIONAL_ASHA_INCENTIVE", "ASHA_MONTHLY_ROUTINE") + ); + List validActivities = new ArrayList<>(); + for (IncentiveActivity act : candidates) { + if (("MOBILE_BILL_REIMB".equals(act.getName()) && GroupName.OTHER_INCENTIVES.getDisplayName().equals(act.getGroup())) + || ("ADDITIONAL_ASHA_INCENTIVE".equals(act.getName()) && GroupName.ADDITIONAL_INCENTIVE.getDisplayName().equals(act.getGroup())) + || ("ASHA_MONTHLY_ROUTINE".equals(act.getName()) && GroupName.ASHA_MONTHLY_ROUTINE.getDisplayName().equals(act.getGroup()))) { + validActivities.add(act); + } } + addMonthlyAshaIncentiveRecordsBatch(validActivities, ashaId, userName, Collections.emptySet()); } catch (Exception e) { - logger.error("Error in addMonthlyAshaIncentiveRecord", e); - + logger.error("Error in checkMonthlyAshaIncentive", e); } - } - private void checkMonthlyAshaIncentiveForCg(Integer ashaId) { + private void checkMonthlyAshaIncentiveForCg(Integer ashaId, String userName) { try { - String userName = userRepo.getUserNamedByUserId(ashaId); - - IncentiveActivity MONTHLY_HONORARIUM = incentivesRepo.findIncentiveMasterByNameAndGroup("MONTHLY_HONORARIUM", GroupName.ACTIVITY.getDisplayName()); - IncentiveActivity MITANIN_REGISTER_5_INFO_FILL = incentivesRepo.findIncentiveMasterByNameAndGroup("MITANIN_REGISTER_5_INFO_FILL", GroupName.ACTIVITY.getDisplayName()); - IncentiveActivity MITANIN_REGISTER = incentivesRepo.findIncentiveMasterByNameAndGroup("MITANIN_REGISTER", GroupName.ACTIVITY.getDisplayName()); - if (MONTHLY_HONORARIUM != null) { - addMonthlyAshaIncentiveRecord(MONTHLY_HONORARIUM, ashaId, userName,true); - } - if (MITANIN_REGISTER_5_INFO_FILL != null) { - addMonthlyAshaIncentiveRecord(MITANIN_REGISTER_5_INFO_FILL, ashaId, userName,false); - - } - - if (MITANIN_REGISTER != null) { - addMonthlyAshaIncentiveRecord(MITANIN_REGISTER, ashaId, userName,false); - + if (userName == null) { + userName = userRepo.getUserNamedByUserId(ashaId); } + List validActivities = incentivesRepo.findIncentiveMasterByNameAndGroup( + List.of("MONTHLY_HONORARIUM", "MITANIN_REGISTER_5_INFO_FILL", "MITANIN_REGISTER"), + GroupName.ACTIVITY.getDisplayName() + ); + addMonthlyAshaIncentiveRecordsBatch(validActivities, ashaId, userName, Set.of("MONTHLY_HONORARIUM")); } catch (Exception e) { - logger.error("Error in addMonthlyAshaIncentiveRecord", e); - + logger.error("Error in checkMonthlyAshaIncentiveForCg", e); } - } - private void addMonthlyAshaIncentiveRecord(IncentiveActivity incentiveActivity, Integer ashaId, String userName,Boolean isApproved) { + private void addMonthlyAshaIncentiveRecordsBatch( + List activities, + Integer ashaId, + String userName, + Set preApprovedNames) { + if (activities == null || activities.isEmpty()) { + return; + } try { + LocalDate now = LocalDate.now(); Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now()); + Timestamp startOfMonth = Timestamp.valueOf(now.withDayOfMonth(1).atStartOfDay()); + Timestamp endOfMonth = Timestamp.valueOf(now.withDayOfMonth(now.lengthOfMonth()).atTime(23, 59, 59)); - Timestamp startOfMonth = Timestamp.valueOf(LocalDate.now().withDayOfMonth(1).atStartOfDay()); - Timestamp endOfMonth = Timestamp.valueOf(LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).atTime(23, 59, 59)); - - IncentiveActivityRecord record = recordRepo.findRecordByActivityIdCreatedDateBenId( - incentiveActivity.getId(), - 0L, - ashaId, - startOfMonth, - endOfMonth - ); - + List activityIds = activities.stream() + .map(IncentiveActivity::getId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); - if (record == null) { - record = new IncentiveActivityRecord(); - record.setActivityId(incentiveActivity.getId()); - record.setCreatedDate(timestamp); - record.setCreatedBy(userName); - record.setStartDate(timestamp); - record.setEndDate(timestamp); - record.setUpdatedDate(timestamp); - record.setUpdatedBy(userName); - record.setBenId(0L); - record.setAshaId(ashaId); - record.setIsEligible(true); - record.setIsDefaultActivity(true); - record.setIsApproved(isApproved); - record.setAmount(Long.valueOf(incentiveActivity.getRate())); - recordRepo.save(record); + if (activityIds.isEmpty()) { + return; } - } catch (Exception e) { - logger.error("Error in addMonthlyAshaIncentiveRecord", e); - - } - } - - private void addHwcReferalAshaIncentiveRecord(IncentiveActivity incentiveActivity, Integer ashaId, String userName) { - try { - Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now()); - - Timestamp startOfMonth = Timestamp.valueOf(LocalDate.now().withDayOfMonth(1).atStartOfDay()); - Timestamp endOfMonth = Timestamp.valueOf(LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).atTime(23, 59, 59)); - - IncentiveActivityRecord record = recordRepo.findRecordByActivityIdCreatedDateBenId( - incentiveActivity.getId(), - 0L, - ashaId, - startOfMonth, - endOfMonth + Set existingIds = new HashSet<>( + recordRepo.findExistingActivityIdsByMonth(activityIds, 0L, ashaId, startOfMonth, endOfMonth) ); + List newRecords = new ArrayList<>(); + for (IncentiveActivity activity : activities) { + if (activity != null && !existingIds.contains(activity.getId())) { + IncentiveActivityRecord record = new IncentiveActivityRecord(); + record.setActivityId(activity.getId()); + record.setCreatedDate(timestamp); + record.setCreatedBy(userName); + record.setStartDate(timestamp); + record.setEndDate(timestamp); + record.setUpdatedDate(timestamp); + record.setUpdatedBy(userName); + record.setBenId(0L); + record.setAshaId(ashaId); + record.setIsEligible(true); + record.setIsDefaultActivity(true); + record.setIsApproved(preApprovedNames != null && preApprovedNames.contains(activity.getName())); + record.setAmount(Long.valueOf(activity.getRate())); + newRecords.add(record); + } + } - if (record == null) { - record = new IncentiveActivityRecord(); - record.setActivityId(incentiveActivity.getId()); - record.setCreatedDate(timestamp); - record.setCreatedBy(userName); - record.setStartDate(timestamp); - record.setEndDate(timestamp); - record.setUpdatedDate(timestamp); - record.setUpdatedBy(userName); - record.setBenId(0L); - record.setAshaId(ashaId); - record.setIsEligible(true); - record.setIsDefaultActivity(false); - record.setAmount(Long.valueOf(incentiveActivity.getRate())); - recordRepo.save(record); + if (!newRecords.isEmpty()) { + recordRepo.saveAll(newRecords); } } catch (Exception e) { - logger.error("Error in addMonthlyAshaIncentiveRecord", e); - + logger.error("Error in addMonthlyAshaIncentiveRecordsBatch", e); } - } - private void addIncentiveForIronTablets(Integer userId) { - IncentiveActivity incentiveActivityAM = incentivesRepo.findIncentiveMasterByNameAndGroup("NATIONAL_IRON_PLUS", GroupName.CHILD_HEALTH.getDisplayName()); - IncentiveActivity incentiveActivityCG = incentivesRepo.findIncentiveMasterByNameAndGroup("NATIONAL_IRON_PLUS", GroupName.ACTIVITY.getDisplayName()); - - String userName = userService.getUserDetail(userId).getUserName(); - Integer stateId = userService.getUserDetail(userId).getStateId(); - if (userName != null) { - List eligibleCoupleRegisters = eligibleCoupleRegisterRepo.findByCreatedBy(userName); - List ifaFormSubmissionData = ifaFormSubmissionRepository.findByUserId(userId); - logger.info("eligibleCoupleRegisters :" + eligibleCoupleRegisters.size()); - logger.info("ifaFormSubmissionData :" + ifaFormSubmissionData.size()); - - if (!eligibleCoupleRegisters.isEmpty() && !ifaFormSubmissionData.isEmpty()) { - - int percentage = (int) (((double) ifaFormSubmissionData.size() - / eligibleCoupleRegisters.size()) * 100); - - logger.info("IFA Count : {}", ifaFormSubmissionData.size()); - logger.info("Eligible Couple Count : {}", eligibleCoupleRegisters.size()); - logger.info("Percentage : {}", percentage); + private void addIncentiveForIronTablets(Integer userId, String userName, Integer stateId) { + if (userName == null || stateId == null) { + return; + } - if (percentage >= 50) { + IncentiveActivity targetActivity = null; + if (stateId.equals(StateCode.AM.getStateCode())) { + targetActivity = incentivesRepo.findIncentiveMasterByNameAndGroup("NATIONAL_IRON_PLUS", GroupName.CHILD_HEALTH.getDisplayName()); + } else if (stateId.equals(StateCode.CG.getStateCode())) { + targetActivity = incentivesRepo.findIncentiveMasterByNameAndGroup("NATIONAL_IRON_PLUS", GroupName.ACTIVITY.getDisplayName()); + } - if (stateId.equals(StateCode.AM.getStateCode())) { - addIFAIncentive( - ifaFormSubmissionData.get(ifaFormSubmissionData.size() - 1), - incentiveActivityAM, - userId, - userName); - } + if (targetActivity == null) { + return; + } - if (stateId.equals(StateCode.CG.getStateCode())) { - addIFAIncentive( - ifaFormSubmissionData.get(ifaFormSubmissionData.size() - 1), - incentiveActivityCG, - userId, - userName); - } - } - } + LocalDate now = LocalDate.now(); + Timestamp startOfMonth = Timestamp.valueOf(now.withDayOfMonth(1).atStartOfDay()); + Timestamp endOfMonth = Timestamp.valueOf(now.withDayOfMonth(now.lengthOfMonth()).atTime(23, 59, 59)); + + // Check if IFA incentive record already exists for this month BEFORE querying EC & IFA tables + IncentiveActivityRecord existingRecord = recordRepo.findRecordByActivityIdCreatedDateBenId( + targetActivity.getId(), + 0L, + userId, + startOfMonth, + endOfMonth + ); + if (existingRecord != null) { + return; + } + // Use COUNT(*) queries instead of loading full entities (and LONGTEXT photos) into memory + long ecCount = eligibleCoupleRegisterRepo.countByCreatedBy(userName); + if (ecCount <= 0) { + return; + } + long ifaCount = ifaFormSubmissionRepository.countByUserId(userId); + if (ifaCount <= 0) { + return; } + int percentage = (int) (((double) ifaCount / ecCount) * 100); + logger.info("IFA Count : {}, Eligible Couple Count : {}, Percentage : {}", ifaCount, ecCount, percentage); + if (percentage >= 50) { + addIFAIncentive(targetActivity, userId, userName, startOfMonth, endOfMonth); + } } - private void addIFAIncentive(IFAFormSubmissionData ifaFormSubmissionData, IncentiveActivity incentiveActivityAM, Integer userId, String userName) { - Timestamp startOfMonth = Timestamp.valueOf(LocalDate.now().withDayOfMonth(1).atStartOfDay()); - Timestamp endOfMonth = Timestamp.valueOf(LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).atTime(23, 59, 59)); - - String lockKey = incentiveActivityAM.getId() + "_" + 0 + "_" + startOfMonth; - + private void addIFAIncentive(IncentiveActivity incentiveActivity, Integer userId, String userName, + Timestamp startOfMonth, Timestamp endOfMonth) { + String lockKey = incentiveActivity.getId() + "_" + 0 + "_" + startOfMonth; Object lock = lockMap.computeIfAbsent(lockKey, k -> new Object()); Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now()); - logger.info("IFA incentive"); - synchronized (lock){ + synchronized (lock) { IncentiveActivityRecord incentiveActivityRecord = recordRepo.findRecordByActivityIdCreatedDateBenId( - incentiveActivityAM.getId(), + incentiveActivity.getId(), 0L, userId, startOfMonth, @@ -1251,26 +1258,21 @@ private void addIFAIncentive(IFAFormSubmissionData ifaFormSubmissionData, Incent ); if (incentiveActivityRecord == null) { incentiveActivityRecord = new IncentiveActivityRecord(); - incentiveActivityRecord.setActivityId(incentiveActivityAM.getId()); + incentiveActivityRecord.setActivityId(incentiveActivity.getId()); incentiveActivityRecord.setCreatedDate(timestamp); incentiveActivityRecord.setStartDate(timestamp); incentiveActivityRecord.setEndDate(timestamp); incentiveActivityRecord.setUpdatedDate(timestamp); - incentiveActivityRecord.setUpdatedBy(ifaFormSubmissionData.getUserName()); - incentiveActivityRecord.setCreatedBy(ifaFormSubmissionData.getUserName()); + incentiveActivityRecord.setUpdatedBy(userName); + incentiveActivityRecord.setCreatedBy(userName); incentiveActivityRecord.setBenId(0L); incentiveActivityRecord.setAshaId(userId); - incentiveActivityRecord.setAmount(Long.valueOf(incentiveActivityAM.getRate())); + incentiveActivityRecord.setAmount(Long.valueOf(incentiveActivity.getRate())); recordRepo.save(incentiveActivityRecord); logger.info("saved IFA incentive"); - } - } lockMap.remove(lockKey, lock); - - } - }