Skip to content

Commit

Permalink
New Entities and APIs related to CHO mobile application (#83)
Browse files Browse the repository at this point in the history
* Fixed the NoSuchMethodException encountered while deployment.  Needed to add a no-arg constructor as the class instance was getting created using reflection by jboss.

* Removed the extra FhirRestfulServer constructor.

* Corrected the indentation.

* Corrected the indentation.

* Implement update geolocation for a village (#24)

* Implement update geolocation for a village

* Update geolocation API infos

* get geolocations data when retrieving village

* Create a new constructor when retrieving village

---------

Co-authored-by: Babacar Ndiaye <[email protected]>

* Beneficiary sync (#26)

* 1) Created wrapper API to sync beneficiaries from CHO app to AMRIT server that returns both beneficiaryID and beneficiaryRegID.
2) Handled exceptions. Instead of returning custom error codes & 200 as HTTP status code , now sending appropriate HTTP status codes with message in response body.

* 1. Created API to down-sync beneficiaries (new and updated both) from AMRIT server to CHO App.
2. Handled exceptions as well.
3. Changed searchSyncLocation url for Identity service.
4. Created a new request object with villageID and lastSyncDate.

* Beneficiary flow status records sync (#27)


* 1. Created API to down-sync beneficiaries flow status records (new and updated both) from AMRIT server to CHO App.
2. Handled exceptions as well.

* Implement save fingerprints for a user (#25)

* Implement save fingerprints for a user

* HTTP Request method changed to POST from GET (#28)


* Changed request method for down-sync APIs to POST from GET. Swagger doesn't read request body for GET calls.

* Modified API to sync beneficiaries and flow records based on villageId list instead of a single villageId.

* Modified App-server syncing APIs . Sending response object 'Output response' while sync ben to server. Serialising nulls as well while down syncing.

* Add one other field address (#31)



* Update geolocation API infos

* Changed serviceID and visitCategoryId to 9 as suggested. Referred commit 'f98d6361' done by 'KA40094929' for the same.

* 1) Removed Authorization from response header.
2) Used existing method to create gson with null serialisation instead of new gson builder instance creation.

* 1) Created entity to save user activity logs.
2) Created API to save/sync logs from App to server.
3) Handled exceptions.

* Add APIs to get and set the master villageID without auth (#33)


Add APIs to get and set the master villageID without auth
Refactor DDL

* Created API to get beneficiary nurse form data (visit details , chief complaints , vitals , history and examination) based on benRegID and visitCode to sync to App.

* 1) Removed benAdherence from response while down syncing nurse data.
2) Created entity outreach master.
3) API to get outreaches in a state.

* Added wrapper API to return visitId also in response while saving nurse data on server . Used Existing API to save nurse data , modified the response in this new API.

* Made changes to fix getLocDetails API.

* Added field to save user image (in case of outreach login) in user activity logs entity.Corresponding changes in service logic as well.

* Modified and refactored APIs to set, get master village of a user. Added field 'loginDistance' to master district branch mapping entity.

* Changed response while setting location coordinates for a village.

* Changes suggested by Ravi(Wipro).Added userID field in view getVanLocDetails.Corresponding changes in getLocDetailsBasedOnSpIDAndPsmIDNew API.

* 1) Added entity to save prescription templates.
2) APIs to upload and fetch templates.

* Added field 'isOutOfReach' in user activity logs table. It will act as a flag when user logs in outside the HWC range.

* API to delete prescription templates.Removed unique constraint in template entity.

* Corrected ben visit detail repo call to get graph data for generalOPD doctor data.

* Added APis to get count of beneficiaries and ben flow records to be synced from Server to App. To be used to show progress bar in the app.

* Corrected the URl for APi to get beneficiary count.

* Created daily outreach activity entity,repo and APIs related to it.

* Added Identity-API url to get count of beneficiaries in all the properties files.

* Removed duplicate columns of userID from V_getVanLocDetails.

* CHOAppSyncController - Request header vulnerability fix.

