From 18b0c3b7ecddec27e76bd0e3f867d8219f78f0a9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Mon, 19 Oct 2026 15:16:13 +0530 Subject: [PATCH 01/21] general checkup --- .../controller/DiseaseControlController.java | 60 +++++++++++++++++ .../iemr/flw/domain/iemr/GeneralCheckUp.java | 65 +++++++++++++++++++ .../iemr/flw/dto/iemr/GeneralCheckUpDto.java | 9 +++ .../flw/dto/iemr/GeneralCheckUpListDto.java | 9 +++ 4 files changed, 143 insertions(+) create mode 100644 src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java create mode 100644 src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java create mode 100644 src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index 764ebeaf6..0c0e0f9a4 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -375,4 +375,64 @@ public ResponseEntity> getVisitDetails( } + @RequestMapping(value = "generalCheckUp/getAll", method = RequestMethod.POST) + public ResponseEntity> getGeneralCheckUp( + @RequestBody GetBenRequestHandler getBenRequestHandler) { + + Map response = new LinkedHashMap<>(); + + try { + List result = + diseaseControlService.getCdtfVisits(getBenRequestHandler); + + 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("Chronic Disease Visit Save Request: {}", requestList); + + try { + List savedList = + diseaseControlService.saveChronicDiseaseVisit(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 000000000..3f80c7c78 --- /dev/null +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java @@ -0,0 +1,65 @@ +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 Long 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 = "other_text", length = 250) + 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/dto/iemr/GeneralCheckUpDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java new file mode 100644 index 000000000..a86f56201 --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java @@ -0,0 +1,9 @@ +package com.iemr.flw.dto.iemr; + +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/GeneralCheckUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java new file mode 100644 index 000000000..a1e489bae --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java @@ -0,0 +1,9 @@ +package com.iemr.flw.dto.iemr; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class GeneralCheckUpListDto { + @JsonProperty("check_up_date") + private String CheckUpDate; + +} From 3eddc565a95a5ddc4313af7198b7a2e58aa52bd2 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 17:19:15 +0530 Subject: [PATCH 02/21] general checkup save get api --- .../flw/controller/DiseaseControlController.java | 16 +++++++++------- .../com/iemr/flw/domain/iemr/GeneralCheckUp.java | 5 ----- .../iemr/flw/service/DiseaseControlService.java | 3 +++ .../service/impl/DiseaseControlServiceImpl.java | 10 ++++++++++ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index 0c0e0f9a4..9b23a9b90 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -377,13 +377,13 @@ 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.getCdtfVisits(getBenRequestHandler); + List result = + diseaseControlService.getGeneralCheckUp(token); if (result != null && !result.isEmpty()) { response.put("statusCode", HttpStatus.OK.value()); @@ -406,14 +406,16 @@ public ResponseEntity> getGeneralCheckUp( @RequestMapping(value = "generalCheckUp/saveAll", method = RequestMethod.POST) public ResponseEntity> savGeneralCheckUp( - @RequestBody List requestList,@RequestHeader(value = "JwtToken") String token) { + @RequestBody List requestList,@RequestHeader(value = "JwtToken") String token) { Map response = new LinkedHashMap<>(); - logger.info("Chronic Disease Visit Save Request: {}", requestList); + logger.info("####################################################"); + logger.info("General checkup Disease Visit Save Request: {}", requestList); + logger.info("####################################################"); try { - List savedList = - diseaseControlService.saveChronicDiseaseVisit(requestList,token); + List savedList = + diseaseControlService.saveGeneralCheckUp(requestList,token); if (savedList != null && !savedList.isEmpty()) { response.put("statusCode", HttpStatus.OK.value()); diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java index 3f80c7c78..66390ccbc 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java @@ -39,11 +39,6 @@ public class GeneralCheckUp { @Column(name = "problems", columnDefinition = "json") private String problems; - @Column(name = "other_text", length = 250) - private String otherText; - - @Column(name = "priority", length = 20) - private String priority; @Column(name = "referral_reason", length = 500) private String referralReason; diff --git a/src/main/java/com/iemr/flw/service/DiseaseControlService.java b/src/main/java/com/iemr/flw/service/DiseaseControlService.java index 65e315dce..c7db39869 100644 --- a/src/main/java/com/iemr/flw/service/DiseaseControlService.java +++ b/src/main/java/com/iemr/flw/service/DiseaseControlService.java @@ -49,4 +49,7 @@ public interface DiseaseControlService { List saveChronicDiseaseVisit(List requestList,String token) throws IEMRException; List getCdtfVisits(GetBenRequestHandler getBenRequestHandler); + + List saveGeneralCheckUp(List generalCheckUpRequest,String token); + List getGeneralCheckUp(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 4cbfeb874..988b6da62 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1581,4 +1581,14 @@ public List getCdtfVisits(GetBenRequestHandler getBenReq return dtoList; } + @Override + public List saveGeneralCheckUp(List generalCheckUpRequest, String token) { + + return null; + } + + @Override + public List getGeneralCheckUp(String token) { + return null; + } } \ No newline at end of file From a06bc279c93d5437e630795678972bcedc00948b Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 17:29:30 +0530 Subject: [PATCH 03/21] general checkup save get api --- .../iemr/flw/controller/DiseaseControlController.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index 9b23a9b90..32afa2eab 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) { @@ -410,7 +413,13 @@ public ResponseEntity> savGeneralCheckUp( Map response = new LinkedHashMap<>(); logger.info("####################################################"); - logger.info("General checkup Disease Visit Save Request: {}", requestList); + 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 { From 894da33a1e9fccf9f09d4cf4339b1c360502d668 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 17:40:47 +0530 Subject: [PATCH 04/21] general checkup save get api --- .../iemr/flw/dto/iemr/GeneralCheckUpDto.java | 3 ++ .../flw/dto/iemr/GeneralCheckUpListDto.java | 44 ++++++++++++++++++- .../com/iemr/flw/dto/iemr/ProblemDto.java | 11 +++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/iemr/flw/dto/iemr/ProblemDto.java diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java index a86f56201..da0594c3a 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpDto.java @@ -1,5 +1,8 @@ package com.iemr.flw.dto.iemr; +import lombok.Data; + +@Data public class GeneralCheckUpDto { private Long id; private Long beneficiaryId; diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java index a1e489bae..0cf45ab25 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java @@ -1,9 +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 CheckUpDate; + private String checkUpDate; + + @JsonProperty("problem_type") + private String problemType; + + @JsonProperty("problems_g6") + private String problemsG6; + + @JsonProperty("other_text") + private String otherTextLegacy; + + private String checkupId; + + private Long 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 000000000..44de6eabd --- /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 From 82a91970c38516bf657d696e995e627f0dc412d6 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 17:58:15 +0530 Subject: [PATCH 05/21] update response --- .../iemr/flw/domain/iemr/GeneralCheckUp.java | 15 ++- .../flw/dto/iemr/GeneralCheckUpListDto.java | 2 +- .../flw/repo/iemr/GeneralCheckUpRepo.java | 12 ++ .../flw/service/DiseaseControlService.java | 2 +- .../impl/DiseaseControlServiceImpl.java | 110 +++++++++++++++++- 5 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java index 66390ccbc..f3d84c52a 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java @@ -28,7 +28,7 @@ public class GeneralCheckUp { private Long householdId; @Column(name = "asha_id", nullable = false) - private Long ashaId; + private Integer ashaId; @Column(name = "checkup_date", nullable = false) private LocalDate checkupDate; @@ -39,6 +39,19 @@ public class GeneralCheckUp { @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; diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java index 0cf45ab25..8091e2801 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java @@ -21,7 +21,7 @@ public class GeneralCheckUpListDto { private String checkupId; - private Long ashaId; + private Integer ashaId; private String checkupDate; 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 000000000..bfb09e8e2 --- /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 findByCreatedByOrderByIdDesc(String userName); +} diff --git a/src/main/java/com/iemr/flw/service/DiseaseControlService.java b/src/main/java/com/iemr/flw/service/DiseaseControlService.java index c7db39869..83de6f339 100644 --- a/src/main/java/com/iemr/flw/service/DiseaseControlService.java +++ b/src/main/java/com/iemr/flw/service/DiseaseControlService.java @@ -50,6 +50,6 @@ public interface DiseaseControlService { List getCdtfVisits(GetBenRequestHandler getBenRequestHandler); - List saveGeneralCheckUp(List generalCheckUpRequest,String token); + List saveGeneralCheckUp(List generalCheckUpRequest,String token) throws IEMRException; List getGeneralCheckUp(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 988b6da62..4a48fbedf 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; @@ -1582,13 +1593,106 @@ public List getCdtfVisits(GetBenRequestHandler getBenReq } @Override - public List saveGeneralCheckUp(List generalCheckUpRequest, String token) { + @Transactional + public List saveGeneralCheckUp(List generalCheckUpRequest, String token) throws IEMRException { + - return null; + 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()); + + 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 public List getGeneralCheckUp(String token) { - return null; + + String userName = jwtUtil.extractUsername(token); + + List rows = generalCheckUpRepo.findByCreatedByOrderByIdDesc(userName); + List result = new ArrayList<>(); + + for (GeneralCheckUp e : rows) { + String visitDate = e.getCheckupDate() != null + ? e.getCheckupDate().format(VISIT_DATE_FMT) : null; + + GeneralCheckUpListDto f = new GeneralCheckUpListDto(); + f.setCheckUpDate(visitDate); // "22-10-2026" + f.setProblemType(e.getProblemType()); // "g6" + f.setOtherText(e.getOtherText()); + f.setCheckupId(e.getCheckupId()); + 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>() {})); + } + } catch (JsonProcessingException 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); + } + return result; } } \ No newline at end of file From 2a8806c6425035f796fef2b08aa86b9bb9cfc78c Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 18:12:49 +0530 Subject: [PATCH 06/21] update response --- src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java | 2 +- .../com/iemr/flw/service/impl/DiseaseControlServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java index 8091e2801..27f58e695 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpListDto.java @@ -8,7 +8,7 @@ @Data public class GeneralCheckUpListDto { @JsonProperty("check_up_date") - private String checkUpDate; + private String check_up_date; @JsonProperty("problem_type") private String problemType; 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 4a48fbedf..a1e999799 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1658,7 +1658,7 @@ public List getGeneralCheckUp(String token) { ? e.getCheckupDate().format(VISIT_DATE_FMT) : null; GeneralCheckUpListDto f = new GeneralCheckUpListDto(); - f.setCheckUpDate(visitDate); // "22-10-2026" + f.setCheck_up_date(visitDate); // "22-10-2026" f.setProblemType(e.getProblemType()); // "g6" f.setOtherText(e.getOtherText()); f.setCheckupId(e.getCheckupId()); From c45ec8cfd2658466d6f83643914cf6c7c91be815 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 18:27:47 +0530 Subject: [PATCH 07/21] update response --- .../flw/repo/iemr/GeneralCheckUpRepo.java | 2 +- .../impl/DiseaseControlServiceImpl.java | 38 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java index bfb09e8e2..557f82308 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpRepo.java @@ -8,5 +8,5 @@ @Repository public interface GeneralCheckUpRepo extends JpaRepository { - List findByCreatedByOrderByIdDesc(String userName); + List findByCreatedBy(String userName); } 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 a1e999799..41365815a 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1648,12 +1648,37 @@ public List saveGeneralCheckUp(List genera @Override public List getGeneralCheckUp(String token) { - String userName = jwtUtil.extractUsername(token); + log.info("===== getGeneralCheckUp() called ====="); + log.info("Received token: {}", token); + + String userName = null; + try { + userName = jwtUtil.extractUsername(token); + log.info("Extracted username from token: {}", userName); + } catch (Exception e) { + log.error("Error while extracting username from token", e); + throw e; // ya apna custom exception throw kar sakte ho + } + + List rows = null; + try { + rows = generalCheckUpRepo.findByCreatedBy(userName); + log.info("Records fetched from DB for user [{}]: {}", userName, rows != null ? rows.size() : 0); + } catch (Exception e) { + log.error("Error while fetching GeneralCheckUp records for user: {}", userName, e); + throw e; + } - List rows = generalCheckUpRepo.findByCreatedByOrderByIdDesc(userName); List result = new ArrayList<>(); + if (rows == null || rows.isEmpty()) { + log.warn("No GeneralCheckUp records found for user: {}", userName); + return result; + } + for (GeneralCheckUp e : rows) { + log.debug("Processing GeneralCheckUp id: {}, checkupId: {}", e.getId(), e.getCheckupId()); + String visitDate = e.getCheckupDate() != null ? e.getCheckupDate().format(VISIT_DATE_FMT) : null; @@ -1679,8 +1704,12 @@ public List getGeneralCheckUp(String token) { if (e.getProblems() != null) { f.setProblems(objectMapper.readValue( e.getProblems(), new TypeReference>() {})); + log.debug("Successfully parsed problems JSON for id: {}", e.getId()); + } else { + log.debug("Problems field is null for id: {}", e.getId()); } } catch (JsonProcessingException ex) { + log.error("Invalid problems JSON for id: {}. JSON: {}", e.getId(), e.getProblems(), ex); throw new IllegalStateException("Invalid problems json for id " + e.getId(), ex); } @@ -1693,6 +1722,11 @@ public List getGeneralCheckUp(String token) { result.add(dto); } + + log.info("===== getGeneralCheckUp() completed successfully. Total records returned: {} =====", result.size()); + // Optional: full response dekhna ho to (production mein mat rakho) + // log.debug("Final response: {}", result); + return result; } } \ No newline at end of file From 3b007e30ab0f100e0afe3723aca4cb8699dd4643 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 19:54:04 +0530 Subject: [PATCH 08/21] update response --- .../java/com/iemr/flw/controller/DiseaseControlController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index 32afa2eab..d99ce331f 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -379,8 +379,7 @@ public ResponseEntity> getVisitDetails( @RequestMapping(value = "generalCheckUp/getAll", method = RequestMethod.POST) - public ResponseEntity> getGeneralCheckUp( - @RequestHeader(value = "JwtToken") String token) { + public ResponseEntity> getGeneralCheckUp(@RequestBody GetBenRequestHandler getBenRequestHandler,@RequestHeader(value = "JwtToken") String token) { Map response = new LinkedHashMap<>(); From bd45c8723a93d6c0bbf545e02932592747df7a9f Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 19:57:12 +0530 Subject: [PATCH 09/21] update response --- .../impl/DiseaseControlServiceImpl.java | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) 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 41365815a..9989c556e 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1648,36 +1648,36 @@ public List saveGeneralCheckUp(List genera @Override public List getGeneralCheckUp(String token) { - log.info("===== getGeneralCheckUp() called ====="); - log.info("Received token: {}", token); + logger.info("===== getGeneralCheckUp() called ====="); + logger.info("Received token: {}", token); String userName = null; try { userName = jwtUtil.extractUsername(token); - log.info("Extracted username from token: {}", userName); + logger.info("Extracted username from token: {}", userName); } catch (Exception e) { - log.error("Error while extracting username from token", e); - throw e; // ya apna custom exception throw kar sakte ho + logger.error("Error while extracting username from token", e); + throw e; } List rows = null; try { rows = generalCheckUpRepo.findByCreatedBy(userName); - log.info("Records fetched from DB for user [{}]: {}", userName, rows != null ? rows.size() : 0); + logger.info("Records fetched from DB for user [{}]: {}", userName, rows != null ? rows.size() : 0); } catch (Exception e) { - log.error("Error while fetching GeneralCheckUp records for user: {}", userName, e); + logger.error("Error while fetching GeneralCheckUp records for user: {}", userName, e); throw e; } List result = new ArrayList<>(); if (rows == null || rows.isEmpty()) { - log.warn("No GeneralCheckUp records found for user: {}", userName); + logger.warn("No GeneralCheckUp records found for user: {}", userName); return result; } for (GeneralCheckUp e : rows) { - log.debug("Processing GeneralCheckUp id: {}, checkupId: {}", e.getId(), e.getCheckupId()); + logger.debug("Processing GeneralCheckUp id: {}, checkupId: {}", e.getId(), e.getCheckupId()); String visitDate = e.getCheckupDate() != null ? e.getCheckupDate().format(VISIT_DATE_FMT) : null; @@ -1704,12 +1704,12 @@ public List getGeneralCheckUp(String token) { if (e.getProblems() != null) { f.setProblems(objectMapper.readValue( e.getProblems(), new TypeReference>() {})); - log.debug("Successfully parsed problems JSON for id: {}", e.getId()); + logger.debug("Successfully parsed problems JSON for id: {}", e.getId()); } else { - log.debug("Problems field is null for id: {}", e.getId()); + logger.debug("Problems field is null for id: {}", e.getId()); } } catch (JsonProcessingException ex) { - log.error("Invalid problems JSON for id: {}. JSON: {}", e.getId(), e.getProblems(), 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); } @@ -1723,9 +1723,8 @@ public List getGeneralCheckUp(String token) { result.add(dto); } - log.info("===== getGeneralCheckUp() completed successfully. Total records returned: {} =====", result.size()); - // Optional: full response dekhna ho to (production mein mat rakho) - // log.debug("Final response: {}", result); + logger.info("===== getGeneralCheckUp() completed successfully. Total records returned: {} =====", result.size()); + return result; } From 516f75b93a99df1b2d60f70ce2c58f43a6610409 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 20:08:43 +0530 Subject: [PATCH 10/21] update response --- .../iemr/flw/service/impl/DiseaseControlServiceImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 9989c556e..6a44aeedf 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1651,18 +1651,17 @@ public List getGeneralCheckUp(String token) { logger.info("===== getGeneralCheckUp() called ====="); logger.info("Received token: {}", token); - String userName = null; + Integer userName = null; try { - userName = jwtUtil.extractUsername(token); + userName = jwtUtil.extractUserId(token); logger.info("Extracted username from token: {}", userName); } catch (Exception e) { logger.error("Error while extracting username from token", e); - throw e; } List rows = null; try { - rows = generalCheckUpRepo.findByCreatedBy(userName); + 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); From fc62b950ff3396255c2681200c06f5bb78c809aa Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 20:27:36 +0530 Subject: [PATCH 11/21] update response --- .../com/iemr/flw/service/impl/DiseaseControlServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6a44aeedf..cb0457764 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1685,7 +1685,7 @@ public List getGeneralCheckUp(String token) { f.setCheck_up_date(visitDate); // "22-10-2026" f.setProblemType(e.getProblemType()); // "g6" f.setOtherText(e.getOtherText()); - f.setCheckupId(e.getCheckupId()); + 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()); From 8a665b9758ed496fcd41de9ef29bfd3ab2998ac2 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Tue, 20 Oct 2026 20:40:47 +0530 Subject: [PATCH 12/21] update response --- .../iemr/flw/service/impl/DiseaseControlServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 cb0457764..916953a36 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1615,6 +1615,9 @@ public List saveGeneralCheckUp(List genera 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 @@ -1682,8 +1685,8 @@ public List getGeneralCheckUp(String token) { ? e.getCheckupDate().format(VISIT_DATE_FMT) : null; GeneralCheckUpListDto f = new GeneralCheckUpListDto(); - f.setCheck_up_date(visitDate); // "22-10-2026" - f.setProblemType(e.getProblemType()); // "g6" + f.setCheck_up_date(visitDate); + f.setProblemType(e.getProblemType()); f.setOtherText(e.getOtherText()); f.setCheckupId(e.getId().toString()); f.setAshaId(e.getAshaId()); From 32855a3dcff93df36e562f846da0d07170881790 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 28 Oct 2026 17:08:04 +0530 Subject: [PATCH 13/21] Add api for general checkup follow up --- .../controller/DiseaseControlController.java | 66 ++ .../domain/iemr/GeneralCheckUpFollowUp.java | 48 ++ .../dto/iemr/GeneralCheckUpFollowUpDto.java | 12 + .../iemr/GeneralCheckUpFollowUpListDto.java | 19 + .../flw/repo/iemr/BenReferDetailsRepo.java | 3 + .../flw/repo/iemr/CbacIemrDetailsRepo.java | 3 + .../repo/iemr/EligibleCoupleRegisterRepo.java | 2 + .../GeneralCheckUpFollowUpRepository.java | 10 + .../iemr/IFAFormSubmissionRepository.java | 2 + .../flw/repo/iemr/IncentiveRecordRepo.java | 15 + .../iemr/flw/repo/iemr/IncentivesRepo.java | 3 + .../flw/service/DiseaseControlService.java | 2 + .../impl/DiseaseControlServiceImpl.java | 155 +++- .../service/impl/IncentiveServiceImpl.java | 792 +++++++++--------- 14 files changed, 735 insertions(+), 397 deletions(-) create mode 100644 src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java create mode 100644 src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java create mode 100644 src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java create mode 100644 src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index d99ce331f..318b29bad 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -445,4 +445,70 @@ public ResponseEntity> savGeneralCheckUp( } + @RequestMapping(value = "generalCheckUpFollowUp/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 = "generalCheckUpFollowUp/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/GeneralCheckUpFollowUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java new file mode 100644 index 000000000..f907e377a --- /dev/null +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java @@ -0,0 +1,48 @@ +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; +} \ No newline at end of file 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 000000000..eebd3b24e --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java @@ -0,0 +1,12 @@ +package com.iemr.flw.dto.iemr; + +import lombok.Data; + +@Data +public class GeneralCheckUpFollowUpDto { + private Long id; + private Long beneficiaryId; + private Long houseHoldId; + private String visitDate; + 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 000000000..fc8bdd588 --- /dev/null +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java @@ -0,0 +1,19 @@ +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; + +} 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 25a0b652a..dbb76975e 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java @@ -47,6 +47,9 @@ public interface BenReferDetailsRepo extends JpaRepository 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 5e93dfad6..82a96c807 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 218c5b2b3..d9418df08 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 000000000..1b6f0d4b7 --- /dev/null +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java @@ -0,0 +1,10 @@ +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; + +@Repository +public interface GeneralCheckUpFollowUpRepository + extends JpaRepository { +} \ No newline at end of file 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 0b1b5ff72..88201f45b 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 74acfa5f8..d72c069d6 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 d1cbc7f84..10faf62f5 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 83de6f339..363dcb5d2 100644 --- a/src/main/java/com/iemr/flw/service/DiseaseControlService.java +++ b/src/main/java/com/iemr/flw/service/DiseaseControlService.java @@ -51,5 +51,7 @@ public interface DiseaseControlService { 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 916953a36..a49527d3a 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -113,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 @@ -1647,6 +1648,156 @@ public List saveGeneralCheckUp(List genera 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 entities = new ArrayList<>(); + + for (GeneralCheckUpFollowUpDto dto : dtos) { + + if (dto == null || dto.getFields() == null) { + throw new IllegalArgumentException( + "Follow-up details are required"); + } + + 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"); + } + + GeneralCheckUpFollowUp entity = + new GeneralCheckUpFollowUp(); + + entity.setBenId(dto.getBeneficiaryId()); + entity.setHouseholdId(dto.getHouseHoldId()); + entity.setFollowUpDate(followUpDate); + entity.setFollowupStatus(status); + + entity.setReferredTo( + referredToHigherFacility + ? fields.getReferredTo() + : null + ); + + entity.setAshaId(userId); + entity.setCreatedBy(username); + + entities.add(entity); + } + + List savedEntities = + generalCheckUpFollowUpRepository.saveAll(entities); + + return savedEntities.stream() + .map(entity -> { + GeneralCheckUpFollowUpDto dto = + new GeneralCheckUpFollowUpDto(); + + dto.setId(entity.getId()); + dto.setBeneficiaryId(entity.getBenId()); + dto.setHouseHoldId(entity.getHouseholdId()); + + GeneralCheckUpFollowUpListDto fields = + new GeneralCheckUpFollowUpListDto(); + + fields.setFollowUpDate( + entity.getFollowUpDate().toString()); + fields.setFollowupStatus( + entity.getFollowupStatus()); + fields.setReferredTo(entity.getReferredTo()); + + dto.setFields(fields); + 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 + @Transactional(readOnly = true) + public List getGeneralCheckUpFollowUp( + String token) { + + Integer userId = getUserIdFromToken(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()); + + GeneralCheckUpFollowUpListDto fields = + new GeneralCheckUpFollowUpListDto(); + + 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()); + } @Override public List getGeneralCheckUp(String token) { 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 b89cb137f..7fa1ef08a 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); - - } - } From f52c4c6162f6e92e15160709861887789577a371 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 28 Oct 2026 17:28:07 +0530 Subject: [PATCH 14/21] Add api for general checkup follow up --- .../controller/DiseaseControlController.java | 2 +- .../GeneralCheckUpFollowUpRepository.java | 3 + .../impl/DiseaseControlServiceImpl.java | 78 ++++++++++--------- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index 318b29bad..b821fd9ab 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -445,7 +445,7 @@ public ResponseEntity> savGeneralCheckUp( } - @RequestMapping(value = "generalCheckUpFollowUp/getAll", method = RequestMethod.POST) + @RequestMapping(value = "generalCheckUpFollowUp/getAll", method = RequestMethod.POST) public ResponseEntity> getGeneralCheckUpFollowUp(@RequestBody GetBenRequestHandler getBenRequestHandler,@RequestHeader(value = "JwtToken") String token) { Map response = new LinkedHashMap<>(); diff --git a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java index 1b6f0d4b7..14980f863 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java @@ -4,7 +4,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface GeneralCheckUpFollowUpRepository extends JpaRepository { + List findByAshaId(Integer userId); } \ 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 a49527d3a..aa7196782 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1758,45 +1758,51 @@ public List saveGeneralCheckUpFollowUp( } @Override - @Transactional(readOnly = true) + @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()); + + GeneralCheckUpFollowUpListDto fields = + new GeneralCheckUpFollowUpListDto(); + + 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); + } - Integer userId = getUserIdFromToken(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()); - - GeneralCheckUpFollowUpListDto fields = - new GeneralCheckUpFollowUpListDto(); - - 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()); } @Override From 585b82412e830330fd8e274c5d5acf1f2c762029 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Wed, 28 Oct 2026 18:50:38 +0530 Subject: [PATCH 15/21] Add api for general checkup follow up --- .../controller/DiseaseControlController.java | 65 ---------- .../GeneralCheckUpFollowUpController.java | 121 ++++++++++++++++++ 2 files changed, 121 insertions(+), 65 deletions(-) create mode 100644 src/main/java/com/iemr/flw/controller/GeneralCheckUpFollowUpController.java diff --git a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java index b821fd9ab..57b4e3b49 100644 --- a/src/main/java/com/iemr/flw/controller/DiseaseControlController.java +++ b/src/main/java/com/iemr/flw/controller/DiseaseControlController.java @@ -445,70 +445,5 @@ public ResponseEntity> savGeneralCheckUp( } - @RequestMapping(value = "generalCheckUpFollowUp/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 = "generalCheckUpFollowUp/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/controller/GeneralCheckUpFollowUpController.java b/src/main/java/com/iemr/flw/controller/GeneralCheckUpFollowUpController.java new file mode 100644 index 000000000..ca450d670 --- /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 From 0063bd12fa662d620e5949313fe66f4f1a7cf03e Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 29 Oct 2026 12:38:51 +0530 Subject: [PATCH 16/21] Make multiple followUp in HWC referal --- .../domain/iemr/GeneralCheckUpFollowUp.java | 6 + .../dto/iemr/GeneralCheckUpFollowUpDto.java | 4 + .../GeneralCheckUpFollowUpRepository.java | 11 +- .../impl/DiseaseControlServiceImpl.java | 103 +++++++++++++----- 4 files changed, 94 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java index f907e377a..3457fdf4f 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java @@ -45,4 +45,10 @@ public class GeneralCheckUpFollowUp { @Column(name = "updated_date", insertable = false, updatable = false) private Timestamp updatedDate; + + @Column(name = "referralReason") + private String referralReason; + + @Column(name = "referredOnDate") + private LocalDate referredOnDate; } \ No newline at end of file diff --git a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java index eebd3b24e..9840e0d0e 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpDto.java @@ -2,11 +2,15 @@ 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/repo/iemr/GeneralCheckUpFollowUpRepository.java b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java index 14980f863..cef915267 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java +++ b/src/main/java/com/iemr/flw/repo/iemr/GeneralCheckUpFollowUpRepository.java @@ -4,10 +4,19 @@ 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); -} \ No newline at end of file + + Optional + findFirstByBenIdAndReferralReasonAndReferredOnDateGreaterThanEqualAndReferredOnDateLessThan( + Long benId, + String referralReason, + LocalDate monthStart, + LocalDate nextMonthStart);} + 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 aa7196782..fe95b878d 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1648,6 +1648,7 @@ public List saveGeneralCheckUp(List genera return generalCheckUpRequest; } + @Override @Transactional public List saveGeneralCheckUpFollowUp( @@ -1662,7 +1663,7 @@ public List saveGeneralCheckUpFollowUp( Integer userId = jwtUtil.extractUserId(token); String username = jwtUtil.extractUsername(token); - List entities = new ArrayList<>(); + List result = new ArrayList<>(); for (GeneralCheckUpFollowUpDto dto : dtos) { @@ -1671,6 +1672,30 @@ public List saveGeneralCheckUpFollowUp( "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(); @@ -1684,8 +1709,8 @@ public List saveGeneralCheckUpFollowUp( "Follow-up date is required"); } - LocalDate followUpDate = LocalDate.parse( - date.substring(0, 10)); + LocalDate followUpDate = + LocalDate.parse(date.substring(0, 10)); String status = fields.getFollowupStatus(); @@ -1695,7 +1720,8 @@ public List saveGeneralCheckUpFollowUp( } boolean referredToHigherFacility = - "referred_to_higher_facility".equalsIgnoreCase(status); + "referred_to_higher_facility" + .equalsIgnoreCase(status); if (referredToHigherFacility && (fields.getReferredTo() == null @@ -1704,11 +1730,23 @@ public List saveGeneralCheckUpFollowUp( "Referred-to facility is required"); } + // Find the existing record for this specific referral. GeneralCheckUpFollowUp entity = - new GeneralCheckUpFollowUp(); - + 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); @@ -1721,37 +1759,41 @@ public List saveGeneralCheckUpFollowUp( entity.setAshaId(userId); entity.setCreatedBy(username); - entities.add(entity); - } + GeneralCheckUpFollowUp savedEntity = + generalCheckUpFollowUpRepository.save(entity); + + // Return the saved record with referral information. + GeneralCheckUpFollowUpDto response = + new GeneralCheckUpFollowUpDto(); - List savedEntities = - generalCheckUpFollowUpRepository.saveAll(entities); + response.setId(savedEntity.getId()); + response.setBeneficiaryId(savedEntity.getBenId()); + response.setHouseHoldId(savedEntity.getHouseholdId()); - return savedEntities.stream() - .map(entity -> { - GeneralCheckUpFollowUpDto dto = - new GeneralCheckUpFollowUpDto(); + response.setReferralReason(savedEntity.getReferralReason()); + response.setReferredOnDate( + savedEntity.getReferredOnDate() != null + ? savedEntity.getReferredOnDate() + : null + ); + + GeneralCheckUpFollowUpListDto responseFields = + new GeneralCheckUpFollowUpListDto(); - dto.setId(entity.getId()); - dto.setBeneficiaryId(entity.getBenId()); - dto.setHouseHoldId(entity.getHouseholdId()); + responseFields.setFollowUpDate( + savedEntity.getFollowUpDate().toString()); + responseFields.setFollowupStatus( + savedEntity.getFollowupStatus()); + responseFields.setReferredTo(savedEntity.getReferredTo()); - GeneralCheckUpFollowUpListDto fields = - new GeneralCheckUpFollowUpListDto(); + response.setFields(responseFields); - fields.setFollowUpDate( - entity.getFollowUpDate().toString()); - fields.setFollowupStatus( - entity.getFollowupStatus()); - fields.setReferredTo(entity.getReferredTo()); + result.add(response); + } - dto.setFields(fields); - return dto; - }) - .collect(Collectors.toList()); + return result; } catch (Exception e) { - // Replace with your project's standard IEMRException constructor. throw new RuntimeException( "Error saving General Check-up follow-up", e); } @@ -1775,6 +1817,8 @@ public List getGeneralCheckUpFollowUp( dto.setId(entity.getId()); dto.setBeneficiaryId(entity.getBenId()); dto.setHouseHoldId(entity.getHouseholdId()); + dto.setReferralReason(entity.getReferralReason()); + dto.setReferredOnDate(entity.getReferredOnDate()); GeneralCheckUpFollowUpListDto fields = new GeneralCheckUpFollowUpListDto(); @@ -1787,6 +1831,7 @@ public List getGeneralCheckUpFollowUp( fields.setFollowupStatus(entity.getFollowupStatus()); fields.setReferredTo(entity.getReferredTo()); + dto.setFields(fields); dto.setVisitDate( From 21de33b427cb2bd1fa72e311f1427fce7f5634a4 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 29 Oct 2026 15:22:33 +0530 Subject: [PATCH 17/21] Make multiple followUp in HWC referal --- src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java | 1 - .../java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java | 4 ++-- .../com/iemr/flw/service/impl/DiseaseControlServiceImpl.java | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java index f3d84c52a..ec9f9c64b 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUp.java @@ -52,7 +52,6 @@ public class GeneralCheckUp { private String priority; - @Column(name = "referral_reason", length = 500) private String referralReason; diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java index 3457fdf4f..6961a9ace 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java @@ -46,9 +46,9 @@ public class GeneralCheckUpFollowUp { @Column(name = "updated_date", insertable = false, updatable = false) private Timestamp updatedDate; - @Column(name = "referralReason") + @Column(name = "referral_reason") private String referralReason; - @Column(name = "referredOnDate") + @Column(name = "referred_on_date") private LocalDate referredOnDate; } \ 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 fe95b878d..aa00718be 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1758,6 +1758,7 @@ public List saveGeneralCheckUpFollowUp( entity.setAshaId(userId); entity.setCreatedBy(username); + entity.setReferredTo(dto.getFields().getReferredTo()); GeneralCheckUpFollowUp savedEntity = generalCheckUpFollowUpRepository.save(entity); From d2aa09baa6009efc0a1da3928761e37366dcaa87 Mon Sep 17 00:00:00 2001 From: Saurav Mishra Date: Thu, 29 Oct 2026 15:24:49 +0530 Subject: [PATCH 18/21] Make multiple followUp in HWC referal --- .../java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java index 6961a9ace..3457fdf4f 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java @@ -46,9 +46,9 @@ public class GeneralCheckUpFollowUp { @Column(name = "updated_date", insertable = false, updatable = false) private Timestamp updatedDate; - @Column(name = "referral_reason") + @Column(name = "referralReason") private String referralReason; - @Column(name = "referred_on_date") + @Column(name = "referredOnDate") private LocalDate referredOnDate; } \ No newline at end of file From 0c2c97e0489c3de126de1c227311917272ceccaa Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 2 Nov 2026 15:34:30 +0530 Subject: [PATCH 19/21] Add new column is_recommended_for_tpt --- src/main/java/com/iemr/flw/domain/iemr/TBSuspected.java | 3 +++ 1 file changed, 3 insertions(+) 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 be27aaa57..370fe276d 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; From c71a112ac5f962700a44c79ed714d0d18b3606b9 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Mon, 2 Nov 2026 17:38:53 +0530 Subject: [PATCH 20/21] Add new column is_recommended_for_tpt --- .../com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java | 3 +++ .../iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java | 3 +++ src/main/java/com/iemr/flw/dto/iemr/TBSuspectedDTO.java | 1 + .../iemr/flw/service/impl/DiseaseControlServiceImpl.java | 7 +++++++ 4 files changed, 14 insertions(+) diff --git a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java index 3457fdf4f..952472389 100644 --- a/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java +++ b/src/main/java/com/iemr/flw/domain/iemr/GeneralCheckUpFollowUp.java @@ -51,4 +51,7 @@ public class GeneralCheckUpFollowUp { @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/dto/iemr/GeneralCheckUpFollowUpListDto.java b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java index fc8bdd588..07bf2d49b 100644 --- a/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java +++ b/src/main/java/com/iemr/flw/dto/iemr/GeneralCheckUpFollowUpListDto.java @@ -16,4 +16,7 @@ public class GeneralCheckUpFollowUpListDto { @JsonProperty("referred_to") private String referredTo; + @JsonProperty("other_follow_up") + private String otherFollowUp; + } 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 23e568ef7..ec31fa56d 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/service/impl/DiseaseControlServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java index aa00718be..40dec0673 100644 --- a/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java +++ b/src/main/java/com/iemr/flw/service/impl/DiseaseControlServiceImpl.java @@ -1730,6 +1730,7 @@ public List saveGeneralCheckUpFollowUp( "Referred-to facility is required"); } + // Find the existing record for this specific referral. GeneralCheckUpFollowUp entity = generalCheckUpFollowUpRepository @@ -1756,6 +1757,9 @@ public List saveGeneralCheckUpFollowUp( : null ); + if(fields.getOtherFollowUp()!=null){ + entity.setOtherFollowUp(fields.getOtherFollowUp()); + } entity.setAshaId(userId); entity.setCreatedBy(username); entity.setReferredTo(dto.getFields().getReferredTo()); @@ -1823,6 +1827,9 @@ public List getGeneralCheckUpFollowUp( GeneralCheckUpFollowUpListDto fields = new GeneralCheckUpFollowUpListDto(); + if(entity.getOtherFollowUp()!=null){ + fields.setOtherFollowUp(entity.getOtherFollowUp()); + } fields.setFollowUpDate( entity.getFollowUpDate() != null From da09863aada5d994b32a41a79c6494fcbf19c5b4 Mon Sep 17 00:00:00 2001 From: Saurav Mishra <80103738+SauravBizbRolly@users.noreply.github.com> Date: Tue, 3 Nov 2026 07:57:09 +0530 Subject: [PATCH 21/21] Add new column is_recommended_for_tpt --- .../flw/repo/iemr/BenReferDetailsRepo.java | 3 ++ .../iemr/flw/repo/iemr/GeneralOpdRepo.java | 7 +-- .../service/impl/GeneralOpdServiceImpl.java | 49 +++++++++---------- 3 files changed, 30 insertions(+), 29 deletions(-) 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 dbb76975e..a475476ae 100644 --- a/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java +++ b/src/main/java/com/iemr/flw/repo/iemr/BenReferDetailsRepo.java @@ -45,6 +45,9 @@ 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) 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 fe9447659..6c7e1b70a 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/service/impl/GeneralOpdServiceImpl.java b/src/main/java/com/iemr/flw/service/impl/GeneralOpdServiceImpl.java index 898aa9c6f..156fa0b05 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 +}