records) {
+ this.records = records;
+ }
+
+ public boolean isMasterTable() {
+ return tableType == null || DownSyncTableDetail.TABLE_TYPE_MASTER.equalsIgnoreCase(tableType);
+ }
+}
diff --git a/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncRecordAck.java b/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncRecordAck.java
new file mode 100644
index 00000000..e0de23c2
--- /dev/null
+++ b/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncRecordAck.java
@@ -0,0 +1,104 @@
+/*
+* 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.mmu.data.syncActivity_syncLayer;
+
+import com.google.gson.annotations.Expose;
+
+public class DownSyncRecordAck {
+
+ public static final String STATUS_PROCESSED = "P";
+ public static final String STATUS_FAILED = "F";
+ public static final String STATUS_RETRY = "U";
+ public static final String CONFLICT = "CONFLICT";
+
+ @Expose
+ private Long centralID;
+ @Expose
+ private Long vanSerialNo;
+ @Expose
+ private String status;
+ @Expose
+ private String failureReason;
+
+ public DownSyncRecordAck() {
+ }
+
+ public DownSyncRecordAck(Long centralID, Long vanSerialNo, String status, String failureReason) {
+ this.centralID = centralID;
+ this.vanSerialNo = vanSerialNo;
+ this.status = status;
+ this.failureReason = failureReason;
+ }
+
+ public static DownSyncRecordAck success(Long centralID, Long vanSerialNo) {
+ return new DownSyncRecordAck(centralID, vanSerialNo, STATUS_PROCESSED, null);
+ }
+
+ public static DownSyncRecordAck failure(Long centralID, Long vanSerialNo, String failureReason) {
+ return new DownSyncRecordAck(centralID, vanSerialNo, STATUS_FAILED, failureReason);
+ }
+
+
+ public static DownSyncRecordAck retryable(Long centralID, Long vanSerialNo, String failureReason) {
+ return new DownSyncRecordAck(centralID, vanSerialNo, STATUS_RETRY, failureReason);
+ }
+
+ public boolean isRetryable() {
+ return STATUS_RETRY.equalsIgnoreCase(status);
+ }
+
+ public boolean isSuccess() {
+ return STATUS_PROCESSED.equalsIgnoreCase(status);
+ }
+
+ public Long getCentralID() {
+ return centralID;
+ }
+
+ public void setCentralID(Long centralID) {
+ this.centralID = centralID;
+ }
+
+ public Long getVanSerialNo() {
+ return vanSerialNo;
+ }
+
+ public void setVanSerialNo(Long vanSerialNo) {
+ this.vanSerialNo = vanSerialNo;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getFailureReason() {
+ return failureReason;
+ }
+
+ public void setFailureReason(String failureReason) {
+ this.failureReason = failureReason;
+ }
+}
diff --git a/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncTableDetail.java b/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncTableDetail.java
new file mode 100644
index 00000000..1e22fdb6
--- /dev/null
+++ b/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncTableDetail.java
@@ -0,0 +1,215 @@
+/*
+* 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.mmu.data.syncActivity_syncLayer;
+
+import com.google.gson.annotations.Expose;
+
+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 jakarta.persistence.Transient;
+
+/***
+ * Down-sync table configuration (central -> local). Analogous to
+ * {@link SyncUtilityClass} (m_synctabledetail) which drives the up-sync.
+ */
+@Entity
+@Table(name = "m_downsynctabledetail")
+public class DownSyncTableDetail {
+
+ public static final String TABLE_TYPE_MASTER = "MASTER";
+ public static final String TABLE_TYPE_TRANSACTIONAL = "TRANSACTIONAL";
+ public static final String LAST_MOD_COLUMN = "LastModDate";
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Expose
+ @Column(name = "DownSyncTableDetailID", updatable = false)
+ private Integer downSyncTableDetailID;
+ @Expose
+ @Column(name = "SchemaName")
+ private String schemaName;
+ @Expose
+ @Column(name = "TableName")
+ private String tableName;
+ /** columns to SELECT from central */
+ @Expose
+ @Column(name = "ServerColumnName")
+ private String serverColumnName;
+ /** columns in local, positionally mapped with {@link #serverColumnName} */
+ @Expose
+ @Column(name = "VanColumnName")
+ private String vanColumnName;
+ /** local auto-increment PK column - skipped on INSERT */
+ @Expose
+ @Column(name = "VanAutoIncColumnName")
+ private String vanAutoIncColumnName;
+ /** MASTER = full pull, no VanID filter / TRANSACTIONAL = VanID + DownSynced filter */
+ @Expose
+ @Column(name = "TableType")
+ private String tableType;
+
+ @Expose
+ @Column(name = "FkColumnMapping")
+ private String fkColumnMapping;
+
+ @Expose
+ @Column(name = "PreserveCentralPK")
+ private Boolean preserveCentralPK;
+
+
+ @Expose
+ @Column(name = "SyncOrder")
+ private Integer syncOrder;
+ @Expose
+ @Column(name = "IsActive")
+ private Boolean isActive;
+
+ @Transient
+ @Expose
+ private Integer vanID;
+ @Transient
+ @Expose
+ private Integer providerServiceMapID;
+
+ public DownSyncTableDetail() {
+ }
+
+ public boolean isMasterTable() {
+ return tableType == null || TABLE_TYPE_MASTER.equalsIgnoreCase(tableType);
+ }
+
+ public boolean isTransactionalTable() {
+ return TABLE_TYPE_TRANSACTIONAL.equalsIgnoreCase(tableType);
+ }
+
+ public Integer getDownSyncTableDetailID() {
+ return downSyncTableDetailID;
+ }
+
+ public void setDownSyncTableDetailID(Integer downSyncTableDetailID) {
+ this.downSyncTableDetailID = downSyncTableDetailID;
+ }
+
+ public String getSchemaName() {
+ return schemaName;
+ }
+
+ public void setSchemaName(String schemaName) {
+ this.schemaName = schemaName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getServerColumnName() {
+ return serverColumnName;
+ }
+
+ public void setServerColumnName(String serverColumnName) {
+ this.serverColumnName = serverColumnName;
+ }
+
+ public String getVanColumnName() {
+ return vanColumnName;
+ }
+
+ public void setVanColumnName(String vanColumnName) {
+ this.vanColumnName = vanColumnName;
+ }
+
+ public String getLastModColumnName() {
+ return LAST_MOD_COLUMN;
+ }
+
+ public String getVanAutoIncColumnName() {
+ return vanAutoIncColumnName;
+ }
+
+ public void setVanAutoIncColumnName(String vanAutoIncColumnName) {
+ this.vanAutoIncColumnName = vanAutoIncColumnName;
+ }
+
+ public boolean isPreserveCentralPK() {
+ return Boolean.TRUE.equals(preserveCentralPK);
+ }
+
+ public void setPreserveCentralPK(Boolean preserveCentralPK) {
+ this.preserveCentralPK = preserveCentralPK;
+ }
+
+ public String getFkColumnMapping() {
+ return fkColumnMapping;
+ }
+
+ public void setFkColumnMapping(String fkColumnMapping) {
+ this.fkColumnMapping = fkColumnMapping;
+ }
+
+ public String getTableType() {
+ return tableType;
+ }
+
+ public void setTableType(String tableType) {
+ this.tableType = tableType;
+ }
+
+ public Integer getSyncOrder() {
+ return syncOrder;
+ }
+
+ public void setSyncOrder(Integer syncOrder) {
+ this.syncOrder = syncOrder;
+ }
+
+ public Boolean getIsActive() {
+ return isActive;
+ }
+
+ public void setIsActive(Boolean isActive) {
+ this.isActive = isActive;
+ }
+
+ public Integer getVanID() {
+ return vanID;
+ }
+
+ public void setVanID(Integer vanID) {
+ this.vanID = vanID;
+ }
+
+ public Integer getProviderServiceMapID() {
+ return providerServiceMapID;
+ }
+
+ public void setProviderServiceMapID(Integer providerServiceMapID) {
+ this.providerServiceMapID = providerServiceMapID;
+ }
+}
diff --git a/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncTableResult.java b/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncTableResult.java
new file mode 100644
index 00000000..a9691fbb
--- /dev/null
+++ b/src/main/java/com/iemr/mmu/data/syncActivity_syncLayer/DownSyncTableResult.java
@@ -0,0 +1,171 @@
+/*
+* 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.mmu.data.syncActivity_syncLayer;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.google.gson.annotations.Expose;
+
+/***
+ * The outcome of down-syncing one table, reported to the screen.
+ *
+ *
+ * A table can fail in two quite different ways and the difference matters when
+ * reading the result:
+ *
+ *
+ * - the table itself failed - central could not even return the rows (a schema
+ * mismatch, say), so nothing was delivered and no record was flagged;
+ * - the table was delivered but individual records failed, in which case the
+ * table shows a record failure count and each distinct reason with a tally.
+ *
+ */
+public class DownSyncTableResult {
+
+ public static final String STATUS_SUCCESS = "SUCCESS";
+ public static final String STATUS_FAILED = "FAILED";
+ public static final String STATUS_PARTIAL = "PARTIAL";
+ public static final String STATUS_CONFLICT = "CONFLICT";
+
+ @Expose
+ private String groupName;
+ @Expose
+ private String schemaName;
+ @Expose
+ private String tableName;
+ @Expose
+ private String status;
+ @Expose
+ private int inserted;
+ @Expose
+ private int updated;
+ @Expose
+ private int skipped;
+ @Expose
+ private int conflicts;
+ @Expose
+ private int failedRecords;
+ /** why the table as a whole failed; null when the table itself was fine */
+ @Expose
+ private String failureReason;
+ /** distinct record-level failure reasons, each with the number of records */
+ @Expose
+ private Map recordFailureReasons = new LinkedHashMap<>();
+ private Map recordWarnings = new LinkedHashMap<>();
+
+ public DownSyncTableResult(String groupName, String schemaName, String tableName) {
+ this.groupName = groupName;
+ this.schemaName = schemaName;
+ this.tableName = tableName;
+ this.status = STATUS_SUCCESS;
+ }
+
+ /** the table could not be processed at all - nothing was delivered */
+ public void tableFailed(String reason) {
+ this.status = STATUS_FAILED;
+ this.failureReason = reason;
+ }
+
+ /** one record failed; the table itself is fine unless every record failed */
+ public void recordFailed(String reason) {
+ this.failedRecords++;
+ String key = (reason == null || reason.trim().isEmpty()) ? "Unknown error" : reason.trim();
+ recordFailureReasons.merge(key, 1, Integer::sum);
+ if (STATUS_SUCCESS.equals(this.status))
+ this.status = STATUS_PARTIAL;
+ }
+
+ public void recordWarning(String reason) {
+ recordWarnings.merge(reason, 1, Integer::sum);
+ }
+
+ public Map getRecordWarnings() {
+ return recordWarnings;
+ }
+
+ public int getRecordsProcessed() {
+ return inserted + updated + skipped + conflicts + failedRecords;
+ }
+
+ public void addInserted() {
+ inserted++;
+ }
+
+ public void addUpdated() {
+ updated++;
+ }
+
+ public void addSkipped() {
+ skipped++;
+ }
+
+ public void addConflict() {
+ conflicts++;
+ if (STATUS_SUCCESS.equals(this.status))
+ this.status = STATUS_CONFLICT;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public String getSchemaName() {
+ return schemaName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public int getInserted() {
+ return inserted;
+ }
+
+ public int getUpdated() {
+ return updated;
+ }
+
+ public int getSkipped() {
+ return skipped;
+ }
+
+ public int getConflicts() {
+ return conflicts;
+ }
+
+ public int getFailedRecords() {
+ return failedRecords;
+ }
+
+ public String getFailureReason() {
+ return failureReason;
+ }
+
+ public Map getRecordFailureReasons() {
+ return recordFailureReasons;
+ }
+}
diff --git a/src/main/java/com/iemr/mmu/repo/login/UserLoginRepo.java b/src/main/java/com/iemr/mmu/repo/login/UserLoginRepo.java
index 6f6390ee..d14e3c3f 100644
--- a/src/main/java/com/iemr/mmu/repo/login/UserLoginRepo.java
+++ b/src/main/java/com/iemr/mmu/repo/login/UserLoginRepo.java
@@ -15,6 +15,9 @@ public interface UserLoginRepo extends CrudRepository {
@Query(" SELECT u FROM Users u WHERE u.userID = :userID AND u.deleted = false ")
public Users getUserByUserID(@Param("userID") Long userID);
+ @Query(" SELECT u FROM Users u WHERE u.userName = :UserName AND u.deleted = false ")
+ public Users getUserByUsername(@Param("UserName") String username);
+
@Query(nativeQuery = true,value = "select rolename from m_role where roleid in (select roleid from m_userservicerolemapping where userid=:userID)")
List getRoleNamebyUserId(@Param("userID") Long userID);
diff --git a/src/main/java/com/iemr/mmu/repo/nurse/BenVisitDetailRepo.java b/src/main/java/com/iemr/mmu/repo/nurse/BenVisitDetailRepo.java
index c4a03286..75d075f9 100644
--- a/src/main/java/com/iemr/mmu/repo/nurse/BenVisitDetailRepo.java
+++ b/src/main/java/com/iemr/mmu/repo/nurse/BenVisitDetailRepo.java
@@ -101,4 +101,16 @@ public int updateFileID(@Param("fileIDs") String fileIDs, @Param("regID") Long r
@Query(" UPDATE BeneficiaryVisitDetail set vanSerialNo = :benVisitID WHERE benVisitID = :benVisitID")
int updateVanSerialNo(@Param("benVisitID") Long benVisitID);
+ // store responsible doctor's user ID against the visit
+ @Transactional
+ @Modifying
+ @Query("UPDATE BeneficiaryVisitDetail set doctorID = :doctorID where visitCode = :visitCode ")
+ public Integer updateDoctorID(@Param("doctorID") Long doctorID, @Param("visitCode") Long visitCode);
+
+ // store responsible lab technician's user ID against the visit
+ @Transactional
+ @Modifying
+ @Query("UPDATE BeneficiaryVisitDetail set labTechnicianID = :labTechnicianID where visitCode = :visitCode ")
+ public Integer updateLabTechnicianID(@Param("labTechnicianID") Long labTechnicianID, @Param("visitCode") Long visitCode);
+
}
diff --git a/src/main/java/com/iemr/mmu/repo/syncActivity_syncLayer/DownSyncTableDetailRepo.java b/src/main/java/com/iemr/mmu/repo/syncActivity_syncLayer/DownSyncTableDetailRepo.java
new file mode 100644
index 00000000..683bb10a
--- /dev/null
+++ b/src/main/java/com/iemr/mmu/repo/syncActivity_syncLayer/DownSyncTableDetailRepo.java
@@ -0,0 +1,41 @@
+/*
+* 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.mmu.repo.syncActivity_syncLayer;
+
+import java.util.ArrayList;
+
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import com.iemr.mmu.data.syncActivity_syncLayer.DownSyncTableDetail;
+
+@Repository
+public interface DownSyncTableDetailRepo extends CrudRepository {
+
+ @Query(" SELECT d FROM DownSyncTableDetail d WHERE d.isActive = true ORDER BY d.syncOrder, d.downSyncTableDetailID ")
+ ArrayList getActiveDownSyncTables();
+
+ @Query(" SELECT d FROM DownSyncTableDetail d WHERE d.isActive = true AND lower(d.tableName) = lower(:tableName) ")
+ ArrayList getActiveDownSyncTableByName(@Param("tableName") String tableName);
+}
diff --git a/src/main/java/com/iemr/mmu/service/common/transaction/CommonDoctorServiceImpl.java b/src/main/java/com/iemr/mmu/service/common/transaction/CommonDoctorServiceImpl.java
index cab7a2d3..7302abc4 100644
--- a/src/main/java/com/iemr/mmu/service/common/transaction/CommonDoctorServiceImpl.java
+++ b/src/main/java/com/iemr/mmu/service/common/transaction/CommonDoctorServiceImpl.java
@@ -115,6 +115,34 @@ public class CommonDoctorServiceImpl {
@Autowired
private CookieUtil cookieUtil;
+ @Autowired
+ private com.iemr.mmu.repo.nurse.BenVisitDetailRepo benVisitDetailRepo;
+ @Autowired
+ private com.iemr.mmu.repo.login.UserLoginRepo userLoginRepo;
+
+ /**
+ * Resolve the numeric user ID of the responsible staff member from the username
+ * captured in createdBy. Returns null if it cannot be resolved so an unknown
+ * staff member never blocks the flow.
+ */
+ private Long resolveUserId(String username) {
+ if (username == null || username.trim().isEmpty())
+ return null;
+ com.iemr.mmu.data.login.Users user = userLoginRepo.getUserByUsername(username.trim());
+ return user != null ? user.getUserID() : null;
+ }
+
+ /**
+ * Store the responsible doctor's user ID on the visit record, taken from createdBy.
+ */
+ private void storeDoctorIDOnVisit(CommonUtilityClass commonUtilityClass) {
+ if (commonUtilityClass == null || commonUtilityClass.getVisitCode() == null)
+ return;
+ Long doctorID = resolveUserId(commonUtilityClass.getCreatedBy());
+ if (doctorID != null)
+ benVisitDetailRepo.updateDoctorID(doctorID, commonUtilityClass.getVisitCode());
+ }
+
@Autowired
public void setSnomedServiceImpl(SnomedServiceImpl snomedServiceImpl) {
this.snomedServiceImpl = snomedServiceImpl;
@@ -778,6 +806,9 @@ public int updateBenFlowtableAfterDocDataSave(CommonUtilityClass commonUtilityCl
Long tmpBenVisitID = commonUtilityClass.getBenVisitID();
Long tmpbeneficiaryRegID = commonUtilityClass.getBeneficiaryRegID();
+ // Store the responsible doctor's user ID against the visit
+ storeDoctorIDOnVisit(commonUtilityClass);
+
// checking if test is prescribed
if (isTestPrescribed) {
docFlag = (short) 2;
@@ -840,6 +871,9 @@ public int updateBenFlowtableAfterDocDataUpdate(CommonUtilityClass commonUtility
Long tmpBenVisitID = commonUtilityClass.getBenVisitID();
Long tmpbeneficiaryRegID = commonUtilityClass.getBeneficiaryRegID();
+ // Store the responsible doctor's user ID against the visit
+ storeDoctorIDOnVisit(commonUtilityClass);
+
if (commonUtilityClass.getIsSpecialist() != null && commonUtilityClass.getIsSpecialist() == true) {
if (isTestPrescribed)
tcSpecialistFlag = (short) 2;
diff --git a/src/main/java/com/iemr/mmu/service/common/transaction/CommonNurseServiceImpl.java b/src/main/java/com/iemr/mmu/service/common/transaction/CommonNurseServiceImpl.java
index 72e3c8f2..a7efa9d4 100644
--- a/src/main/java/com/iemr/mmu/service/common/transaction/CommonNurseServiceImpl.java
+++ b/src/main/java/com/iemr/mmu/service/common/transaction/CommonNurseServiceImpl.java
@@ -145,6 +145,22 @@ public class CommonNurseServiceImpl implements CommonNurseService {
private Integer TMReferredWL;
@Autowired
private BenVisitDetailRepo benVisitDetailRepo;
+
+ @Autowired
+ private com.iemr.mmu.repo.login.UserLoginRepo userLoginRepo;
+
+ /**
+ * Resolve the numeric user ID of the responsible staff member from the username
+ * captured in createdBy. Returns null if it cannot be resolved so an unknown
+ * staff member never blocks the save.
+ */
+ private Long resolveUserId(String username) {
+ if (username == null || username.trim().isEmpty())
+ return null;
+ com.iemr.mmu.data.login.Users user = userLoginRepo.getUserByUsername(username.trim());
+ return user != null ? user.getUserID() : null;
+ }
+
@Autowired
private BenChiefComplaintRepo benChiefComplaintRepo;
@Autowired
@@ -258,6 +274,10 @@ public Long saveBeneficiaryVisitDetails(BeneficiaryVisitDetail beneficiaryVisitD
}
beneficiaryVisitDetail.setReportFilePath(sb.toString());
+ // Store the responsible nurse's user ID (resolved from the createdBy username)
+ if (beneficiaryVisitDetail.getNurseID() == null)
+ beneficiaryVisitDetail.setNurseID(resolveUserId(beneficiaryVisitDetail.getCreatedBy()));
+
response = benVisitDetailRepo.save(beneficiaryVisitDetail);
benVisitDetailRepo.updateVanSerialNo(response.getBenVisitID());
diff --git a/src/main/java/com/iemr/mmu/service/dataSyncActivity/DataSyncRepository.java b/src/main/java/com/iemr/mmu/service/dataSyncActivity/DataSyncRepository.java
index dc36c7c1..75a74842 100644
--- a/src/main/java/com/iemr/mmu/service/dataSyncActivity/DataSyncRepository.java
+++ b/src/main/java/com/iemr/mmu/service/dataSyncActivity/DataSyncRepository.java
@@ -23,9 +23,12 @@
import java.sql.Timestamp;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.sql.PreparedStatement;
+
import javax.sql.DataSource;
import org.slf4j.Logger;
@@ -33,9 +36,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;
import com.iemr.mmu.repo.syncActivity_syncLayer.SyncUtilityClassRepo;
+import com.iemr.mmu.utils.validator.SqlIdentifierValidator;
/***
*
@@ -137,4 +143,239 @@ public int[] updateLatestMasterInLocal(String query, List