* -Added Copyright headers to new files.
-Removed commented code.
-Changes envs in common_ci.properties as suggested by Dr. Mithun.

---------

Co-authored-by: roopesh-beehyv <[email protected]>
Co-authored-by: babstar93 <[email protected]>
Co-authored-by: Babacar Ndiaye <[email protected]>
  • Loading branch information
4 people authored Feb 9, 2024
1 parent c89bb92 commit aa22386
Show file tree
Hide file tree
Showing 43 changed files with 2,469 additions and 50 deletions.
6 changes: 4 additions & 2 deletions src/main/environment/common_ci.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ carestreamOrderCreateURL [email protected]_API_BASE_URL@/carestream/createOrder
# Registration
registrationUrl =@env.COMMON_API_BASE_URL@/beneficiary/create

syncSearchByLocation =@env.COMMON_API_BASE_URL@/id/searchByDistrictId
syncSearchByLocation =@env.HWC_IDENTITY_API_BASE@/id/searchByVillageIdAndLastModifiedDate

getBenCountToSync = @env.HWC_IDENTITY_API_BASE@/id/countBenByVillageIdAndLastModifiedDate

registrarQuickSearchByIdUrl =@env.COMMON_API_BASE_URL@/beneficiary/searchUserByID

registrarQuickSearchByPhoneNoUrl =@env.COMMON_API_BASE_URL@/beneficiary/searchUserByPhone

getBenImageFromIdentity =@env.COMMON_API_BASE_URL@/id/benImageByBenRegID
getBenImageFromIdentity =@env.HWC_IDENTITY_API_BASE@/id/benImageByBenRegID

##save covid Vaccine details coming from mobile app through fhir
saveCovidVaccineDetailsURL = @env.COMMON_API_BASE_URL@/covid/saveCovidVaccinationDetails
Expand Down
4 changes: 3 additions & 1 deletion src/main/environment/common_dev.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ carestreamOrderCreateURL =<Enter your socket address here>/hwc-commonapi-v1.0/ca
# Registration
registrationUrl =<Enter your socket address here>/hwc-commonapi-v1.0/beneficiary/create

syncSearchByLocation =<Enter your socket address here>/hwc-identity-0.0.1/id/searchByDistrictId
syncSearchByLocation =<Enter your socket address here>/hwc-identity-0.0.1/id/searchByVillageIdAndLastModifiedDate

getBenCountToSync =<Enter your socket address here>/hwc-identity-0.0.1/id/countBenByVillageIdAndLastModifiedDate

registrarQuickSearchByIdUrl =<Enter your socket address here>/hwc-commonapi-v1.0/beneficiary/searchUserByID

Expand Down
4 changes: 3 additions & 1 deletion src/main/environment/common_example.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ carestreamOrderCreateURL =http://localhost:8080/carestream/createOrder
# Registration
registrationUrl =http://localhost:8080/beneficiary/create

syncSearchByLocation =http://localhost:8082/id/searchByDistrictId
syncSearchByLocation =http://localhost:8082/id/searchByVillageIdAndLastModifiedDate

getBenCountToSync = http://localhost:8082/id/countBenByVillageIdAndLastModifiedDate

registrarQuickSearchByIdUrl =http://localhost:8080/beneficiary/searchUserByID

Expand Down
Empty file.
4 changes: 3 additions & 1 deletion src/main/environment/common_prod.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ carestreamOrderCreateURL =<Enter your socket address here>/commonapi-v1.0/carest
# Registration
registrationUrl =<Enter your socket address here>/commonapi-v1.0/beneficiary/create

syncSearchByLocation =<Enter your socket address here>/identity-0.0.1/id/searchByDistrictId
syncSearchByLocation =<Enter your socket address here>/identity-0.0.1/id/searchByVillageIdAndLastModifiedDate

getBenCountToSync =<Enter your socket address here>/identity-0.0.1/id/countBenByVillageIdAndLastModifiedDate

