Skip to content

Commit 27662f6

Browse files
vishwab1claude
andauthored
fix(stoptb): resolve district/block/village against Nikshay masters, not standard AMRIT masters (#444)
Stop TB workers are mapped to Nikshay's own isolated location hierarchy (m_nikshay_district/tu/village), a separate ID space from AMRIT's standard masters (m_district/m_districtblock/m_DistrictBranchMapping). The beneficiary address mapper ignored the districtName/districtBranchName strings sent by mobile and re-derived them by looking the numeric ID up in the standard masters instead, so every Stop TB registration got stamped with whatever unrelated place happened to share that ID (e.g. district 1 -> "Nicobars" instead of "Alluri Sitharama Raju"). Add Nikshay-specific lookup entities/repos and a NikshayAddressResolver that gates on providerServiceMapID -> ServiceName == "Stop TB". Only Stop TB beneficiaries take the Nikshay resolution path; every other service line's address mapping is untouched. Hibernate ddl-auto=none means tenants without the Nikshay tables are unaffected at both startup and runtime, since the new repositories are never queried unless isStopTB is true. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
1 parent e1bde6e commit 27662f6

9 files changed

Lines changed: 359 additions & 20 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* AMRIT – Accessible Medical Records via Integrated Technology
3+
* Integrated EHR (Electronic Health Records) Solution
4+
*
5+
* Copyright (C) "Piramal Swasthya Management and Research Institute"
6+
*
7+
* This file is part of AMRIT.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see https://www.gnu.org/licenses/.
21+
*/
22+
package com.iemr.common.data.location;
23+
24+
import jakarta.persistence.Column;
25+
import jakarta.persistence.Entity;
26+
import jakarta.persistence.Id;
27+
import jakarta.persistence.Table;
28+
import lombok.Data;
29+
30+
/**
31+
* Nikshay's own district master (m_nikshay_district) — an isolated ID space
32+
* from AMRIT's standard m_district, used only for Stop TB location mapping.
33+
*/
34+
@Entity
35+
@Table(name = "m_nikshay_district")
36+
@Data
37+
public class NikshayDistrict {
38+
@Id
39+
@Column(name = "NikshayDistrictID")
40+
private Integer nikshayDistrictID;
41+
42+
@Column(name = "DistrictName")
43+
private String districtName;
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* AMRIT – Accessible Medical Records via Integrated Technology
3+
* Integrated EHR (Electronic Health Records) Solution
4+
*
5+
* Copyright (C) "Piramal Swasthya Management and Research Institute"
6+
*
7+
* This file is part of AMRIT.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see https://www.gnu.org/licenses/.
21+
*/
22+
package com.iemr.common.data.location;
23+
24+
import jakarta.persistence.Column;
25+
import jakarta.persistence.Entity;
26+
import jakarta.persistence.Id;
27+
import jakarta.persistence.Table;
28+
import lombok.Data;
29+
30+
/**
31+
* Nikshay's Tuberculosis Unit master (m_nikshay_tu) — Stop TB's equivalent
32+
* of a "block", but scoped to Nikshay's own hierarchy, not m_districtblock.
33+
*/
34+
@Entity
35+
@Table(name = "m_nikshay_tu")
36+
@Data
37+
public class NikshayTU {
38+
@Id
39+
@Column(name = "NikshayTUID")
40+
private Integer nikshayTUID;
41+
42+
@Column(name = "TUName")
43+
private String tuName;
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* AMRIT – Accessible Medical Records via Integrated Technology
3+
* Integrated EHR (Electronic Health Records) Solution
4+
*
5+
* Copyright (C) "Piramal Swasthya Management and Research Institute"
6+
*
7+
* This file is part of AMRIT.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see https://www.gnu.org/licenses/.
21+
*/
22+
package com.iemr.common.data.location;
23+
24+
import jakarta.persistence.Column;
25+
import jakarta.persistence.Entity;
26+
import jakarta.persistence.Id;
27+
import jakarta.persistence.Table;
28+
import lombok.Data;
29+
30+
/**
31+
* Nikshay's own village master (m_nikshay_village) — an isolated ID space
32+
* from AMRIT's standard m_DistrictBranchMapping, used only for Stop TB.
33+
*/
34+
@Entity
35+
@Table(name = "m_nikshay_village")
36+
@Data
37+
public class NikshayVillage {
38+
@Id
39+
@Column(name = "NikshayVillageID")
40+
private Integer nikshayVillageID;
41+
42+
@Column(name = "VillageName")
43+
private String villageName;
44+
}

src/main/java/com/iemr/common/mapper/CommonIdentityMapperDecorator.java

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@
2929
import com.iemr.common.dto.identity.Identity;
3030
import com.iemr.common.model.beneficiary.BeneficiaryDemographicsModel;
3131
import com.iemr.common.model.beneficiary.BeneficiaryModel;
32+
import com.iemr.common.service.location.NikshayAddressResolver;
3233

3334
public abstract class CommonIdentityMapperDecorator implements CommonIdentityMapper {
35+
@Autowired
36+
NikshayAddressResolver nikshayAddressResolver;
3437
@Autowired
3538
StateMapper stateMapper;
3639
@Autowired
@@ -69,11 +72,13 @@ public CommonIdentityDTO beneficiaryModelCommonIdentityDTO(BeneficiaryModel bene
6972
return null;
7073
}
7174
CommonIdentityDTO commonIdentityDTO = new CommonIdentityDTO();
72-
commonIdentityDTO
73-
.setPermanentAddress(beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics()));
74-
commonIdentityDTO.setCurrentAddress(beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics()));
75-
commonIdentityDTO
76-
.setEmergencyAddress(beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics()));
75+
boolean isStopTB = nikshayAddressResolver.isStopTB(beneficiary.getProviderServiceMapID());
76+
commonIdentityDTO.setPermanentAddress(
77+
beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics(), isStopTB));
78+
commonIdentityDTO.setCurrentAddress(
79+
beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics(), isStopTB));
80+
commonIdentityDTO.setEmergencyAddress(
81+
beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics(), isStopTB));
7782
commonIdentityDTO.setPlaceOfWork(beneficiary.getPlaceOfWork());
7883
commonIdentityDTO.setMarriageDate(beneficiary.getMarriageDate());
7984
commonIdentityDTO.setIsHIVPositive(beneficiary.getIsHIVPos());
@@ -210,6 +215,11 @@ public CommonIdentityDTO beneficiaryModelCommonIdentityDTO(BeneficiaryModel bene
210215
}
211216

