diff --git a/src/main/java/com/iemr/admin/controller/employeemaster/EmployeeMasterController.java b/src/main/java/com/iemr/admin/controller/employeemaster/EmployeeMasterController.java index cfe1979..55bf70c 100644 --- a/src/main/java/com/iemr/admin/controller/employeemaster/EmployeeMasterController.java +++ b/src/main/java/com/iemr/admin/controller/employeemaster/EmployeeMasterController.java @@ -1820,6 +1820,7 @@ public String UserRoleMappings(@RequestBody String userRoleMapping, HttpServletR resDataMap1.setFacilityID(previl.getFacilityID()); resDataMap1.setNikshayTUID(previl.getNikshayTUID()); resDataMap1.setNikshayFacilityID(previl.getNikshayFacilityID()); + resDataMap1.setVanID(previl.getVanID()); resList1.add(resDataMap1); } @@ -1895,6 +1896,7 @@ public String updateUserRoleMapping(@RequestBody String updateUserRoleMapping, H usrRole.setFacilityID(pre.getFacilityID()); usrRole.setNikshayTUID(pre.getNikshayTUID()); usrRole.setNikshayFacilityID(pre.getNikshayFacilityID()); + usrRole.setVanID(pre.getVanID()); if (pre.getTeleConsultation() != null) { usrRole.setTeleConsultation(pre.getTeleConsultation()); diff --git a/src/main/java/com/iemr/admin/controller/nikshay/NikshayLocationController.java b/src/main/java/com/iemr/admin/controller/nikshay/NikshayLocationController.java index aa8d0a8..5678969 100644 --- a/src/main/java/com/iemr/admin/controller/nikshay/NikshayLocationController.java +++ b/src/main/java/com/iemr/admin/controller/nikshay/NikshayLocationController.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -40,7 +41,6 @@ import com.iemr.admin.data.nikshay.NikshayFacility; import com.iemr.admin.data.nikshay.NikshayState; import com.iemr.admin.data.nikshay.NikshayTU; -import com.iemr.admin.data.nikshay.NikshayVillage; import com.iemr.admin.repo.employeemaster.EmployeeMasterRepo; import com.iemr.admin.repo.nikshay.NikshayDistrictRepo; import com.iemr.admin.repo.nikshay.NikshayFacilityRepo; @@ -121,7 +121,7 @@ public String getTUs(@RequestParam("districtID") Integer districtID) { OutputResponse response = new OutputResponse(); try { List tus = nikshayTURepo.findByDistrictID(districtID); - response.setResponse(tus.toString()); + response.setResponse(new Gson().toJson(tus.stream().map(this::toLite).collect(Collectors.toList()))); } catch (Exception e) { logger.error("Error fetching Nikshay TUs for districtID " + districtID + ": " + e.getMessage(), e); response.setError(e); @@ -136,7 +136,7 @@ public String getFacilities(@RequestParam("tuIDs") String tuIDs) { try { List ids = parseIntCsv(tuIDs); List facilities = nikshayFacilityRepo.findByTUIDs(ids); - response.setResponse(facilities.toString()); + response.setResponse(new Gson().toJson(facilities.stream().map(this::toLite).collect(Collectors.toList()))); } catch (Exception e) { logger.error("Error fetching Nikshay facilities for tuIDs " + tuIDs + ": " + e.getMessage(), e); response.setError(e); @@ -150,8 +150,8 @@ public String getVillages(@RequestParam("facilityIDs") String facilityIDs) { OutputResponse response = new OutputResponse(); try { List ids = parseIntCsv(facilityIDs); - List villages = nikshayVillageRepo.findByFacilityIDs(ids); - response.setResponse(villages.toString()); + List villages = nikshayVillageRepo.findLiteByFacilityIDs(ids); + response.setResponse(new Gson().toJson(villages.stream().map(this::toLiteVillage).collect(Collectors.toList()))); } catch (Exception e) { logger.error("Error fetching villages for facilityIDs " + facilityIDs + ": " + e.getMessage(), e); response.setError(e); @@ -174,6 +174,7 @@ public String getUserMappingNikshayData(@RequestParam("usrMappingID") Integer us result.put("districtID", row.getDistrictID()); result.put("nikshayTUID", row.getNikshayTUID()); result.put("nikshayFacilityID", row.getNikshayFacilityID()); + result.put("vanID", row.getVanID()); } response.setResponse(new Gson().toJson(result)); } catch (Exception e) { @@ -183,6 +184,37 @@ public String getUserMappingNikshayData(@RequestParam("usrMappingID") Integer us return response.toString(); } + // TU/Facility/Village lists can run into thousands of rows for a single + // district (e.g. Pune MC: 5,327 facilities), and the full entities carry + // audit fields (createdBy/createdDate/modifiedBy/lastModDate/codes) the + // Admin UI never reads. Send only the ID, name and parent ID each dropdown + // needs — same field names as before, so older UI builds keep working. + private Map toLite(NikshayTU t) { + Map m = new LinkedHashMap<>(); + m.put("nikshayTUID", t.getNikshayTUID()); + m.put("tUName", t.getTUName()); + m.put("nikshayDistrictID", t.getNikshayDistrictID()); + return m; + } + + private Map toLite(NikshayFacility f) { + Map m = new LinkedHashMap<>(); + m.put("nikshayFacilityID", f.getNikshayFacilityID()); + m.put("facilityName", f.getFacilityName()); + m.put("nikshayTUID", f.getNikshayTUID()); + return m; + } + + // row = [nikshayVillageID, villageName, nikshayFacilityID], see + // NikshayVillageRepo.findLiteByFacilityIDs + private Map toLiteVillage(Object[] row) { + Map m = new LinkedHashMap<>(); + m.put("nikshayVillageID", row[0]); + m.put("villageName", row[1]); + m.put("nikshayFacilityID", row[2]); + return m; + } + private List parseIntCsv(String csv) { return Arrays.stream(csv.split(",")) .map(String::trim) diff --git a/src/main/java/com/iemr/admin/controller/stoptbteam/StopTBTeamController.java b/src/main/java/com/iemr/admin/controller/stoptbteam/StopTBTeamController.java new file mode 100644 index 0000000..ff24607 --- /dev/null +++ b/src/main/java/com/iemr/admin/controller/stoptbteam/StopTBTeamController.java @@ -0,0 +1,90 @@ +/* +* 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.admin.controller.stoptbteam; + +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.iemr.admin.service.stoptbteam.StopTBTeamService; +import com.iemr.admin.utils.mapper.OutputMapper; +import com.iemr.admin.utils.response.OutputResponse; + +import io.swagger.v3.oas.annotations.Operation; + +/** Stop TB teams (MMU vans) for Work Location Mapping (AMM-2496). */ +@RestController +@RequestMapping(value = "/stoptb/team") +public class StopTBTeamController { + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + private StopTBTeamService teamService; + + @Operation(summary = "Stop TB teams (MMU vans) of a state") + @GetMapping(value = "/vans", produces = MediaType.APPLICATION_JSON) + public String getStateTeams(@RequestParam("stateID") Integer stateID, + @RequestParam("serviceProviderID") Integer serviceProviderID) { + OutputResponse response = new OutputResponse(); + try { + response.setResponse(OutputMapper.gsonWithoutExpose().toJson(teamService.stateTeams(stateID, serviceProviderID))); + } catch (Exception e) { + logger.error("Stop TB teams for state {} failed", stateID, e); + response.setError(e); + } + return response.toString(); + } + + @Operation(summary = "A Stop TB user's current team") + @GetMapping(value = "/user", produces = MediaType.APPLICATION_JSON) + public String getUserTeam(@RequestParam("userID") Integer userID, + @RequestParam("providerServiceMapID") Integer providerServiceMapID) { + OutputResponse response = new OutputResponse(); + try { + response.setResponse(OutputMapper.gsonWithoutExpose().toJson(teamService.userTeam(userID, providerServiceMapID))); + } catch (Exception e) { + logger.error("Stop TB team of user {} failed", userID, e); + response.setError(e); + } + return response.toString(); + } + + @Operation(summary = "Members of a Stop TB team") + @GetMapping(value = "/members", produces = MediaType.APPLICATION_JSON) + public String getTeamMembers(@RequestParam("vanID") Integer vanID, + @RequestParam("providerServiceMapID") Integer providerServiceMapID) { + OutputResponse response = new OutputResponse(); + try { + response.setResponse(OutputMapper.gsonWithoutExpose().toJson(teamService.teamMembers(vanID, providerServiceMapID))); + } catch (Exception e) { + logger.error("Stop TB team {} members failed", vanID, e); + response.setError(e); + } + return response.toString(); + } +} diff --git a/src/main/java/com/iemr/admin/data/employeemaster/M_UserServiceRoleMapping2.java b/src/main/java/com/iemr/admin/data/employeemaster/M_UserServiceRoleMapping2.java index e33da77..1d54fc9 100644 --- a/src/main/java/com/iemr/admin/data/employeemaster/M_UserServiceRoleMapping2.java +++ b/src/main/java/com/iemr/admin/data/employeemaster/M_UserServiceRoleMapping2.java @@ -435,6 +435,12 @@ public class M_UserServiceRoleMapping2 { @Column(name = "NikshayFacilityID") private String nikshayFacilityID; + // Stop TB team (AMM-2496): the van (camp laptop) the user works with. Same + // value on all of the user's active Stop TB rows; null when not in a team. + @Expose + @Column(name = "VanID") + private Integer vanID; + public M_UserServiceRoleMapping2() { } diff --git a/src/main/java/com/iemr/admin/repo/nikshay/NikshayVillageRepo.java b/src/main/java/com/iemr/admin/repo/nikshay/NikshayVillageRepo.java index 6f0741b..510f229 100644 --- a/src/main/java/com/iemr/admin/repo/nikshay/NikshayVillageRepo.java +++ b/src/main/java/com/iemr/admin/repo/nikshay/NikshayVillageRepo.java @@ -35,4 +35,12 @@ public interface NikshayVillageRepo extends CrudRepository findByFacilityIDs(@Param("facilityIDs") List facilityIDs); + + // Only the three columns the village dropdown uses, as [nikshayVillageID, + // villageName, nikshayFacilityID]. A district can have 1 lakh+ village rows + // (the same village repeated under each facility); loading full entities + // for that was most of the response time. + @Query("select v.nikshayVillageID, v.villageName, v.nikshayFacilityID from NikshayVillage v " + + "where v.nikshayFacilityID in (:facilityIDs) and v.deleted = false order by v.villageName, v.nikshayVillageID") + List findLiteByFacilityIDs(@Param("facilityIDs") List facilityIDs); } diff --git a/src/main/java/com/iemr/admin/repository/stoptbteam/StopTBTeamRepository.java b/src/main/java/com/iemr/admin/repository/stoptbteam/StopTBTeamRepository.java new file mode 100644 index 0000000..f2b1371 --- /dev/null +++ b/src/main/java/com/iemr/admin/repository/stoptbteam/StopTBTeamRepository.java @@ -0,0 +1,138 @@ +/* +* 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.admin.repository.stoptbteam; + +import java.util.List; + +import org.springframework.stereotype.Repository; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; + +/** + * Stop TB teams (AMM-2496). A team is a van; the user's team is the VanID + * on their m_userservicerolemapping rows. Team vans come from one service + * line's vans (MMU today, see stoptb.team.van-service). + */ +@Repository +public class StopTBTeamRepository { + private static String notDeleted(String column) { + return "(" + column + " IS NULL OR " + column + " = b'0')"; + } + + private static final String STOPTB_SERVICE_LINES = + "SELECT p.ProviderServiceMapID FROM m_providerservicemapping p" + + " JOIN m_servicemaster s ON s.ServiceID = p.ServiceID WHERE s.ServiceName = 'Stop TB'"; + + private static final String SELECT_STATE_VANS = + "SELECT v.VanID, v.VanName, v.VehicalNo, v.ParkingPlaceID, pp.ParkingPlaceName" + + " FROM m_van v" + + " JOIN m_providerservicemapping p ON p.ProviderServiceMapID = v.ProviderServiceMapID" + + " JOIN m_servicemaster s ON s.ServiceID = p.ServiceID" + + " LEFT JOIN m_parkingplace pp ON pp.ParkingPlaceID = v.ParkingPlaceID" + + " WHERE s.ServiceName = :vanService AND p.StateID = :stateID" + + " AND p.ServiceProviderID = :serviceProviderID" + + " AND " + notDeleted("p.Deleted") + " AND " + notDeleted("v.Deleted") + + " ORDER BY v.VanName, v.VanID"; + + private static final String SELECT_VAN = + "SELECT v.VanID, p.StateID, p.ServiceProviderID FROM m_van v" + + " JOIN m_providerservicemapping p ON p.ProviderServiceMapID = v.ProviderServiceMapID" + + " JOIN m_servicemaster s ON s.ServiceID = p.ServiceID" + + " WHERE v.VanID = :vanID AND s.ServiceName = :vanService" + + " AND " + notDeleted("p.Deleted") + " AND " + notDeleted("v.Deleted"); + + private static final String SELECT_STOPTB_SERVICE = + "SELECT p.StateID, p.ServiceProviderID FROM m_providerservicemapping p" + + " WHERE p.ProviderServiceMapID = :providerServiceMapID" + + " AND p.ProviderServiceMapID IN (" + STOPTB_SERVICE_LINES + ")"; + + private static final String SELECT_USER_TEAM = + "SELECT m.VanID, v.VanName FROM m_userservicerolemapping m" + + " JOIN m_van v ON v.VanID = m.VanID" + + " WHERE m.UserID = :userID AND m.ProviderServiceMapID = :providerServiceMapID" + + " AND " + notDeleted("m.Deleted") + + " ORDER BY m.LastModDate DESC, m.USRMappingID DESC"; + + private static final String SELECT_TEAM_MEMBERS = + "SELECT DISTINCT u.UserID, u.UserName, u.FirstName, u.LastName FROM m_userservicerolemapping m" + + " JOIN m_user u ON u.UserID = m.UserID" + + " WHERE m.VanID = :vanID AND m.ProviderServiceMapID = :providerServiceMapID" + + " AND " + notDeleted("m.Deleted") + " AND " + notDeleted("u.Deleted") + + " ORDER BY u.UserName"; + + // One team per user: every active Stop TB row of the user gets the same VanID. + private static final String SET_USER_TEAM = + "UPDATE m_userservicerolemapping SET VanID = :vanID" + + " WHERE UserID = :userID AND ProviderServiceMapID = :providerServiceMapID" + + " AND " + notDeleted("Deleted") + + " AND ProviderServiceMapID IN (" + STOPTB_SERVICE_LINES + ")"; + + @PersistenceContext + private EntityManager entityManager; + + /** {VanID, VanName, VehicalNo, ParkingPlaceID, ParkingPlaceName} of the state's team vans. */ + @SuppressWarnings("unchecked") + public List stateVans(String vanService, Integer stateID, Integer serviceProviderID) { + return entityManager.createNativeQuery(SELECT_STATE_VANS).setParameter("vanService", vanService) + .setParameter("stateID", stateID).setParameter("serviceProviderID", serviceProviderID) + .getResultList(); + } + + /** {VanID, StateID, ServiceProviderID} of an active team van, or null. */ + public Object[] van(String vanService, Integer vanID) { + return first(entityManager.createNativeQuery(SELECT_VAN).setParameter("vanService", vanService) + .setParameter("vanID", vanID)); + } + + /** {StateID, ServiceProviderID} when the ID is a Stop TB service line, else null. */ + public Object[] stopTBService(Integer providerServiceMapID) { + return first(entityManager.createNativeQuery(SELECT_STOPTB_SERVICE) + .setParameter("providerServiceMapID", providerServiceMapID)); + } + + /** {VanID, VanName} of the user's team, or null. */ + public Object[] userTeam(Integer userID, Integer providerServiceMapID) { + return first(entityManager.createNativeQuery(SELECT_USER_TEAM).setParameter("userID", userID) + .setParameter("providerServiceMapID", providerServiceMapID)); + } + + /** {UserID, UserName, FirstName, LastName} of the team's members. */ + @SuppressWarnings("unchecked") + public List teamMembers(Integer vanID, Integer providerServiceMapID) { + return entityManager.createNativeQuery(SELECT_TEAM_MEMBERS).setParameter("vanID", vanID) + .setParameter("providerServiceMapID", providerServiceMapID).getResultList(); + } + + /** Puts the user in the team (or none) on all their active Stop TB rows. */ + public int setUserTeam(Integer userID, Integer providerServiceMapID, Integer vanID) { + return entityManager.createNativeQuery(SET_USER_TEAM).setParameter("vanID", vanID) + .setParameter("userID", userID).setParameter("providerServiceMapID", providerServiceMapID) + .executeUpdate(); + } + + private Object[] first(Query query) { + List rows = query.setMaxResults(1).getResultList(); + return rows.isEmpty() ? null : (Object[]) rows.get(0); + } +} diff --git a/src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java b/src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java index 16229ca..365b315 100644 --- a/src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java +++ b/src/main/java/com/iemr/admin/service/employeemaster/EmployeeMasterServiceImpl.java @@ -31,6 +31,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.springframework.web.context.request.RequestContextHolder; @@ -60,6 +61,7 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.JsonParser; +import com.iemr.admin.service.stoptbteam.StopTBTeamService; import com.iemr.admin.data.blocking.M_Providerservicemapping_Blocking; import com.iemr.admin.data.employeemaster.EmployeeSignature; import com.iemr.admin.data.employeemaster.M_Community; @@ -130,6 +132,9 @@ public class EmployeeMasterServiceImpl implements EmployeeMasterInter { @Autowired private M_CommunityRepo m_CommunityRepo; + @Autowired + private StopTBTeamService stopTBTeamService; + @Autowired private M_ReligionRepo m_ReligionRepo; @@ -348,6 +353,7 @@ public ArrayList mapLanguage(List resList) public ArrayList mapRole(List resList1, String authToken) throws JsonMappingException, JsonProcessingException { // Fix 4 + Fix 16 + Fix 17: validate each mapping before any save for (M_UserServiceRoleMapping2 mapping : resList1) { + stopTBTeamService.validateTeam(mapping.getProviderServiceMapID(), mapping.getVanID()); M_Role role = null; if (mapping.getRoleID() != null) { role = roleRepo.findByRoleID(mapping.getRoleID()); @@ -431,6 +437,21 @@ public ArrayList mapRole(List teamRows = new LinkedHashMap<>(); + for (M_UserServiceRoleMapping2 mapping : resList1) { + teamRows.putIfAbsent(mapping.getUserID() + "-" + mapping.getProviderServiceMapID(), mapping); + } + for (M_UserServiceRoleMapping2 mapping : teamRows.values()) { + Integer vanID = mapping.getVanID(); + if (vanID == null) { + Object current = stopTBTeamService.userTeam(mapping.getUserID(), mapping.getProviderServiceMapID()) + .get("vanID"); + vanID = (Integer) current; + } + stopTBTeamService.applyTeam(mapping.getUserID(), mapping.getProviderServiceMapID(), vanID); + } return reslist; } @@ -1125,6 +1146,10 @@ public M_UserServiceRoleMapping2 saveRoleMappingeditedData(M_UserServiceRoleMapp } } + boolean activeRow = !Boolean.TRUE.equals(usrRole.getDeleted()); + if (activeRow) { + stopTBTeamService.validateTeam(usrRole.getProviderServiceMapID(), usrRole.getVanID()); + } M_UserServiceRoleMapping2 data = employeeMasterRepo.save(usrRole); if (ENABLE_CTI_USER_CREATION) { List list = new ArrayList(); @@ -1156,6 +1181,10 @@ public M_UserServiceRoleMapping2 saveRoleMappingeditedData(M_UserServiceRoleMapp M_UserServiceRoleMapping2 savedData = employeeMasterRepo.save(usrRole); } + // Stop TB team (AMM-2496): the same team on all of the user's role rows. + if (activeRow) { + stopTBTeamService.applyTeam(usrRole.getUserID(), usrRole.getProviderServiceMapID(), usrRole.getVanID()); + } return data; } diff --git a/src/main/java/com/iemr/admin/service/stoptbteam/StopTBTeamService.java b/src/main/java/com/iemr/admin/service/stoptbteam/StopTBTeamService.java new file mode 100644 index 0000000..07c4a99 --- /dev/null +++ b/src/main/java/com/iemr/admin/service/stoptbteam/StopTBTeamService.java @@ -0,0 +1,138 @@ +/* +* 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.admin.service.stoptbteam; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.iemr.admin.repository.stoptbteam.StopTBTeamRepository; + +/** + * Stop TB teams for Work Location Mapping (AMM-2496). A team is a van (the + * camp laptop's STOPTB_VAN_ID). A team has many users; a user is in one team, + * stored as VanID on all of their active Stop TB m_userservicerolemapping rows. + */ +@Service +public class StopTBTeamService { + @Autowired + private StopTBTeamRepository teamRepository; + + // Service line whose vans are the teams: MMU today, the Stop TB service + // once it has its own vans. + @Value("${stoptb.team.van-service:MMU}") + private String vanService; + + /** The state's team vans, for the Team dropdown. */ + public List> stateTeams(Integer stateID, Integer serviceProviderID) { + if (stateID == null || serviceProviderID == null) { + throw new IllegalArgumentException("State and service provider are required"); + } + List> teams = new ArrayList<>(); + for (Object[] row : teamRepository.stateVans(vanService, stateID, serviceProviderID)) { + Map team = new LinkedHashMap<>(); + team.put("vanID", toInt(row[0])); + team.put("vanName", row[1]); + team.put("vehicalNo", row[2]); + team.put("parkingPlaceID", toInt(row[3])); + team.put("parkingPlaceName", row[4]); + teams.add(team); + } + return teams; + } + + /** The user's team ({vanID, vanName}), or an empty map. */ + public Map userTeam(Integer userID, Integer providerServiceMapID) { + if (userID == null || providerServiceMapID == null) { + throw new IllegalArgumentException("User and service line are required"); + } + Map team = new LinkedHashMap<>(); + Object[] row = teamRepository.userTeam(userID, providerServiceMapID); + if (row != null) { + team.put("vanID", toInt(row[0])); + team.put("vanName", row[1]); + } + return team; + } + + /** The members of a team under this Stop TB service line. */ + public List> teamMembers(Integer vanID, Integer providerServiceMapID) { + if (vanID == null || providerServiceMapID == null) { + throw new IllegalArgumentException("Team and service line are required"); + } + List> members = new ArrayList<>(); + for (Object[] row : teamRepository.teamMembers(vanID, providerServiceMapID)) { + Map member = new LinkedHashMap<>(); + member.put("userID", toInt(row[0])); + member.put("userName", row[1]); + member.put("firstName", row[2]); + member.put("lastName", row[3]); + members.add(member); + } + return members; + } + + /** + * Checks a mapping's team before it is saved: a team is only allowed on a + * Stop TB service line, and must be a van of that service line's state. + */ + public void validateTeam(Integer providerServiceMapID, Integer vanID) { + if (vanID == null) { + return; + } + Object[] stopTB = providerServiceMapID == null ? null : teamRepository.stopTBService(providerServiceMapID); + if (stopTB == null) { + throw new IllegalArgumentException("A team can only be set on a Stop TB mapping"); + } + Object[] van = teamRepository.van(vanService, vanID); + if (van == null) { + throw new IllegalArgumentException("Team " + vanID + " is not an active " + vanService + " van"); + } + if (!Objects.equals(toInt(van[1]), toInt(stopTB[0])) || !Objects.equals(toInt(van[2]), toInt(stopTB[1]))) { + throw new IllegalArgumentException("Team " + vanID + " is not in this user's state"); + } + } + + /** + * After a Stop TB mapping is saved, gives all of the user's active Stop TB + * rows the same team, so one user is never in two teams. No-op for other + * service lines. + */ + @Transactional(rollbackFor = Exception.class) + public void applyTeam(Integer userID, Integer providerServiceMapID, Integer vanID) { + if (userID == null || providerServiceMapID == null) { + return; + } + teamRepository.setUserTeam(userID, providerServiceMapID, vanID); + } + + private static Integer toInt(Object value) { + return value == null ? null : ((Number) value).intValue(); + } +} diff --git a/src/main/java/com/iemr/admin/to/employeemaster/Previleges1097_3.java b/src/main/java/com/iemr/admin/to/employeemaster/Previleges1097_3.java index 4c6a757..095cbcc 100644 --- a/src/main/java/com/iemr/admin/to/employeemaster/Previleges1097_3.java +++ b/src/main/java/com/iemr/admin/to/employeemaster/Previleges1097_3.java @@ -38,6 +38,16 @@ public class Previleges1097_3 { // M_UserServiceRoleMapping2's NikshayTUID/NikshayFacilityID columns. private String nikshayTUID; private String nikshayFacilityID; + // Stop TB team (van), AMM-2496 + private Integer vanID; + + public Integer getVanID() { + return vanID; + } + + public void setVanID(Integer vanID) { + this.vanID = vanID; + } public Integer getProviderServiceMapID() { return providerServiceMapID;