registrarQuickSearchByIdUrl =<Enter your socket address here>/commonapi-v1.0/beneficiary/searchUserByID

Expand Down
4 changes: 3 additions & 1 deletion src/main/environment/common_test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ carestreamOrderCreateURL =<Enter your socket address here>/commonapi-v1.0/carest
# Registration
registrationUrl =<Enter your socket address here>/commonapi-v1.0/beneficiary/create

syncSearchByLocation =<Enter your socket address here>/identity-0.0.1/id/searchByDistrictId
syncSearchByLocation =<Enter your socket address here>/identity-0.0.1/id/searchByVillageIdAndLastModifiedDate

getBenCountToSync =<Enter your socket address here>/identity-0.0.1/id/countBenByVillageIdAndLastModifiedDate

registrarQuickSearchByIdUrl =<Enter your socket address here>/commonapi-v1.0/beneficiary/searchUserByID

Expand Down
6 changes: 4 additions & 2 deletions src/main/environment/common_uat.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Test env
# Test env
# DB Connections
spring.datasource.url=<Enter AMRIT DB_IEMR URL here>
spring.datasource.username=<Enter your AMRIT DB_IEMR username>
Expand All @@ -14,7 +14,9 @@ carestreamOrderCreateURL =<Enter your socket address here>/commonapi-v1.0/carest
# Registration
registrationUrl =<Enter your socket address here>/commonapi-v1.0/beneficiary/create

syncSearchByLocation =<Enter your socket address here>/identity-0.0.1/id/searchByDistrictId
syncSearchByLocation =<Enter your socket address here>/identity-0.0.1/id/searchByVillageIdAndLastModifiedDate

getBenCountToSync =<Enter your socket address here>/identity-0.0.1/id/countBenByVillageIdAndLastModifiedDate

registrarQuickSearchByIdUrl =<Enter your socket address here>/commonapi-v1.0/beneficiary/searchUserByID

Expand Down
181 changes: 181 additions & 0 deletions src/main/java/com/iemr/hwc/controller/choApp/CHOAppSyncController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* 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.hwc.controller.choApp;

