org.openmrs.module.diagnosiscapturerwanda.DiagnosisCaptureController.java Source code

Java tutorial

Introduction

Here is the source code for org.openmrs.module.diagnosiscapturerwanda.DiagnosisCaptureController.java

Source

/**
 * The contents of this file are subject to the OpenMRS Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
package org.openmrs.module.diagnosiscapturerwanda;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Concept;
import org.openmrs.ConceptSearchResult;
import org.openmrs.Encounter;
import org.openmrs.Obs;
import org.openmrs.Patient;
import org.openmrs.Visit;
import org.openmrs.api.ObsService;
import org.openmrs.api.context.Context;
import org.openmrs.module.diagnosiscapturerwanda.util.AutoCompleteObj;
import org.openmrs.module.diagnosiscapturerwanda.util.DiagnosisUtil;
import org.openmrs.util.OpenmrsUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class DiagnosisCaptureController {

    protected final Log log = LogFactory.getLog(getClass());

    /**
     * this is the main get method
     * @param patientId
     * @param visitId
     * @param encounterId
     * @param session
     * @param map
     * @return
     */
    @RequestMapping(value = "/module/diagnosiscapturerwanda/diagnosisCapture", method = RequestMethod.GET)
    public String processDiagnosisCapturePageGet(@RequestParam(value = "patientId") Integer patientId,
            @RequestParam(value = "visitId") Integer visitId,
            @RequestParam(required = false, value = "obsGroupId") Integer obsGroupId,
            @RequestParam(value = "visitToday", required = false) String visitToday, HttpSession session,
            ModelMap map) {

        Patient patient = Context.getPatientService().getPatient(patientId);
        if (patient == null)
            return null;
        map.put("patient", patient);

        map.put("visitToday", visitToday);

        Visit visit = Context.getVisitService().getVisit(visitId);
        if (visit == null)
            throw new RuntimeException("You must pass in a valid visitId to this page.");
        if (visit != null && !visit.getPatient().equals(patient))
            throw new RuntimeException(
                    "visit passed into DiagnosisPatientDashboardController doesn't belong to patient passed into this controller.");
        map.put("visit", visit);

        DiagnosisCaptureController.loadMetadata(map);

        if (obsGroupId != null) {
            try {
                map.put("obsGroup", Context.getObsService().getObs(obsGroupId));
            } catch (Exception ex) {
                log.error("invalid encounterId passed to DiagnosisCapture Controller.");
            }
        }
        return null;
    }

    /**
     * helper that throws concepts & encounterTypes in the model
     * @param map
     */
    private static ModelMap loadMetadata(ModelMap map) {
        map.put("concept_set_primary_diagnosis",
                MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT);
        map.put("concept_set_secondary_diagnosis",
                MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_SECONDARY_DIAGNOSIS_CONSTRUCT);
        map.put("concept_primary_secondary", MetadataDictionary.CONCEPT_DIAGNOSIS_ORDER);
        map.put("concept_primary_care_diagnosis", MetadataDictionary.CONCEPT_PRIMARY_CARE_DIAGNOSIS);
        map.put("concept_confirmed_suspected", MetadataDictionary.CONCEPT_DIAGNOSIS_CONFIRMED_SUSPECTED);
        map.put("concept_diagnosis_other", MetadataDictionary.CONCEPT_DIAGNOSIS_NON_CODED);
        map.put("concept_confirmed", MetadataDictionary.CONCEPT_CONFIRMED);
        map.put("concept_suspected", MetadataDictionary.CONCEPT_SUSPTECTED);
        map.put("concept_set_body_system", DiagnosisUtil.getCategories());
        map.put("concept_set_diagnosis_classification",
                MetadataDictionary.CONCEPT_SET_ICPC_SYMPTOM_INFECTION_INJURY_DIAGNOSIS);
        map.put("encounter_type_diagnosis", MetadataDictionary.ENCOUNTER_TYPE_DIAGNOSIS);
        map.put("encounter_type_findings", MetadataDictionary.ENCOUNTER_TYPE_FINDINGS);
        map.put("concept_symptom", MetadataDictionary.CONCEPT_CLASSIFICATION_SYMPTOM);
        map.put("concept_infection", MetadataDictionary.CONCEPT_CLASSIFICATION_INFECTION);
        map.put("concept_injury", MetadataDictionary.CONCEPT_CLASSIFICATION_INJURY);
        map.put("concept_diagnosis", MetadataDictionary.CONCEPT_CLASSIFICATION_DIAGNOSIS);

        List<ConceptSearchResult> diagnosisConcepts = Context.getConceptService().getConcepts(null,
                Context.getAdministrationService().getAllowedLocales(), false, null, null, null, null,
                MetadataDictionary.CONCEPT_PRIMARY_CARE_DIAGNOSIS, null, null);

        map.put("diagnosisConcepts", DiagnosisUtil.convertToAutoCompleteObj(diagnosisConcepts));

        return map;
    }

    /**
     * this is the main post method
     * @param visitId
     * @param diagnosisId
     * @param primarySecondary
     * @param confirmedSuspected
     * @param diagnosisOther
     * @param session
     * @param map
     * @return
     */
    @RequestMapping(value = "/module/diagnosiscapturerwanda/diagnosisCapture", method = RequestMethod.POST)
    public String processDiagnosisCaptureSubmit(@RequestParam(value = "hiddenVisitId") Integer visitId,
            @RequestParam(required = false, value = "hiddenObsGroupId") Integer hiddenObsGroupId,
            @RequestParam(value = "diagnosisId") Integer diagnosisId,
            @RequestParam(value = "primary_secondary") Integer primarySecondary,
            @RequestParam(value = "confirmed_suspected") Integer confirmedSuspected,
            @RequestParam(required = false, value = "diagnosisOther") String diagnosisOther,
            @RequestParam(value = "visitToday", required = false) String visitToday, HttpSession session,
            ModelMap map) {

        Visit visit = Context.getVisitService().getVisit(visitId);
        if (visit == null)
            throw new RuntimeException(
                    "There is no visit for this patient on this day.  Please go to the diagnosis patient dashboard to figure out why...");

        map.put("visitToday", visitToday);

        map.put("patient", visit.getPatient());
        map.put("visit", visit);
        DiagnosisCaptureController.loadMetadata(map);

        boolean hasValidationError = false;
        Encounter enc = null;
        Obs oParent = null;
        boolean saveNeeded = false;

        //Edit Encounter:  switch primary/secondary if necessary, compare values
        if (hiddenObsGroupId != null) {

            //for lazy loading.  Total fucking crap
            oParent = Context.getObsService().getObs(hiddenObsGroupId);
            enc = Context.getEncounterService().getEncounter(oParent.getEncounter().getId());
            for (Obs oTmp : enc.getObsAtTopLevel(false)) {
                if (oTmp.getId().equals(oParent.getId())) {
                    oParent = oTmp;
                    break;
                }
            }

            boolean continueWithThisObs = false;
            if (oParent.getConcept()
                    .equals(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT)) {
                continueWithThisObs = true;
                if (primarySecondary.equals(1)) {
                    saveNeeded = true;
                    oParent.setConcept(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_SECONDARY_DIAGNOSIS_CONSTRUCT);
                }
            } else if (oParent.getConcept()
                    .equals(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_SECONDARY_DIAGNOSIS_CONSTRUCT)) {
                continueWithThisObs = true;
                if (primarySecondary.equals(0)) {
                    saveNeeded = true;
                    oParent.setConcept(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT);
                }
            }
            if (continueWithThisObs) {
                for (Obs o : oParent.getGroupMembers(false)) {
                    //new diagnosis
                    Integer existingVal = o.getValueCoded() == null ? null : o.getValueCoded().getConceptId();
                    //               if (o.getConcept().equals(MetadataDictionary.CONCEPT_PRIMARY_CARE_DIAGNOSIS) && OpenmrsUtil.nullSafeEquals(diagnosisId, existingVal) == false){
                    //                  o.setValueCoded(Context.getConceptService().getConcept(diagnosisId));
                    //                  saveNeeded = true;
                    //               }
                    //               if (o.getConcept().equals(MetadataDictionary.CONCEPT_DIAGNOSIS_NON_CODED) && OpenmrsUtil.nullSafeEquals(diagnosisOther, o.getValueText()) == false){
                    //                  o.setValueText(diagnosisOther);
                    //                  saveNeeded = true;
                    //               }
                    //               existingVal = o.getValueCoded()== null ? null : o.getValueCoded().getConceptId();
                    if (o.getConcept().equals(MetadataDictionary.CONCEPT_DIAGNOSIS_CONFIRMED_SUSPECTED)
                            && OpenmrsUtil.nullSafeEquals(confirmedSuspected, existingVal) == false) {
                        o.setValueCoded(Context.getConceptService().getConcept(confirmedSuspected));
                        saveNeeded = true;
                    }
                }
            }
        } else {
            enc = DiagnosisUtil.findEncounterByTypeInVisit(visit, MetadataDictionary.ENCOUNTER_TYPE_DIAGNOSIS);
            Concept diagnosis = Context.getConceptService().getConcept(diagnosisId);
            if (diagnosis != null || (diagnosisOther != null && !diagnosisOther.equals(""))) {
                if (enc == null)
                    enc = DiagnosisUtil.buildEncounter(visit.getPatient(),
                            MetadataDictionary.ENCOUNTER_TYPE_DIAGNOSIS, visit);
                enc = constructDiagnosisObsTree(enc, diagnosis, primarySecondary,
                        Context.getConceptService().getConcept(confirmedSuspected), diagnosisOther);
            }
            saveNeeded = true;
        }
        //validate and save
        if (saveNeeded && enc != null) {
            hasValidationError = !hasOneOrNoPrimaryDiagnosis(visit, enc);

            //validate method
            if (!hasValidationError) {
                //this is total crap;  its for the encounter validator which enforces the encounter between visit start and stop
                if (enc.getEncounterDatetime().getTime() > visit.getStopDatetime().getTime()) {
                    visit.setStopDatetime(DiagnosisUtil.getStartAndEndOfDay(enc.getEncounterDatetime())[1]);
                    Context.getVisitService().saveVisit(visit);
                }
                //save
                enc.setVisit(visit);
                enc = Context.getEncounterService().saveEncounter(enc);

            } else {
                map.put("more_than_one_primary_diagnosis_err", "err");
                //editing an existing diagnosis:
                if (oParent != null && oParent.getId() != null)
                    map.put("obsGroup", oParent);
                else if (enc != null) { // adding a new one, and its invalid, just drop it.
                    for (Obs o : enc.getObsAtTopLevel(false)) {
                        if (o.getId() == null)
                            enc.removeObs(o);
                    }
                }
                return null;

            }
        }
        //if everything's cool, then reset with a redirect
        return "redirect:/module/diagnosiscapturerwanda/diagnosisCapture.list?patientId="
                + visit.getPatient().getPatientId() + "&visitId=" + visit.getVisitId();
    }

    /**
     * validates diagnosis encounter creation.  there must be exactly one primary diagnosis.
     * doesn't add encounter to visit, if necessary
     * @param v
     * @param newEnc
     * @return
     */
    private boolean hasOneOrNoPrimaryDiagnosis(Visit v, Encounter enc) {
        Set<Encounter> visitEncs = v.getEncounters();
        boolean remove = false;
        if (enc != null && !visitEncs.contains(enc)) {
            visitEncs.add(enc);
            remove = true;
        }
        int count = 0;
        for (Encounter e : visitEncs) {
            if (!e.isVoided() && e.getEncounterType().equals(MetadataDictionary.ENCOUNTER_TYPE_DIAGNOSIS)) {
                for (Obs o : e.getObsAtTopLevel(false)) {
                    if (o.getConcept()
                            .equals(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT))
                        count++;
                }
            }
        }
        if (remove)
            visitEncs.remove(enc);
        return (count <= 1 ? true : false);
    }

    /**
     * returns if the visit has already got one primary diagnosis
     * @param v
     * @return
     */
    private boolean hasOnePrimaryDiagnosis(Visit v) {
        Set<Encounter> visitEncs = v.getEncounters();

        int count = 0;
        for (Encounter e : visitEncs) {
            if (!e.isVoided() && e.getEncounterType().equals(MetadataDictionary.ENCOUNTER_TYPE_DIAGNOSIS)) {
                for (Obs o : e.getObsAtTopLevel(false)) {
                    if (o.getConcept()
                            .equals(MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT))
                        return true;
                }
            }
        }
        return false;
    }

    /**
     * the ajax method for checking to see if a primary diagnosis already exists
     * @param visitId
     * @param session, restrictBySymptoms, searchPharse
     * @param model
     * @return
     */
    @RequestMapping(value = "/module/diagnosiscapturerwanda/checkPrimaryStatus", method = RequestMethod.POST)
    public String getPrimaryStatusJSON(@RequestParam("visitId") Integer visitId, HttpSession session,
            ModelMap model) {

        Visit visit = Context.getVisitService().getVisit(visitId);

        if (hasOnePrimaryDiagnosis(visit)) {
            model.put("json", DiagnosisUtil.convertToJSON("{\"result\":\"true\"}"));
        } else {
            model.put("json", DiagnosisUtil.convertToJSON("{\"result\":\"false\"}"));
        }
        return "/module/diagnosiscapturerwanda/jsonAjaxResponse";
    }

    /**
     * the ajax method for looking up a diagnosis by name; if restrictBySymptom is true, then only return symptoms, else, return all
     * @param searchPhrase
     * @param session, restrictBySymptoms, searchPharse
     * @param model
     * @return
     */
    @RequestMapping(value = "/module/diagnosiscapturerwanda/getDiagnosisByNameJSON", method = RequestMethod.GET)
    public String getDiagnosisByNameJSON(@RequestParam("searchPhrase") String searchPhrase,
            @RequestParam("restrictBySymptom") boolean restrictBySymptom, HttpSession session, ModelMap model) {
        List<Concept> cList = new ArrayList<Concept>();
        for (ConceptSearchResult csr : Context.getConceptService().getConcepts(searchPhrase,
                Context.getAdministrationService().getAllowedLocales(), false, null, null, null, null,
                MetadataDictionary.CONCEPT_PRIMARY_CARE_DIAGNOSIS, null, null)) {
            if (restrictBySymptom && MetadataDictionary.CONCEPT_CLASSIFICATION_SYMPTOM.getSetMembers()
                    .contains(csr.getConcept())) {
                cList.add(csr.getConcept());
            } else {
                cList.add(csr.getConcept());
            }
        }

        model.put("json", DiagnosisUtil.convertToJSONAutoComplete(cList));
        return "/module/diagnosiscapturerwanda/jsonAjaxResponse";
    }

    //TODO: this is wrong, should only delete obsGroup, and maybe encounter only if empty
    //to do this, you need the jsps to send obsGroupId, not encounterId
    @RequestMapping(value = "/module/diagnosiscapturerwanda/deleteDiagnosis", method = RequestMethod.POST)
    public String deleteDiagnosis(@RequestParam("obsGroupId") Integer obsGroupId, HttpSession session,
            ModelMap model) {
        try {
            ObsService os = Context.getObsService();
            Obs o = os.getObs(obsGroupId);
            os.voidObs(o, "voided through diagnosiscapture");
            model.put("json", DiagnosisUtil.convertToJSON("{\"result\":\"success\"}"));
        } catch (Exception ex) {
            model.put("json", DiagnosisUtil.convertToJSON("{\"result\":\"failed\"}"));
            ex.printStackTrace();
        }

        return "/module/diagnosiscapturerwanda/jsonAjaxResponse";
    }

    /**
     * the ajax method that returns all diagnosis in an ICPC chapter
     * @param groupingId
     * @param session
     * @param model
     * @return
     */
    @RequestMapping(value = "/module/diagnosiscapturerwanda/getDiagnosesByIcpcSystemJSON", method = RequestMethod.GET)
    public String getDiagnosesByIcpcSystemJSON(@RequestParam("groupingId") int groupingId,
            @RequestParam("restrictBySymptom") boolean restrictBySymptom, HttpSession session, ModelMap model) {
        Integer classificationId = null;
        if (restrictBySymptom)
            classificationId = MetadataDictionary.CONCEPT_CLASSIFICATION_SYMPTOM.getId();
        List<Concept> cList = DiagnosisUtil.getConceptListByGroupingAndClassification(groupingId, classificationId); //these come out of this method sorted by name
        model.put("json", DiagnosisUtil.convertToJSON(cList));
        return "/module/diagnosiscapturerwanda/jsonAjaxResponse";
    }

    /**
     * utility build the primary diagnosis obs tree and attach to encounter
     */
    private Encounter constructDiagnosisObsTree(Encounter enc, Concept diagnosis, Integer primarySecondary,
            Concept confirmedSusptectedAnswer, String other) {

        //determine primary or secondary; 0 = primary 1=secondary
        Concept c = primarySecondary.equals(0)
                ? MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_PRIMARY_DIAGNOSIS_CONSTRUCT
                : MetadataDictionary.CONCEPT_SET_PRIMARY_CARE_SECONDARY_DIAGNOSIS_CONSTRUCT;

        //build the obsGroup
        Obs oParent = DiagnosisUtil.buildObs(enc.getPatient(), c, enc.getEncounterDatetime(), null, null, null,
                enc.getLocation());
        //build the children
        Obs oDiagnosis = DiagnosisUtil.buildObs(enc.getPatient(), MetadataDictionary.CONCEPT_PRIMARY_CARE_DIAGNOSIS,
                enc.getEncounterDatetime(), diagnosis, null, null, enc.getLocation());
        Obs oConfirmedSuspected = DiagnosisUtil.buildObs(enc.getPatient(),
                MetadataDictionary.CONCEPT_DIAGNOSIS_CONFIRMED_SUSPECTED, enc.getEncounterDatetime(),
                confirmedSusptectedAnswer, null, null, enc.getLocation());
        Obs oOther = DiagnosisUtil.buildObs(enc.getPatient(), MetadataDictionary.CONCEPT_DIAGNOSIS_NON_CODED,
                enc.getEncounterDatetime(), null, other, null, enc.getLocation());

        oParent.addGroupMember(oDiagnosis);
        oParent.addGroupMember(oConfirmedSuspected);
        oParent.addGroupMember(oOther);

        enc.addObs(oParent);

        return enc;
    }

}