212217
protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsModel beneficiaryDemographicsModel) {
218+
return beneficiaryDemographicsModelToAddress(beneficiaryDemographicsModel, false);
219+
}
220+
221+
protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsModel beneficiaryDemographicsModel,
222+
boolean isStopTB) {
213223
if (beneficiaryDemographicsModel == null) {
214224
return null;
215225
}
@@ -222,8 +232,10 @@ protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsM
222232
address.setStateId(beneficiaryDemographicsModel.getStateID());
223233
address.setDistrictId(beneficiaryDemographicsModel.getDistrictID());
224234
if (beneficiaryDemographicsModel.getDistrictID() != null) {
225-
address.setDistrict(
226-
districtMapper.districtToModelByID(beneficiaryDemographicsModel.getDistrictID()).getDistrictName());
235+
address.setDistrict(isStopTB
236+
? nikshayAddressResolver.resolveDistrictName(beneficiaryDemographicsModel.getDistrictID())
237+
: districtMapper.districtToModelByID(beneficiaryDemographicsModel.getDistrictID())
238+
.getDistrictName());
227239
}
228240
address.setServicePointName(beneficiaryDemographicsModel.getServicePointName());
229241
address.setCountry(beneficiaryDemographicsModel.getCountryName());
@@ -239,14 +251,17 @@ protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsM
239251
address.setParkingPlaceID(beneficiaryDemographicsModel.getParkingPlaceID());
240252
address.setServicePointID(beneficiaryDemographicsModel.getServicePointID());
241253
if (beneficiaryDemographicsModel.getDistrictBranchID() != null) {
242-
address.setVillage(branchMapper
243-
.districtBranchToModelByID(beneficiaryDemographicsModel.getDistrictBranchID()).getVillageName());
254+
address.setVillage(isStopTB
255+
? nikshayAddressResolver.resolveVillageName(beneficiaryDemographicsModel.getDistrictBranchID())
256+
: branchMapper.districtBranchToModelByID(beneficiaryDemographicsModel.getDistrictBranchID())
257+
.getVillageName());
244258
}
245259
address.setSubDistrictId(beneficiaryDemographicsModel.getBlockID());
246260
address.setCountryId(beneficiaryDemographicsModel.getCountryID());
247261
if (beneficiaryDemographicsModel.getBlockID() != null) {
248-
address.setSubDistrict(
249-
blockMapper.districtBlockToModelByID(beneficiaryDemographicsModel.getBlockID()).getBlockName());
262+
address.setSubDistrict(isStopTB
263+
? nikshayAddressResolver.resolveTUName(beneficiaryDemographicsModel.getBlockID())
264+
: blockMapper.districtBlockToModelByID(beneficiaryDemographicsModel.getBlockID()).getBlockName());
250265
}
251266
address.setGpsLatitude(beneficiaryDemographicsModel.getLatitude());
252267
address.setGpsLongitude(beneficiaryDemographicsModel.getLongitude());

src/main/java/com/iemr/common/mapper/IdentityBenEditMapperDecorator.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@
3333
import com.iemr.common.model.beneficiary.BenPhoneMapModel;
3434
import com.iemr.common.model.beneficiary.BeneficiaryDemographicsModel;
3535
import com.iemr.common.model.beneficiary.BeneficiaryModel;
36+
import com.iemr.common.service.location.NikshayAddressResolver;
3637

3738
public abstract class IdentityBenEditMapperDecorator implements IdentityBenEditMapper {
39+
@Autowired
40+
NikshayAddressResolver nikshayAddressResolver;
3841
@Autowired
3942
StateMapper stateMapper;
4043
@Autowired
@@ -69,6 +72,11 @@ public abstract class IdentityBenEditMapperDecorator implements IdentityBenEditM
6972
MaritalStatusMapper maritalStatusMapper;
7073

7174
protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsModel beneficiaryDemographicsModel) {
75+
return beneficiaryDemographicsModelToAddress(beneficiaryDemographicsModel, false);
76+
}
77+
78+
protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsModel beneficiaryDemographicsModel,
79+
boolean isStopTB) {
7280
if (beneficiaryDemographicsModel == null) {
7381
return null;
7482
}
@@ -81,8 +89,10 @@ protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsM
8189
address.setStateId(beneficiaryDemographicsModel.getStateID());
8290
address.setDistrictId(beneficiaryDemographicsModel.getDistrictID());
8391
if (beneficiaryDemographicsModel.getDistrictID() != null) {
84-
address.setDistrict(
85-
districtMapper.districtToModelByID(beneficiaryDemographicsModel.getDistrictID()).getDistrictName());
92+
address.setDistrict(isStopTB
93+
? nikshayAddressResolver.resolveDistrictName(beneficiaryDemographicsModel.getDistrictID())
94+
: districtMapper.districtToModelByID(beneficiaryDemographicsModel.getDistrictID())
95+
.getDistrictName());
8696
}
8797
address.setServicePointName(beneficiaryDemographicsModel.getServicePointName());
8898
address.setCountry(beneficiaryDemographicsModel.getCountryName());
@@ -98,14 +108,17 @@ protected Address beneficiaryDemographicsModelToAddress(BeneficiaryDemographicsM
98108
address.setParkingPlaceID(beneficiaryDemographicsModel.getParkingPlaceID());
99109
address.setServicePointID(beneficiaryDemographicsModel.getServicePointID());
100110
if (beneficiaryDemographicsModel.getDistrictBranchID() != null) {
101-
address.setVillage(branchMapper
102-
.districtBranchToModelByID(beneficiaryDemographicsModel.getDistrictBranchID()).getVillageName());
111+
address.setVillage(isStopTB
112+
? nikshayAddressResolver.resolveVillageName(beneficiaryDemographicsModel.getDistrictBranchID())
113+
: branchMapper.districtBranchToModelByID(beneficiaryDemographicsModel.getDistrictBranchID())
114+
.getVillageName());
103115
}
104116
address.setSubDistrictId(beneficiaryDemographicsModel.getBlockID());
105117
address.setCountryId(beneficiaryDemographicsModel.getCountryID());
106118
if (beneficiaryDemographicsModel.getBlockID() != null) {
107-
address.setSubDistrict(
108-
blockMapper.districtBlockToModelByID(beneficiaryDemographicsModel.getBlockID()).getBlockName());
119+
address.setSubDistrict(isStopTB
120+
? nikshayAddressResolver.resolveTUName(beneficiaryDemographicsModel.getBlockID())
121+
: blockMapper.districtBlockToModelByID(beneficiaryDemographicsModel.getBlockID()).getBlockName());
109122
}
110123
address.setGpsLatitude(beneficiaryDemographicsModel.getLatitude());
111124
address.setGpsLongitude(beneficiaryDemographicsModel.getLongitude());
@@ -124,9 +137,13 @@ public IdentityEditDTO BenToIdentityEditMapper(BeneficiaryModel beneficiary) {
124137
}
125138

126139
IdentityEditDTO identityEditDTO = new IdentityEditDTO();
127-
identityEditDTO.setPermanentAddress(beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics()));
128-
identityEditDTO.setCurrentAddress(beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics()));
129-
identityEditDTO.setEmergencyAddress(beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics()));
140+
boolean isStopTB = nikshayAddressResolver.isStopTB(beneficiary.getProviderServiceMapID());
141+
identityEditDTO.setPermanentAddress(
142+
beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics(), isStopTB));
143+
identityEditDTO.setCurrentAddress(
144+
beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics(), isStopTB));
145+
identityEditDTO.setEmergencyAddress(
146+
beneficiaryDemographicsModelToAddress(beneficiary.getI_bendemographics(), isStopTB));
130147
identityEditDTO.setPlaceOfWork(beneficiary.getPlaceOfWork());
131148
identityEditDTO.setMarriageDate(beneficiary.getMarriageDate());
132149
identityEditDTO.setIsHIVPositive(beneficiary.getIsHIVPos());
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* AMRIT – Accessible Medical Records via Integrated Technology
3+
* Integrated EHR (Electronic Health Records) Solution
4+
*
5+
* Copyright (C) "Piramal Swasthya Management and Research Institute"
6+
*
7+
* This file is part of AMRIT.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see https://www.gnu.org/licenses/.
21+
*/
22+
package com.iemr.common.repository.location;
23+
24+
import org.springframework.data.repository.CrudRepository;
25+
import org.springframework.stereotype.Repository;
26+
27+
import com.iemr.common.data.location.NikshayDistrict;
28+
29+
@Repository
30+
public interface NikshayDistrictRepository extends CrudRepository<NikshayDistrict, Integer> {
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* AMRIT – Accessible Medical Records via Integrated Technology
3+
* Integrated EHR (Electronic Health Records) Solution
4+
*
5+
* Copyright (C) "Piramal Swasthya Management and Research Institute"
6+
*
7+
* This file is part of AMRIT.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see https://www.gnu.org/licenses/.
21+
*/
22+
package com.iemr.common.repository.location;
23+
24+
import org.springframework.data.repository.CrudRepository;
25+
import org.springframework.stereotype.Repository;
26+
27+
import com.iemr.common.data.location.NikshayTU;
28+
29+
@Repository
30+
public interface NikshayTURepository extends CrudRepository<NikshayTU, Integer> {
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* AMRIT – Accessible Medical Records via Integrated Technology
3+
* Integrated EHR (Electronic Health Records) Solution
4+
*
5+
* Copyright (C) "Piramal Swasthya Management and Research Institute"
6+
*
7+
* This file is part of AMRIT.
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU General Public License
20+
* along with this program. If not, see https://www.gnu.org/licenses/.
21+
*/
22+
package com.iemr.common.repository.location;
23+
24+
import org.springframework.data.repository.CrudRepository;
25+
import org.springframework.stereotype.Repository;
26+
27+
import com.iemr.common.data.location.NikshayVillage;
28+
29+
@Repository
30+
public interface NikshayVillageRepository extends CrudRepository<NikshayVillage, Integer> {
31+
}

0 commit comments

Comments
 (0)