import com.iemr.hwc.data.choApp.OutreachActivity;
import com.iemr.hwc.data.choApp.UserActivityLogs;
import com.iemr.hwc.data.doctor.PrescriptionTemplates;
import com.iemr.hwc.service.choApp.CHOAppSyncService;
import com.iemr.hwc.utils.request.SyncSearchRequest;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping(value = "/sync", headers = "Authorization")
/**
* Objective: Performs beneficiaries and ben flow status sync to AMRIT server from CHO app and vice-versa.
* Details
*/
public class CHOAppSyncController {
private CHOAppSyncService choappSyncService;

@Autowired
public void setCHOAppSyncService(CHOAppSyncService choappSyncService) {
this.choappSyncService = choappSyncService;
}

// beneficiary registration sync from CHO app to AMRIT server with common and identity new
@ApiOperation(value = "Sync new beneficiaries to AMRIT server", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/beneficiariesToServer" }, method = { RequestMethod.POST })
public ResponseEntity<String> beneficiaryRegistrationSyncToServer(@RequestBody String comingReq,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.registerCHOAPPBeneficiary(comingReq, Authorization);
}

// beneficiary registration sync from AMRIT server to CHO app with identity new
@ApiOperation(value = "Sync beneficiaries from AMRIT server to CHO App", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/beneficiariesToApp" }, method = { RequestMethod.POST })
public ResponseEntity<String> beneficiarySyncToAppLocal(@RequestBody SyncSearchRequest villageIDAndLastSyncDate,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.getBeneficiaryByVillageIDAndLastModifiedDate(villageIDAndLastSyncDate, Authorization);
}

// Get count of beneficiary to sync from AMRIT server to CHO app with identity new
@ApiOperation(value = "Returns count of beneficiaries to be synced from AMRIT server to CHO App", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/beneficiariesToAppCount" }, method = { RequestMethod.POST })
public ResponseEntity<String> beneficiarySyncToAppLocalCount(@RequestBody SyncSearchRequest villageIDAndLastSyncDate,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.countBeneficiaryByVillageIDAndLastModifiedDate(villageIDAndLastSyncDate, Authorization);
}

//Count of beneficiary flow status records to sync from AMRIT server to CHO app
@ApiOperation(value = "Returns count of beneficiaries flow status records to be synced", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/benFlowStatusRecordsCount" }, method = {
RequestMethod.POST })
public ResponseEntity<String> flowStatusesSyncToAppLocalCount(@RequestBody SyncSearchRequest villageIDAndLastSyncDate,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.countFlowRecordsByVillageIDAndLastModifiedDate(villageIDAndLastSyncDate, Authorization);
}

// beneficiary flow status records sync from AMRIT server to CHO app
@ApiOperation(value = "Sync beneficiaries flow status records ", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/benFlowStatusRecordsToApp" }, method = {
RequestMethod.POST })
public ResponseEntity<String> flowStatusesSyncToAppLocal(@RequestBody SyncSearchRequest villageIDAndLastSyncDate,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.getFlowRecordsByVillageIDAndLastModifiedDate(villageIDAndLastSyncDate, Authorization);
}

// Login logout logs sync from CHO app to AMRIT server
@ApiOperation(value = "Sync user activity logs to AMRIT server", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/userActivityLogsToServer" }, method = { RequestMethod.POST })
public ResponseEntity<String> userActivityLogsSyncToServer(@RequestBody List<UserActivityLogs> logsList,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.saveUserActivityLogs(logsList, Authorization);
}

// beneficiary nurse-form data(visit details,vitals,chief complaints,history,examinations) sync from AMRIT server to CHO app
@ApiOperation(value = "Sync beneficiaries nurse-form data from AMRIT server to CHO App", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/beneficiaryGeneralOPDNurseFormDataToApp" }, method = { RequestMethod.POST })
public ResponseEntity<String> beneficiaryNurseFormDataGeneralOPDSyncToAppLocal(
@ApiParam(value = "{\"benRegID\":\"Long\",\"visitCode\":\"Long\"}") @RequestBody String comingRequest,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.getBeneficiaryNurseFormDataGeneralOPD(comingRequest, Authorization);
}

// beneficiary nurse-form data(visit details,vitals,chief complaints,history,examinations) save from CHO app to server
@ApiOperation(value = "Save beneficiaries nurse-form data CHO App to AMRIT server", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/generalOPDNurseFormDataToServer" }, method = { RequestMethod.POST })
public ResponseEntity<String> beneficiaryNurseFormDataGeneralOPDSyncToServer(@RequestBody String comingRequest,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.saveBeneficiaryNurseFormDataGeneralOPD(comingRequest, Authorization);
}

// Upload Prescription templates from CHO app to AMRIT server
@ApiOperation(value = "Save prescription templates to AMRIT server", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/prescriptionTemplatesToServer" }, method = { RequestMethod.POST })
public ResponseEntity<String> prescriptionTemplatesToServer(@RequestBody List<PrescriptionTemplates> templateList,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.savePrescriptionTemplatesToServer(templateList, Authorization);
}

// Fetch Prescription templates for a doctor from AMRIT server
@ApiOperation(value = "Fetch prescription templates for doctor to AMRIT server", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/{userID}/prescriptionTemplatesDataToApp" }, method = { RequestMethod.GET })
public ResponseEntity<String> prescriptionTemplatesToApp(@PathVariable Integer userID,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.savePrescriptionTemplatesToApp(userID, Authorization);
}

// Delete Prescription templates for a doctor from AMRIT server
@ApiOperation(value = "Delete prescription templates for doctor to AMRIT server", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/{userID}/prescriptionTemplates/{tempID}/delete" }, method = { RequestMethod.DELETE })
public ResponseEntity<String> deleteTemplate(@PathVariable Integer userID,
@PathVariable Integer tempID,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.deletePrescriptionTemplates(userID, tempID);
}

// save new Outreach activity event
@ApiOperation(value = "Create new event for outreach activity", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/activity/create" }, method = { RequestMethod.POST })
public ResponseEntity<String> createNewOutreachActivity(@RequestBody OutreachActivity activity,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.createNewOutreachActivity(activity, Authorization);
}

// Get all outreach activities by user
@ApiOperation(value = "Get list of all outreach activities by user", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/activity/{userId}/getAllByUser" }, method = { RequestMethod.GET })
public ResponseEntity<String> getActivitiesByUser(@PathVariable Integer userId,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.getActivitiesByUser(userId, Authorization);
}

// Get an outreach activity by activityId
@ApiOperation(value = "Get an outreach activities by activityId", consumes = "application/json", produces = "application/json")
@RequestMapping(value = { "/activity/{activityId}/getById" }, method = { RequestMethod.GET })
public ResponseEntity<String> getActivityByIdr(@PathVariable Integer activityId,
@RequestHeader(HttpHeaders.AUTHORIZATION) String Authorization) {

return choappSyncService.getActivityById(activityId, Authorization);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* 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.hwc.controller.masterVillage;

import com.google.gson.Gson;
import com.iemr.hwc.data.login.UserMasterVillageDTO;
import com.iemr.hwc.data.login.UsersMasterVillage;
import com.iemr.hwc.service.masterVillage.MasterVillageService;
import com.iemr.hwc.utils.response.OutputResponse;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@CrossOrigin
@RestController
@RequestMapping(value = "/masterVillage", headers = "Authorization")
public class MasterVillageController {
private Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());

private MasterVillageService masterVillageService;

@Autowired
public void setMasterVillageService(MasterVillageService masterVillageService){
this.masterVillageService = masterVillageService;
}

@ApiOperation(value = "set master village to a user", consumes = "application/json", produces = "application/json")
@RequestMapping(value = "/set", method = { RequestMethod.POST }, produces = {
"application/json" })
public String setMasterVillage(@RequestBody UserMasterVillageDTO userMasterVillageDTO) {
OutputResponse response = new OutputResponse();
try {
if (userMasterVillageDTO!=null && userMasterVillageDTO.getUserID() != null && userMasterVillageDTO.getMasterVillageID() != null) {
String resp = masterVillageService.setMasterVillage(userMasterVillageDTO.getUserID(), userMasterVillageDTO.getMasterVillageID());

if(resp !=null && resp.equals("not_ok")){
response.setError(500, "Error setting master village");
}
else if(resp !=null && resp.equals("villageID_not_exist")){
response.setError(404, "Village ID does not exist");
}
else if(resp !=null && resp.equals("userID_not_exist")){
response.setError(404, "User ID does not exist");
}
else if(resp!=null){
response.setResponse(resp);
}
} else {
response.setError(400, "Invalid request");
}
} catch (Exception e) {
logger.error(e.getMessage());
response.setError(500, "Error while setting master village");
}
return response.toString();
}

@ApiOperation(value = "Get master village for a user", consumes = "application/json", produces = "application/json")
@RequestMapping(value = "/{userID}/get", method = RequestMethod.GET)
public String getMasterVillage(@PathVariable("userID") Long userID) {
logger.info("Get master village by userID ..." + userID);
OutputResponse response = new OutputResponse();
UsersMasterVillage user = masterVillageService.getMasterVillage(userID);
if (user != null){
if(user.getMasterVillage()!=null){
Gson gson = new Gson();
response.setResponse(gson.toJson(user.getMasterVillage()));
}
else{
logger.error("No master village associated with user " + userID);
response.setError(404, "User with userID: "+userID+" do not have master village");
}
}
else{
logger.error("No active master village record for user " + userID + " found");
response.setError(404, "No master village record found with userID: "+userID);
}
return response.toString();
}
}
Loading

0 comments on commit aa22386

Please sign in to comment.