From ce01105dfff26ff05b51e11b146c8c24f8c01dbb Mon Sep 17 00:00:00 2001
From: Vanitha S <116701245+vanitha1822@users.noreply.github.com>
Date: Fri, 27 Feb 2026 14:07:03 +0530
Subject: [PATCH 1/3] Fix the issue in Downloading Reports (#117)
* fix: column datatype mismatch issue
* fix: report download issue in AMM-2017
---
.../service/report/CRMReportServiceImpl.java | 107 ++++++++----------
1 file changed, 50 insertions(+), 57 deletions(-)
diff --git a/src/main/java/com/iemr/inventory/service/report/CRMReportServiceImpl.java b/src/main/java/com/iemr/inventory/service/report/CRMReportServiceImpl.java
index 714043b7..526c63e2 100644
--- a/src/main/java/com/iemr/inventory/service/report/CRMReportServiceImpl.java
+++ b/src/main/java/com/iemr/inventory/service/report/CRMReportServiceImpl.java
@@ -223,31 +223,31 @@ public String getDailyStockDetailsReport(ItemStockEntryReport entryReport) {
openingStock = ((Number) objects[10]).longValue();
}
Long adjustedQuantity_FromDate = 0L;
- if (objects[11] != null) {
- adjustedQuantity_FromDate = ((Number) objects[11]).longValue();
+ if (objects[15] != null) {
+ adjustedQuantity_FromDate = ((Number) objects[15]).longValue();
}
Long quantityDispanced = 0L;
- if (objects[12] != null) {
- quantityDispanced = ((Number) objects[12]).longValue();
+ if (objects[11] != null) {
+ quantityDispanced = ((Number) objects[11]).longValue();
}
- String itemName = (String) objects[13];
- String facilityName = (String) objects[14];
- String itemCategoryName = (String) objects[15];
+ String itemName = (String) objects[12];
+ String facilityName = (String) objects[13];
+ String itemCategoryName = (String) objects[14];
Long adjustedQuantity_ToDate = 0L;
- if (objects[16] != null) {
- adjustedQuantity_ToDate = ((Number) objects[16]).longValue();
+ if (objects[15] != null) {
+ adjustedQuantity_ToDate = ((Number) objects[15]).longValue();
}
Long adjustedQuantity_ToDate_Receipt = 0L;
- if (objects[17] != null) {
- adjustedQuantity_ToDate_Receipt = ((Number) objects[17]).longValue();
+ if (objects[16] != null) {
+ adjustedQuantity_ToDate_Receipt = ((Number) objects[16]).longValue();
}
Long adjustedQuantity_ToDate_Issue = 0L;
- if (objects[18] != null) {
- adjustedQuantity_ToDate_Issue = ((Number) objects[18]).longValue();
+ if (objects[17] != null) {
+ adjustedQuantity_ToDate_Issue = ((Number) objects[17]).longValue();
}
Long ClosingStock = 0L;
- if (objects[19] != null) {
- ClosingStock = ((Number) objects[19]).longValue();
+ if (objects[18] != null) {
+ ClosingStock = ((Number) objects[18]).longValue();
}
@@ -421,31 +421,31 @@ public String getMonthlyReport(ItemStockEntryReport entryReport) {
openingStock = ((Number) objects[10]).longValue();
}
Long adjustedQuantity_FromDate = 0L;
- if (objects[11] != null) {
- adjustedQuantity_FromDate = ((Number) objects[11]).longValue();
+ if (objects[15] != null) {
+ adjustedQuantity_FromDate = ((Number) objects[15]).longValue();
}
Long quantityDispanced = 0L;
- if (objects[12] != null) {
- quantityDispanced = ((Number) objects[12]).longValue();
+ if (objects[11] != null) {
+ quantityDispanced = ((Number) objects[11]).longValue();
}
- String itemName = (String) objects[13];
- String facilityName = (String) objects[14];
- String itemCategoryName = (String) objects[15];
+ String itemName = (String) objects[12];
+ String facilityName = (String) objects[13];
+ String itemCategoryName = (String) objects[14];
Long adjustedQuantity_ToDate = 0L;
- if (objects[16] != null) {
- adjustedQuantity_ToDate = ((Number) objects[16]).longValue();
+ if (objects[15] != null) {
+ adjustedQuantity_ToDate = ((Number) objects[15]).longValue();
}
Long adjustedQuantity_ToDate_Receipt = 0L;
- if (objects[17] != null) {
- adjustedQuantity_ToDate_Receipt = ((Number) objects[17]).longValue();
+ if (objects[16] != null) {
+ adjustedQuantity_ToDate_Receipt = ((Number) objects[16]).longValue();
}
Long adjustedQuantity_ToDate_Issue = 0L;
- if (objects[18] != null) {
- adjustedQuantity_ToDate_Issue = ((Number) objects[18]).longValue();
+ if (objects[17] != null) {
+ adjustedQuantity_ToDate_Issue = ((Number) objects[17]).longValue();
}
Long ClosingStock = 0L;
- if (objects[19] != null) {
- ClosingStock = ((Number) objects[19]).longValue();
+ if (objects[18] != null) {
+ ClosingStock = ((Number) objects[18]).longValue();
}
// Long actualOpening = openingStock + adjustedQuantity_FromDate;
Long actualOpening = openingStock;
@@ -520,57 +520,50 @@ public String getYearlyReport(ItemStockEntryReport entryReport) {
for (Object[] objects : reports) {
if (objects != null && objects.length > 0) {
- String batchNo = (String) objects[3];
+ String batchNo = objects[3] != null ? objects[3].toString() : null;
Long totalQuantityReceived = 0L;
if (objects[4] != null) {
- totalQuantityReceived = ((Number) objects[4]).longValue();
+ totalQuantityReceived = Long.valueOf(objects[4].toString());
}
Double unitCostPrice = 0.0;
if (objects[5] != null) {
- unitCostPrice = ((Number) objects[5]).doubleValue();
+ unitCostPrice = Double.valueOf(objects[5].toString());
}
Date expiryDate = (Date) objects[6];
Long openingStock = 0L;
if (objects[10] != null) {
- openingStock = ((Number) objects[10]).longValue();
+ openingStock = Long.valueOf(objects[10].toString());
}
Long adjustedQuantity_FromDate = 0L;
- if (objects[11] != null) {
- adjustedQuantity_FromDate = ((Number) objects[11]).longValue();
+ if (objects[15] != null) {
+ adjustedQuantity_FromDate = Long.valueOf(objects[15].toString());
}
Long quantityDispanced = 0L;
- if (objects[12] != null) {
- quantityDispanced = ((Number) objects[12]).longValue();
+ if (objects[11] != null) {
+ quantityDispanced = Long.valueOf(objects[11].toString());
}
- String itemName = (String) objects[13];
- String facilityName = (String) objects[14];
- String itemCategoryName = (String) objects[15];
+ String itemName = objects[12] != null ? objects[12].toString() : null;
+ String facilityName = objects[13] != null ? objects[13].toString() : null;
+ String itemCategoryName = objects[14] != null ? objects[14].toString() : null;
Long adjustedQuantity_ToDate = 0L;
- if (objects[16] != null) {
- adjustedQuantity_ToDate = ((Number) objects[16]).longValue();
+ if (objects[15] != null) {
+ adjustedQuantity_ToDate = Long.valueOf(objects[15].toString());
}
Long adjustedQuantity_ToDate_Receipt = 0L;
- if (objects[17] != null) {
- adjustedQuantity_ToDate_Receipt = ((Number) objects[17]).longValue();
+ if (objects[16] != null) {
+ adjustedQuantity_ToDate_Receipt = Long.valueOf(objects[16].toString());
}
Long adjustedQuantity_ToDate_Issue = 0L;
- if (objects[18] != null) {
- adjustedQuantity_ToDate_Issue = ((Number) objects[18]).longValue();
+ if (objects[17] != null) {
+ adjustedQuantity_ToDate_Issue = Long.valueOf(objects[17].toString());
}
Long ClosingStock = 0L;
- if (objects[19] != null) {
- ClosingStock = ((Number) objects[19]).longValue();
+ if (objects[18] != null) {
+ ClosingStock = Long.valueOf(objects[18].toString());
}
-// Long actualOpening = openingStock + adjustedQuantity_FromDate;
Long actualOpening = openingStock;
- Long actualDispensed = quantityDispanced;// - adjustedQuantity_ToDate;
+ Long actualDispensed = quantityDispanced;
Long actualClosing = ClosingStock;
-// if (actualOpening == 0 || actualOpening == null) {
-// actualClosing = totalQuantityReceived - actualDispensed + adjustedQuantity_ToDate;
-// } else {
-// actualClosing = actualOpening - actualDispensed + adjustedQuantity_ToDate;
-// totalQuantityReceived = 0L;
-// }
YearlyReport stockDetail = new YearlyReport();
stockDetail.setSlNo(slNo++);
From 7fc1e8b4782f87ee5fedcf92cc707f3ca7e865ed Mon Sep 17 00:00:00 2001
From: KOPPIREDDY DURGA PRASAD
<144464542+DurgaPrasad-54@users.noreply.github.com>
Date: Thu, 12 Mar 2026 16:04:01 +0530
Subject: [PATCH 2/3] Cherry-pick health and version API enhancements to
release-3.6.1 (#119)
* feat(health,version): add health and version endpoints
* fix(health): removed duplicates from healthservices
* fix: The DEGRADED status was incorrectly returning HTTP 503
* fix(health): run checks concurrently, prevent thread starvation, and harden timeouts
* fix(health): add proper @Deprecated metadata and javadoc for obsolete methods
* fix(health): add proper @Deprecated metadata and javadoc for obsolete methods
* refactor(health): remove obsolete deprecated health check methods
* fix(health): mark timed-out components DOWN and make status maps thread-safe
* fix(health): removed duplicates from health services
* fix(health): harden advanced MySQL checks and throttle execution
* fix(health): harden advanced MySQL checks and reflect DEGRADED status
* fix(health): avoid nested executor deadlock in advanced MySQL checks
* fix(health): scope PROCESSLIST lock-wait check to application DB user
* fix(health): avoid blocking DB I/O under write lock and restore interrupt flag
---
pom.xml | 26 +
.../controller/health/HealthController.java | 86 +++
.../controller/version/VersionController.java | 68 +--
.../service/health/HealthService.java | 544 ++++++++++++++++++
.../utils/JwtUserIdValidationFilter.java | 4 +-
5 files changed, 694 insertions(+), 34 deletions(-)
create mode 100644 src/main/java/com/iemr/inventory/controller/health/HealthController.java
create mode 100644 src/main/java/com/iemr/inventory/service/health/HealthService.java
diff --git a/pom.xml b/pom.xml
index f23f68a5..adf80292 100644
--- a/pom.xml
+++ b/pom.xml
@@ -386,6 +386,32 @@
+
+ io.github.git-commit-id
+ git-commit-id-maven-plugin
+ 9.0.2
+
+
+ get-the-git-infos
+
+ revision
+
+ initialize
+
+
+
+ true
+ ${project.build.outputDirectory}/git.properties
+
+ ^git.branch$
+ ^git.commit.id.abbrev$
+ ^git.build.version$
+ ^git.build.time$
+
+ false
+ false
+
+
org.springframework.boot
spring-boot-maven-plugin
diff --git a/src/main/java/com/iemr/inventory/controller/health/HealthController.java b/src/main/java/com/iemr/inventory/controller/health/HealthController.java
new file mode 100644
index 00000000..59fb160b
--- /dev/null
+++ b/src/main/java/com/iemr/inventory/controller/health/HealthController.java
@@ -0,0 +1,86 @@
+/*
+* 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/.
+*/
+
+package com.iemr.inventory.controller.health;
+
+import java.time.Instant;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.iemr.inventory.service.health.HealthService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+@RestController
+@RequestMapping("/health")
+@Tag(name = "Health Check", description = "APIs for checking infrastructure health status")
+public class HealthController {
+
+ private static final Logger logger = LoggerFactory.getLogger(HealthController.class);
+
+ private final HealthService healthService;
+
+ public HealthController(HealthService healthService) {
+ this.healthService = healthService;
+ }
+
+ @GetMapping
+ @Operation(summary = "Check infrastructure health",
+ description = "Returns the health status of MySQL, Redis, and other configured services")
+ @ApiResponses({
+ @ApiResponse(responseCode = "200", description = "Services are UP or DEGRADED (operational with warnings)"),
+ @ApiResponse(responseCode = "503", description = "One or more critical services are DOWN")
+ })
+ public ResponseEntity