From 83a1744c83c1b795252d83102860c83193b6a50b Mon Sep 17 00:00:00 2001 From: MAKOBA REAGAN PATRICK <47450907+reagan-meant@users.noreply.github.com> Date: Wed, 10 Apr 2024 16:28:55 +0300 Subject: [PATCH] Add logic to see matches before saving patient (#6) * Add logic to see matches before savinf patient * Add fixes * Add more fixes * Show the transfer Status * Revert and fix unit test * add color for matches * Update buttons * Update PR --------- Co-authored-by: aziz --- .../module/legacyui/LegacyUIActivator.java | 31 +- omod/pom.xml | 7 +- .../patient/ShortPatientFormController.java | 295 +++++++++++++----- omod/src/main/resources/config.xml | 29 ++ .../admin/patients/shortPatientForm.jsp | 204 +++++++++++- .../src/main/webapp/template/popupMessage.jsp | 24 ++ .../ShortPatientFormControllerTest.java | 64 ++-- 7 files changed, 523 insertions(+), 131 deletions(-) create mode 100644 omod/src/main/webapp/template/popupMessage.jsp diff --git a/api/src/main/java/org/openmrs/module/legacyui/LegacyUIActivator.java b/api/src/main/java/org/openmrs/module/legacyui/LegacyUIActivator.java index 44ff793d..721a2327 100644 --- a/api/src/main/java/org/openmrs/module/legacyui/LegacyUIActivator.java +++ b/api/src/main/java/org/openmrs/module/legacyui/LegacyUIActivator.java @@ -70,8 +70,6 @@ public void willStart() { public void started() { applicationContext.getAutowireCapableBeanFactory().autowireBean(this); - createFhirPatientIdentierSystem(); - log.info("Legacy UI Module started"); } @@ -89,37 +87,10 @@ public void stopped() { log.info("Legacy UI Module stopped"); } - private void createFhirPatientIdentierSystem() { - - List pidTypes = patientService.getAllPatientIdentifierTypes(false); - for (PatientIdentifierType pidType : pidTypes) { - Optional existingIdSystem = fhirPatientIdentifierSystemService - .getFhirPatientIdentifierSystem(pidType); - if (existingIdSystem.isPresent()) { - existingIdSystem.get().setPatientIdentifierType(pidType); - //existingIdSystem.get().setUrl("http://openelis-global.org/pat_xx"); - existingIdSystem.get().setUrl("https://openmrs.org/" + pidType.getName().replace(" ", "_")); - - fhirPatientIdentifierSystemService.saveFhirPatientIdentifierSystem(existingIdSystem.get()); - } else { - FhirPatientIdentifierSystem idSystem = new FhirPatientIdentifierSystem(); - idSystem.setName(pidType.getName() + " ID System"); - idSystem.setPatientIdentifierType(pidType); - pidType.getName(); - idSystem.setUrl("https://openmrs.org/" + pidType.getName().replace(" ", "_")); - fhirPatientIdentifierSystemService.saveFhirPatientIdentifierSystem(idSystem); - } - } - - /* PatientIdentifierType pidType = patientService - .getPatientIdentifierTypeByUuid("b3b24192-6856-46fd-ab4e-acde31f80c85"); */ - - } - @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.applicationContext = applicationContext; } -} +} \ No newline at end of file diff --git a/omod/pom.xml b/omod/pom.xml index 3cf1ff5e..4da9517f 100644 --- a/omod/pom.xml +++ b/omod/pom.xml @@ -83,7 +83,12 @@ - + + com.squareup.okhttp3 + okhttp + 4.9.1 + + org.openmrs.directwebremoting dwr diff --git a/omod/src/main/java/org/openmrs/web/controller/patient/ShortPatientFormController.java b/omod/src/main/java/org/openmrs/web/controller/patient/ShortPatientFormController.java index 20be0d0f..9e1c2219 100644 --- a/omod/src/main/java/org/openmrs/web/controller/patient/ShortPatientFormController.java +++ b/omod/src/main/java/org/openmrs/web/controller/patient/ShortPatientFormController.java @@ -9,6 +9,7 @@ */ package org.openmrs.web.controller.patient; +import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -20,7 +21,12 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import ca.uhn.fhir.parser.IParser; + +import org.hl7.fhir.r4.model.ContactPoint; import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.Patient.ContactComponent; +import org.hl7.fhir.r4.model.HumanName; import org.openmrs.Concept; import org.openmrs.Location; import org.openmrs.Obs; @@ -38,6 +44,8 @@ import org.openmrs.User; import org.openmrs.api.APIException; import org.openmrs.api.context.Context; +import org.openmrs.module.fhir2.api.translators.PatientTranslator; +import org.openmrs.util.HttpClient; import org.openmrs.util.LocationUtility; import org.openmrs.util.OpenmrsConstants; import org.openmrs.util.OpenmrsUtil; @@ -47,6 +55,7 @@ import org.openmrs.web.controller.person.PersonFormController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; @@ -58,9 +67,22 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.context.request.WebRequest; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.client.api.IGenericClient; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.Credentials; + import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.concurrent.TimeUnit; +import java.util.UUID; /** * This controller is used for the "mini"/"new"/"short" patient form. Only key/important attributes @@ -83,6 +105,12 @@ public class ShortPatientFormController { @Autowired PatientValidator patientValidator; + @Autowired + PatientTranslator patientTranslator; + + @Autowired + HttpClient httpClient; + @RequestMapping(method = RequestMethod.GET, value = SHORT_PATIENT_FORM_URL) public void showForm() { } @@ -214,10 +242,35 @@ public boolean getIdentifierLocationUsed() { */ @RequestMapping(method = RequestMethod.POST, value = SHORT_PATIENT_FORM_URL) public String saveShortPatient(WebRequest request, @ModelAttribute("personNameCache") PersonName personNameCache, - @ModelAttribute("personAddressCache") PersonAddress personAddressCache, - @ModelAttribute("relationshipsMap") Map relationshipsMap, - @ModelAttribute("patientModel") ShortPatientModel patientModel, BindingResult result) { - + @ModelAttribute("personAddressCache") PersonAddress personAddressCache, + @ModelAttribute("relationshipsMap") Map relationshipsMap, + @RequestParam(value = "continueFlag", required = false) String continueFlag, + @ModelAttribute("patientModel") ShortPatientModel patientModel, BindingResult result, Model model) { + + String opencrClientTimeOut = Context.getAdministrationService().getGlobalProperty( + "opencr.opencrClientTimeOut", + "30"); + OkHttpClient client = new OkHttpClient.Builder() + .callTimeout(Integer.parseInt(opencrClientTimeOut), TimeUnit.SECONDS) // Set timeout for complete call (including connection, read, and write operations) to 30 seconds + .build(); + + String opencrMatchesUrl = Context.getAdministrationService().getGlobalProperty("opencrMatchesUrl", + "https://localhost:5001/CR/fhir/matches"); + + String opencrMatchesCheckFlag = Context.getAdministrationService().getGlobalProperty( + "legacyui.enableMatchCheck", + "true"); + + String token = null; + String opencMatches = null; + + // Add the data to the Model + if (!Context.isAuthenticated()) { + // return "module/legacyui/template/popupMessage"; + return "module/legacyui/admin/patients/shortPatientForm"; + + } + if (Context.isAuthenticated()) { // First do form validation so that we can easily bind errors to // fields @@ -225,10 +278,10 @@ public String saveShortPatient(WebRequest request, @ModelAttribute("personNameCa if (result.hasErrors()) { return "module/legacyui/admin/patients/shortPatientForm"; } - + Patient patient = null; patient = getPatientFromFormData(patientModel); - + Errors patientErrors = new BindException(patient, "patient"); patientValidator.validate(patient, patientErrors); if (patientErrors.hasErrors()) { @@ -239,23 +292,99 @@ public String saveShortPatient(WebRequest request, @ModelAttribute("personNameCa for (ObjectError error : patientErrors.getAllErrors()) { result.reject(error.getCode(), error.getArguments(), "Validation errors found"); } - + return "module/legacyui/admin/patients/shortPatientForm"; } + + ContactPoint contactPoint = new ContactPoint(); + + for (PersonAttribute iterable_element : patient.getActiveAttributes()) { + if (iterable_element.getAttributeType().getUuid().equals(Context.getAdministrationService() + .getGlobalProperty("fhir2.personContactPointAttributeTypeUuid"))) + contactPoint.setId(iterable_element.getUuid()); + contactPoint.setValue(iterable_element.getValue()); + contactPoint.setUse(ContactPoint.ContactPointUse.MOBILE); + contactPoint.setSystem(ContactPoint.ContactPointSystem.PHONE); + + } + + if (opencrMatchesCheckFlag.equals("true")) { + List myList = new ArrayList<>(); + myList.add(contactPoint); + org.hl7.fhir.r4.model.Patient fhirResource = patientTranslator.toFhirResource(patient); + + fhirResource.setTelecom(myList); + + // Check if the conversion was successful + if (fhirResource != null) { + // Now you can safely use the result + fhirResource.getName().get(0).setUse(HumanName.NameUse.OFFICIAL); + + // Create a FhirContext + FhirContext fhirContext = FhirContext.forR4(); + + // Create a JSON parser + IParser jsonParser = fhirContext.newJsonParser(); + + // Serialize the Patient resource to JSON + String jsonPayload = jsonParser.encodeResourceToString(fhirResource); + + // Now, jsonPayload contains the JSON representation of the Patient + System.out.println("JSON Payload:\n" + jsonPayload); + + // Create basic authentication credentials + String username = "sigdep3"; + String password = "sigdep3"; + String credentials = Credentials.basic(username, password); + + Request apiRequest = new Request.Builder() + .url(opencrMatchesUrl) + .post(RequestBody.create(MediaType.parse("application/json"), jsonPayload)) + .header("Authorization", credentials) // Add Authorization header + .build(); + try (Response apiResponse = client.newCall(apiRequest).execute()) { + if (apiResponse.isSuccessful()) { + opencMatches = apiResponse.body().string(); + model.addAttribute("opencMatches", opencMatches); + } else { + model.addAttribute("queryError", "OpenCR patient match issue"); + + System.out.println("Error: " + apiResponse.code() + " - " + apiResponse.message()); + return "module/legacyui/admin/patients/shortPatientForm"; + + } + } catch (IOException e) { + model.addAttribute("queryError", "OpenCR server error"); + + e.printStackTrace(); + return "module/legacyui/admin/patients/shortPatientForm"; + + } + } else { + // Handle the case where conversion to FHIR resource failed + System.out.println("Error: Conversion to FHIR resource failed"); + } + + if (!continueFlag.equals("continue")) { + // return "module/legacyui/template/popupMessage"; + return "module/legacyui/admin/patients/shortPatientForm"; + } + + } // check if name/address were edited, void them and replace them boolean foundChanges = hasPersonNameOrAddressChanged(patient, personNameCache, personAddressCache); - + try { patient = Context.getPatientService().savePatient(patient); request.setAttribute(WebConstants.OPENMRS_MSG_ATTR, - Context.getMessageSourceService().getMessage("Patient.saved"), WebRequest.SCOPE_SESSION); - + Context.getMessageSourceService().getMessage("Patient.saved"), WebRequest.SCOPE_SESSION); + // TODO do we really still need this, besides ensuring that the // cause of death is provided? // process and save the death info saveDeathInfo(patientModel, request); - + if (!patient.getVoided() && relationshipsMap != null) { for (Relationship relationship : relationshipsMap.values()) { // if the user added a person to this relationship, save @@ -265,13 +394,12 @@ public String saveShortPatient(WebRequest request, @ModelAttribute("personNameCa } } } - } - catch (APIException e) { + } catch (APIException e) { log.error("Error occurred while attempting to save patient", e); request.setAttribute(WebConstants.OPENMRS_ERROR_ATTR, - Context.getMessageSourceService().getMessage("Patient.save.error"), WebRequest.SCOPE_SESSION); + Context.getMessageSourceService().getMessage("Patient.save.error"), WebRequest.SCOPE_SESSION); // TODO revert the changes and send them back to the form - + // don't send the user back to the form because the created // person name/addresses // will be recreated over again if the user attempts to resubmit @@ -279,14 +407,22 @@ public String saveShortPatient(WebRequest request, @ModelAttribute("personNameCa return "module/legacyui/admin/patients/shortPatientForm"; } } - + return "redirect:" + PATIENT_DASHBOARD_URL + "?patientId=" + patient.getPatientId(); - + } - + return "module/legacyui/findPatient"; } + private static String parseToken(String responseBody) { + // Implement your JSON parsing logic here to extract the token from the response + // For simplicity, assuming the token is always present in the 'token' field + // Replace this with your actual JSON parsing logic + // You might want to use a JSON library for this task + return responseBody.split("\"token\":")[1].split(",")[0].replaceAll("\"", ""); + } + /** * Convenience method that gets the data from the patientModel * @@ -334,19 +470,22 @@ else if (!(personAddress.isVoided() && personAddress.getPersonAddressId() == nul // add the person attributes if (patientModel.getPersonAttributes() != null) { for (PersonAttribute formAttribute : patientModel.getPersonAttributes()) { - //skip past new attributes with no values, because the user left them blank + // skip past new attributes with no values, because the user left them blank if (formAttribute.getPersonAttributeId() == null && StringUtils.isBlank(formAttribute.getValue())) { continue; } - //if the value has been changed for an existing attribute, void it and create a new one + // if the value has been changed for an existing attribute, void it and create a + // new one if (formAttribute.getPersonAttributeId() != null && !OpenmrsUtil.nullSafeEquals(formAttribute.getValue(), patient.getAttribute(formAttribute.getAttributeType()).getValue())) { - //As per the logic in Person.addAttribute, the old edited attribute will get voided - //as this new one is getting added + // As per the logic in Person.addAttribute, the old edited attribute will get + // voided + // as this new one is getting added formAttribute = new PersonAttribute(formAttribute.getAttributeType(), formAttribute.getValue()); - //AOP is failing to set these in unit tests, just set them here for the tests to pass + // AOP is failing to set these in unit tests, just set them here for the tests + // to pass formAttribute.setDateCreated(new Date()); formAttribute.setCreator(Context.getAuthenticatedUser()); } @@ -698,16 +837,16 @@ public static String extractUUID(String url) { } public Patient createPatient(String CRIdentifier) throws Exception { - + // Get patient // IGenericClient client = new FhirLegacyUIConfig().getFhirClient(); IGenericClient client = Context.getRegisteredComponent("clientRegistryFhirClient", IGenericClient.class); - + // Patient patient = client.read() org.hl7.fhir.r4.model.Patient fhirPatient = client.read() - - .resource(org.hl7.fhir.r4.model.Patient.class).withId(CRIdentifier).execute(); - + + .resource(org.hl7.fhir.r4.model.Patient.class).withId(CRIdentifier).execute(); + User user = Context.getAuthenticatedUser(); Patient p = new Patient(); p.setPersonCreator(user); @@ -717,17 +856,18 @@ public Patient createPatient(String CRIdentifier) throws Exception { p.setUuid(CRIdentifier); List links = fhirPatient.getLink() - .stream() - .map(patientLink -> patientLink.getOther()) - .collect(Collectors.toList()); + .stream() + .map(patientLink -> patientLink.getOther()) + .collect(Collectors.toList()); String telecom = ""; - + if (fhirPatient.getTelecomFirstRep() != null && fhirPatient.getTelecomFirstRep().getValue() != null) { telecom = fhirPatient.getTelecomFirstRep().getValue(); } - - //Add null checker for attribute CRUID - PersonAttributeType type = Context.getPersonService().getPersonAttributeTypeByUuid("2b4fbe39-3281-42fa-b45b-e5cfee7bf1db"); + + String phoneUUID = Context.getAdministrationService().getGlobalProperty("fhir2.personContactPointAttributeTypeUuid"); + PersonAttributeType type = Context.getPersonService() + .getPersonAttributeTypeByUuid(phoneUUID); PersonAttribute attribute = new PersonAttribute(type, telecom); p.addAttribute(attribute); @@ -735,20 +875,21 @@ public Patient createPatient(String CRIdentifier) throws Exception { PersonName name = new PersonName(); List givenNames = fhirPatient.getNameFirstRep().getGiven(); if (!givenNames.isEmpty()) { - + StringBuilder sb = new StringBuilder(); for (int i = 1; i < givenNames.size(); i++) { sb.append(givenNames.get(i).getValue()).append(" "); } - + if (sb.length() > 0) { sb.deleteCharAt(sb.length() - 1); } - - name = new PersonName(givenNames.get(0).getValue(), sb.toString(), fhirPatient.getNameFirstRep().getFamily()); - + + name = new PersonName(givenNames.get(0).getValue(), sb.toString(), + fhirPatient.getNameFirstRep().getFamily()); + } - + switch (fhirPatient.getBirthDateElement().getPrecision()) { case DAY: p.setBirthdateEstimated(false); @@ -758,7 +899,7 @@ public Patient createPatient(String CRIdentifier) throws Exception { p.setBirthdateEstimated(true); break; } - + // Set patient gender if (fhirPatient.hasGender()) { switch (fhirPatient.getGender()) { @@ -776,7 +917,7 @@ public Patient createPatient(String CRIdentifier) throws Exception { break; } } - + name.setCreator(user); name.setDateCreated(new Date()); name.setChangedBy(user); @@ -785,33 +926,32 @@ public Patient createPatient(String CRIdentifier) throws Exception { p.setBirthdate(fhirPatient.getBirthDate()); // Get the identifiers of the patient List identifiers = fhirPatient.getIdentifier(); - String fhirIdsExp = "http://clientregistry.org/artnumber|6b6e9d94-015b-48f6-ac95-da239512ff91, http://clientregistry.org/openmrs|3825d4f8-1afd-4da4-b30f-e0ff4cd256a5"; - String fhirIds = Context.getAdministrationService().getGlobalProperty("fhirIds", fhirIdsExp); + String fhirIds = Context.getAdministrationService().getGlobalProperty("opencrIdsMapping"); Map optionsMap = new HashMap<>(); - String[] options = fhirIds.split(","); + String[] options = fhirIds.split(","); - //String[] options = fhirIds.split("\\|"); - for (String option : options) { + // String[] options = fhirIds.split("\\|"); + for (String option : options) { String[] keyValue = option.split("\\|"); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - optionsMap.put(key, value); - } - } + if (keyValue.length == 2) { + String key = keyValue[0].trim(); + String value = keyValue[1].trim(); + optionsMap.put(key, value); + } + } for (org.hl7.fhir.r4.model.Identifier fhirIdentifier : identifiers) { - if(fhirIdentifier.getSystem() != null && optionsMap.get(fhirIdentifier.getSystem()) != null){ - + if (fhirIdentifier.getSystem() != null && fhirIdentifier.getValue() != null && optionsMap.get(fhirIdentifier.getSystem()) != null) { + PatientIdentifier pi = new PatientIdentifier(); pi.setIdentifier(fhirIdentifier.getValue()); - + pi.setIdentifierType(Context.getPatientService().getPatientIdentifierTypeByUuid( - optionsMap.get(fhirIdentifier.getSystem()))); + optionsMap.get(fhirIdentifier.getSystem()))); pi.setLocation(Context.getLocationService().getDefaultLocation()); - + switch (fhirIdentifier.getUse()) { case OFFICIAL: pi.setPreferred(true); @@ -820,30 +960,33 @@ public Patient createPatient(String CRIdentifier) throws Exception { pi.setPreferred(false); break; } - + BindException piErrors = new BindException(pi, "patientIdentifier"); new PatientIdentifierValidator().validate(pi, piErrors); if (piErrors.hasErrors()) { log.warn(piErrors.getMessage()); - + } p.addIdentifier(pi); } - + } - /* if(CRUID != null){ - PatientIdentifier pi = new PatientIdentifier(); - pi.setIdentifier(CRUID); - pi.setIdentifierType(Context.getPatientService().getPatientIdentifierTypeByUuid("43a6e699-c2b8-4d5f-9e7f-cf19448d59b7")); - pi.setLocation(Context.getLocationService().getDefaultLocation()); - pi.setPreferred(false); - - p.addIdentifier(pi); - } */ - //Patient patient = Context.getPatientService().savePatient(p); - //resultsMap.put("success", patient.getPatientId()); - + /* + * if(CRUID != null){ + * PatientIdentifier pi = new PatientIdentifier(); + * pi.setIdentifier(CRUID); + * pi.setIdentifierType(Context.getPatientService(). + * getPatientIdentifierTypeByUuid("43a6e699-c2b8-4d5f-9e7f-cf19448d59b7")); + * pi.setLocation(Context.getLocationService().getDefaultLocation()); + * pi.setPreferred(false); + * + * p.addIdentifier(pi); + * } + */ + // Patient patient = Context.getPatientService().savePatient(p); + // resultsMap.put("success", patient.getPatientId()); + return p; - + } -} +} \ No newline at end of file diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 2b3d21b2..27fee43c 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -395,4 +395,33 @@ + + legacyui.enableMatchCheck + true + + Allow OpenCR match check before patient creation + + + + + opencrMatchesUrl + https://test2.cihis.org/openhimcore/CR/fhir/matches/ + + OpenCR matches url + + + + opencrIdsMapping + http://openelis-global.org/pat_nationalId|6b6e9d94-015b-48f6-ac95-da239512ff91, https://openmrs.org/UPI|1bdba5bf-b074-458a-bba1-c6d58d799089 + + OpenCR systems mapping to OpenMRS Identifier types UUIDs e.g http://clientregistry.org/artnumber|6b6e9d94-015b-48f6-ac95-da239512ff91, http://clientregistry.org/artnumber|6b6e9d94-015b-48f6-ac95-da239512ff91 + + + + opencr.opencrClientTimeOut + 30 + + OpenCR client timeout in seconds + + diff --git a/omod/src/main/webapp/admin/patients/shortPatientForm.jsp b/omod/src/main/webapp/admin/patients/shortPatientForm.jsp index 43a392ac..bc8a47d8 100644 --- a/omod/src/main/webapp/admin/patients/shortPatientForm.jsp +++ b/omod/src/main/webapp/admin/patients/shortPatientForm.jsp @@ -313,6 +313,23 @@ } .lastCell { border-bottom: 1px lightgray solid; + } + + /* Define a specific class for the table */ + .custom-table { + border-collapse: collapse; + width: 100%; + margin-top: 20px; + } + + .custom-table th, .custom-table td { + border: 1px solid #dddddd; + text-align: left; + padding: 8px; + } + + .custom-dialog { + top: 10px !important; } @@ -321,6 +338,8 @@ + +

@@ -681,20 +700,193 @@ - + + " />
" name="action" id="addButton">     + " onclick="history.go(-1);">
+if (content.trim() !== '') { + // Your script code here + //alert('Fetched Data: ' + document.getElementById('extraData').textContent); + $j('
').dialog({ + title: '', + autoOpen: true, // Automatically open the dialog when the page loads + draggable: false, + resizable: false, + width: '95%', + dialogClass: 'custom-dialog', // Define a custom CSS class + modal: true, + buttons: { + "Cancel": function() { + $j(this).dialog("close"); + }, + "Continue": function() { + $j(this).dialog("close"); + $j('#continueFlag').val('continue'); + //$j('input[name="continueFlag"]').val('yourDynamicValue'); + + $j('#addButton').click(); + + + } + + }, + open: function() { + // var tableHtml = createTable(jsonObject); // Create the table + //$j(this).html(tableHtml); // Set the table as the dialog content + //document.getElementById('extraData1').textContent; + //var content = document.getElementById('extraData1').textContent; + // $j(this).html(content); + $j(this).html('
' ); + + var jsonObject = null; + try { + jsonObject = JSON.parse(content); + console.log(jsonObject); + } catch (error) { + console.error('Error parsing JSON:', error); + } + createTable(jsonObject.parent, 'Nouveau Patient', '#7C7AD2'); + createTable(jsonObject.auto, 'Correspondances Auto.','#33CCCC'); + createTable(jsonObject.potential, 'Correspondances potentielles', '#FFD966'); + createTable(jsonObject.conflict, 'Conflits de correspondance','#FF8C66'); + + } + }); + + function createTable(data, category, color) { + var tableHtml = ''; + tableHtml += ''; + tableHtml += ''; + + if (data.length === 0) { + tableHtml += ''; + } else { + for (var i = 0; i < data.length; i++) { + tableHtml += ''; + tableHtml += ''; + tableHtml += ''; + tableHtml += ''; + tableHtml += ''; + tableHtml += ''; + tableHtml += ''; + + // Separate columns for extensions + tableHtml += ''; + + // Separate columns for identifiers + tableHtml += ''; + + tableHtml += ''; + + + if(category !== 'Nouveau Patient'){ + tableHtml += ''; + }else{ + tableHtml += ''; + } + tableHtml += ''; + } + } + + tableHtml += ''; + tableHtml += '
IDPrenom(s)Nom de familleDate de naissanceGenreTelephoneExtensionscode ARVStatusAction
Aucun patient disponible
' + data[i].id + '' + data[i].given + '' + data[i].family + '' + data[i].birthDate + '' + data[i].gender + '' + data[i].phone + ''; + for (var extensionKey in data[i]) { + if (extensionKey.startsWith('extension_')) { + tableHtml += '
' + extensionKey.substring(10) + ': ' + data[i][extensionKey] + '
'; + } + } + tableHtml += '
'; + for (var identifierKey in data[i]) { + if (identifierKey.startsWith('identifier_')) { + tableHtml += '
' + identifierKey.substring(11) + ': ' + data[i][identifierKey] + '
'; + } + } + tableHtml += '
'; + for (var extensionKey in data[i]) { + if (extensionKey.startsWith('extension_patient_status')) { + tableHtml += data[i][extensionKey]; + } + } + tableHtml += '
'; + + $j('#container').append('

' + category + '

'); + $j('#container').append(tableHtml); + } + + function importData(button) { + // Find the closest tr (table row) to the clicked button + var row = button.closest('tr'); + + // Get the content of the first td (assuming it contains the ID) + var id = row.querySelector('td:first-child').textContent; + document.location = "shortPatientForm.form?fhirPatientId=" + id; + + } + function ContinueCreate(button) { + $j('.custom-dialog').find('button:contains("Continue")').click(); + } + + function handleSaveResults(result) { + // This method will be called by DWR with the search results + // Do something with the search results here, such as displaying them on the page + if (result.hasOwnProperty("success")) { + document.location = "admin/patients/shortPatientForm.form?fhirPatientId=" + result["success"]; + + } else { + alert("Error: " + result["error"]); + + } + } + $j('.custom-dialog').parent().find('button:contains("Continue")').hide(); + +}else if (content2.trim() !== ''){ + $j('
').dialog({ + title: '', + autoOpen: true, // Automatically open the dialog when the page loads + draggable: false, + resizable: false, + width: '95%', + dialogClass: 'custom-dialog', // Define a custom CSS class + modal: true, + buttons: { + "Continue": function() { + $j(this).dialog("close"); + $j('#continueFlag').val('continue'); + //$j('input[name="continueFlag"]').val('yourDynamicValue'); + + $j('#addButton').click(); + + + }, + "Cancel": function() { + $j(this).dialog("close"); + } + }, + open: function() { + // var tableHtml = createTable(jsonObject); // Create the table + //$j(this).html(tableHtml); // Set the table as the dialog content + //document.getElementById('extraData1').textContent; + var content = document.getElementById('extraData2').textContent; + $j(this).html(content); + + } + }); +}; + <%@ include file="/WEB-INF/view/module/legacyui/template/footer.jsp" %> diff --git a/omod/src/main/webapp/template/popupMessage.jsp b/omod/src/main/webapp/template/popupMessage.jsp new file mode 100644 index 00000000..69819ebd --- /dev/null +++ b/omod/src/main/webapp/template/popupMessage.jsp @@ -0,0 +1,24 @@ +<%@ include file="/WEB-INF/view/module/legacyui/template/include.jsp" %> +
+
+
+ + + + + diff --git a/omod/src/test/java/org/openmrs/web/controller/patient/ShortPatientFormControllerTest.java b/omod/src/test/java/org/openmrs/web/controller/patient/ShortPatientFormControllerTest.java index 1b9cc03b..c70ea382 100644 --- a/omod/src/test/java/org/openmrs/web/controller/patient/ShortPatientFormControllerTest.java +++ b/omod/src/test/java/org/openmrs/web/controller/patient/ShortPatientFormControllerTest.java @@ -40,6 +40,8 @@ import org.openmrs.web.test.WebTestHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; import org.springframework.web.bind.support.SessionStatus; @@ -64,6 +66,7 @@ public class ShortPatientFormControllerTest extends BaseModuleWebContextSensitiv public void saveShortPatient_shouldPassIfAllTheFormDataIsValid() throws Exception { Patient p = Context.getPatientService().getPatient(2); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); WebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); BindException errors = new BindException(patientModel, "patientModel"); @@ -75,8 +78,8 @@ public void saveShortPatient_shouldPassIfAllTheFormDataIsValid() throws Exceptio .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) mockWebRequest.getAttribute("personNameCache", WebRequest.SCOPE_SESSION), - (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, - (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors); + (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, "true", + (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("Patient.saved", @@ -93,6 +96,8 @@ public void saveShortPatient_shouldCreateANewPatient() throws Exception { int patientCount = Context.getPatientService().getAllPatients().size(); Patient p = new Patient(); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + patientModel.setPersonName(new PersonName("new", "", "patient")); List identifiers = new ArrayList(); PatientIdentifier id = new PatientIdentifier("myID", Context.getPatientService().getPatientIdentifierType(2), @@ -110,7 +115,7 @@ public void saveShortPatient_shouldCreateANewPatient() throws Exception { ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), new PersonAddress(), null, - patientModel, errors); + "true", patientModel, errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertNotNull(p.getId()); @@ -131,6 +136,8 @@ public void saveShortPatient_shouldCreateANewPatient() throws Exception { public void saveShortPatient_shouldSendTheUserBackToTheFormInCaseOfValidationErrors() throws Exception { Patient p = new Patient(); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + patientModel.setPersonName(new PersonName("new", "", "patient")); List identifiers = new ArrayList(); patientModel.setIdentifiers(identifiers); @@ -141,8 +148,8 @@ public void saveShortPatient_shouldSendTheUserBackToTheFormInCaseOfValidationErr ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); - String formUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), new PersonAddress(), null, - patientModel, errors); + String formUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), new PersonAddress(), null, "true", + patientModel, errors, model); Assert.assertTrue("Should report validation errors", errors.hasErrors()); Assert.assertEquals("module/legacyui/admin/patients/shortPatientForm", formUrl); @@ -156,6 +163,8 @@ public void saveShortPatient_shouldSendTheUserBackToTheFormInCaseOfValidationErr public void saveShortPatient_shouldVoidANameAndReplaceItWithANewOneIfItIsChangedToAUniqueValue() throws Exception { Patient p = Context.getPatientService().getPatient(2); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + PersonName oldPersonName = p.getPersonName(); String oldGivenName = oldPersonName.getGivenName(); int nameCount = p.getNames().size(); @@ -170,7 +179,7 @@ public void saveShortPatient_shouldVoidANameAndReplaceItWithANewOneIfItIsChanged ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, personNameCache, (PersonAddress) p - .getPersonAddress().clone(), null, patientModel, errors); + .getPersonAddress().clone(), null, "true", patientModel, errors, model); Assert.assertEquals(nameCount + 1, p.getNames().size()); Assert.assertTrue("The old name should be voided", oldPersonName.isVoided()); @@ -201,6 +210,8 @@ public void saveShortPatient_shouldAddANewNameIfThePersonHadNoNames() throws Exc PersonName newName = new PersonName("new", null, "name"); newName.setDateCreated(new Date()); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + patientModel.setPersonName(newName); BindException errors = new BindException(patientModel, "patientModel"); @@ -209,7 +220,7 @@ public void saveShortPatient_shouldAddANewNameIfThePersonHadNoNames() throws Exc ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), (PersonAddress) p - .getPersonAddress().clone(), null, patientModel, errors); + .getPersonAddress().clone(), null, "true", patientModel, errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); @@ -225,6 +236,8 @@ public void saveShortPatient_shouldAddANewNameIfThePersonHadNoNames() throws Exc public void saveShortPatient_shouldVoidAnAddressAndReplaceItWithANewOneIfItIsChangedToAUniqueValue() throws Exception { Patient p = Context.getPatientService().getPatient(2); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + PersonAddress oldPersonAddress = patientModel.getPersonAddress(); String oldAddress1 = oldPersonAddress.getAddress1(); int addressCount = p.getAddresses().size(); @@ -239,7 +252,8 @@ public void saveShortPatient_shouldVoidAnAddressAndReplaceItWithANewOneIfItIsCha ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, - (PersonName) BeanUtils.cloneBean(p.getPersonName()), personAddressCache, null, patientModel, errors); + (PersonName) BeanUtils.cloneBean(p.getPersonName()), personAddressCache, null, "true", patientModel, errors, + model); Assert.assertEquals(addressCount + 1, p.getAddresses().size()); Assert.assertTrue("The old address should be voided", oldPersonAddress.isVoided()); Assert.assertNotNull("The void reason should be set", oldPersonAddress.getVoidReason()); @@ -272,6 +286,8 @@ public void saveShortPatient_shouldAddANewAddressIfThePersonHadNone() throws Exc newAddress.setAddress1("Kampala"); newAddress.setDateCreated(new Date()); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + patientModel.setPersonAddress(newAddress); BindException errors = new BindException(patientModel, "patientModel"); @@ -280,7 +296,8 @@ public void saveShortPatient_shouldAddANewAddressIfThePersonHadNone() throws Exc ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, - (PersonName) BeanUtils.cloneBean(p.getPersonName()), new PersonAddress(), null, patientModel, errors); + (PersonName) BeanUtils.cloneBean(p.getPersonName()), new PersonAddress(), null, "true", patientModel, errors, + model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); @@ -307,6 +324,8 @@ public void saveShortPatient_shouldIgnoreANewAddressThatWasAddedAndVoidedAtSameT newAddress.setDateCreated(new Date()); newAddress.setVoided(true); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + patientModel.setPersonAddress(newAddress); BindException errors = new BindException(patientModel, "patientModel"); @@ -315,7 +334,8 @@ public void saveShortPatient_shouldIgnoreANewAddressThatWasAddedAndVoidedAtSameT ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, - (PersonName) BeanUtils.cloneBean(p.getPersonName()), new PersonAddress(), null, patientModel, errors); + (PersonName) BeanUtils.cloneBean(p.getPersonName()), new PersonAddress(), null, "true", patientModel, errors, + model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); @@ -333,6 +353,8 @@ public void saveShortPatient_shouldAddANewPersonAttributeWithANonEmptyValue() th Patient p = Context.getPatientService().getPatient(2); int originalAttributeCount = p.getAttributes().size(); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + int attributeTypeId = 2; String birthPlace = "Kampala"; PersonAttribute newPersonAttribute = new PersonAttribute(Context.getPersonService().getPersonAttributeType( @@ -351,8 +373,8 @@ public void saveShortPatient_shouldAddANewPersonAttributeWithANonEmptyValue() th .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) mockWebRequest.getAttribute("personNameCache", WebRequest.SCOPE_SESSION), - (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, - (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors); + (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, "true", + (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("Patient.saved", @@ -374,6 +396,8 @@ public void saveShortPatient_shouldNotAddANewPersonAttributeWithAnEmptyValue() t Patient p = Context.getPatientService().getPatient(2); int originalAttributeCount = p.getAttributes().size(); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + //add a new person Attribute with no value patientModel.getPersonAttributes().add( new PersonAttribute(Context.getPersonService().getPersonAttributeType(2), null)); @@ -388,8 +412,8 @@ public void saveShortPatient_shouldNotAddANewPersonAttributeWithAnEmptyValue() t .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) mockWebRequest.getAttribute("personNameCache", WebRequest.SCOPE_SESSION), - (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, - (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors); + (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, "true", + (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("Patient.saved", @@ -420,6 +444,8 @@ public void saveShortPatient_shouldVoidAnExistingPersonAttributeWithAnEmptyValue int originalActiveAttributeCount = p.getActiveAttributes().size(); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + PersonAttribute attributeToEdit = null; String oldValue = null; String newValue = ""; @@ -447,8 +473,8 @@ public void saveShortPatient_shouldVoidAnExistingPersonAttributeWithAnEmptyValue .getBean("shortPatientFormController"); controller.saveShortPatient(mockWebRequest, (PersonName) mockWebRequest.getAttribute("personNameCache", WebRequest.SCOPE_SESSION), - (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, - (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors); + (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, "true", + (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("Patient.saved", @@ -479,6 +505,8 @@ public void saveShortPatient_shouldShouldReplaceAnExistingAttributeWithANewOneWh int originalAttributeCount = p.getAttributes().size(); ShortPatientModel patientModel = new ShortPatientModel(p); + Model model = (Model) new ModelMap("query", "testQuery"); + PersonAttribute attributeToEdit = null; String oldValue = null; String newValue = "New"; @@ -506,8 +534,8 @@ public void saveShortPatient_shouldShouldReplaceAnExistingAttributeWithANewOneWh .getBean("shortPatientFormController"); controller.saveShortPatient(mockWebRequest, (PersonName) mockWebRequest.getAttribute("personNameCache", WebRequest.SCOPE_SESSION), - (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, - (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors); + (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), null, "true", + (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors, model); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("Patient.saved",