Advertisement
Guest User

my groovy file

a guest
Jul 17th, 2018
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Groovy 21.01 KB | None | 0 0
  1. import org.apache.commons.lang.StringUtils
  2. import org.hibernate.Query
  3. import org.hibernate.SessionFactory;
  4. import org.openmrs.Obs;
  5. import org.openmrs.Patient;
  6. import org.openmrs.Concept;
  7. import org.openmrs.Encounter;
  8. import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniObservation
  9. import org.openmrs.util.OpenmrsUtil;
  10. import org.openmrs.api.context.Context;
  11. import org.openmrs.module.bahmniemrapi.obscalculator.ObsValueCalculator;
  12. import org.openmrs.module.bahmniemrapi.encountertransaction.contract.BahmniEncounterTransaction
  13. import org.openmrs.module.emrapi.encounter.domain.EncounterTransaction;
  14.  
  15. import org.joda.time.LocalDate;
  16. import org.joda.time.Months;
  17.  
  18. public class BahmniObsValueCalculator implements ObsValueCalculator {
  19.  
  20.     static Double BMI_VERY_SEVERELY_UNDERWEIGHT = 16.0;
  21.     static Double BMI_SEVERELY_UNDERWEIGHT = 17.0;
  22.     static Double BMI_UNDERWEIGHT = 18.5;
  23.     static Double BMI_NORMAL = 25.0;
  24.     static Double BMI_OVERWEIGHT = 30.0;
  25.     static Double BMI_OBESE = 35.0;
  26.     static Double BMI_SEVERELY_OBESE = 40.0;
  27.     static Double ZERO = 0.0;
  28.     static Map<BahmniObservation, BahmniObservation> obsParentMap = new HashMap<BahmniObservation, BahmniObservation>();
  29.  
  30.     public static enum BmiStatus {
  31.         VERY_SEVERELY_UNDERWEIGHT("Very Severely Underweight"),
  32.         SEVERELY_UNDERWEIGHT("Severely Underweight"),
  33.         UNDERWEIGHT("Underweight"),
  34.         NORMAL("Normal"),
  35.         OVERWEIGHT("Overweight"),
  36.         OBESE("Obese"),
  37.         SEVERELY_OBESE("Severely Obese"),
  38.         VERY_SEVERELY_OBESE("Very Severely Obese");
  39.  
  40.         private String status;
  41.  
  42.         BmiStatus(String status) {
  43.             this.status = status
  44.         }
  45.  
  46.         @Override
  47.         public String toString() {
  48.             return status;
  49.         }
  50.     }
  51.  
  52.  
  53.     public void run(BahmniEncounterTransaction bahmniEncounterTransaction) {
  54.         calculateAndAdd(bahmniEncounterTransaction);
  55.         calculateDiffOffSurgTimeInAndTimeOut(bahmniEncounterTransaction);
  56.         def file11 = new File(OpenmrsUtil.getApplicationDataDirectory() + "obscalculator/groovy_debug.txt")
  57.         file11.append '\ndebugging statement:';
  58.     }
  59.     static def calculateDiffOffSurgTimeInAndTimeOut(bahmniEncounterTransaction bahmniEncounterTransaction){
  60.         Collection<BahmniObservation> observations = bahmniEncounterTransaction.getObservations()
  61.         BahmniObservation surgicalTimeDataObservation = find("Surgical Time Data", observations, null);
  62.  
  63.         BahmniObservation surgicalTimeInObservation = find("Surgical Time In",surgicalTimeDataObservation ? [surgicalTimeDataObservation] : [], null);
  64.         BahmniObservation surgicalTimeOutObservation = find("Surgical Time Out", surgicalTimeDataObservation ? [surgicalTimeDataObservation] : [], null);
  65.  
  66.         BahmniObservation surgicalTotalTimeObservation = find("Surgical Total Time", surgicalTimeDataObservation ? [surgicalTimeDataObservation] : [], null);
  67.         if(!hasValueDate(surgicalTimeInObservation)|| !hasValueDate(surgicalTimeOutObservation)){
  68.             return
  69.         }
  70.  
  71.         Date obsDatetime = getDate(surgicalTimeInObservation) != null ? getDate(surgicalTimeInObservation) : getDate(surgicalTimeOutObservation)
  72.         surgicalTotalTimeObservation = surgicalTotalTimeObservation ?: createObs("Surgical Total Time", surgicalTimeDataObservation, bahmniEncounterTransaction, obsDatetime) as BahmniObservation;
  73.         def values = "30 min"
  74.         surgicalTotalTimeObservation.setValue(values);
  75.  
  76.         def file11 = new File(OpenmrsUtil.getApplicationDataDirectory() + "obscalculator/groovy_debug.txt")
  77.         file11.append '\ndebugging statement:'+" "+ values;
  78.         return;
  79.     }
  80.  
  81.     static def calculateAndAdd(BahmniEncounterTransaction bahmniEncounterTransaction) {
  82.         Collection<BahmniObservation> observations = bahmniEncounterTransaction.getObservations()
  83.         def nowAsOfEncounter = bahmniEncounterTransaction.getEncounterDateTime() != null ? bahmniEncounterTransaction.getEncounterDateTime() : new Date();
  84.  
  85.         BahmniObservation heightObservation = find("Height", observations, null)
  86.         BahmniObservation weightObservation = find("Weight", observations, null)
  87.         BahmniObservation parent = null;
  88.  
  89.         if (hasValue(heightObservation) || hasValue(weightObservation)) {
  90.             def heightObs = null, weightObs = null;
  91.             Encounter encounter = Context.getEncounterService().getEncounterByUuid(bahmniEncounterTransaction.getEncounterUuid());
  92.             if (encounter != null) {
  93.                 Set<Obs> latestObsOfEncounter = encounter.getObsAtTopLevel(true);
  94.                 latestObsOfEncounter.each { Obs latestObs ->
  95.                     for (Obs groupMember : latestObs.groupMembers) {
  96.                         heightObs = heightObs ? heightObs : (groupMember.concept.getName().name.equalsIgnoreCase("HEIGHT") ? groupMember : null);
  97.                         weightObs = weightObs ? weightObs : (groupMember.concept.getName().name.equalsIgnoreCase("WEIGHT") ? groupMember : null);
  98.                     }
  99.                 }
  100.                 if (isSameObs(heightObservation, heightObs) && isSameObs(weightObservation, weightObs)) {
  101.                     return;
  102.                 }
  103.             }
  104.  
  105.  
  106.             BahmniObservation bmiDataObservation = find("BMI Data", observations, null)
  107.             BahmniObservation bmiObservation = find("BMI", bmiDataObservation ? [bmiDataObservation] : [], null)
  108.             BahmniObservation bmiAbnormalObservation = find("BMI Abnormal", bmiDataObservation ? [bmiDataObservation]: [], null)
  109.  
  110.             BahmniObservation bmiStatusDataObservation = find("BMI Status Data", observations, null)
  111.             BahmniObservation bmiStatusObservation = find("BMI Status", bmiStatusDataObservation ? [bmiStatusDataObservation] : [], null)
  112.             BahmniObservation bmiStatusAbnormalObservation = find("BMI Status Abnormal", bmiStatusDataObservation ? [bmiStatusDataObservation]: [], null)
  113.  
  114.             Patient patient = Context.getPatientService().getPatientByUuid(bahmniEncounterTransaction.getPatientUuid())
  115.             def patientAgeInMonthsAsOfEncounter = Months.monthsBetween(new LocalDate(patient.getBirthdate()), new LocalDate(nowAsOfEncounter)).getMonths()
  116.  
  117.             parent = obsParent(heightObservation, parent)
  118.             parent = obsParent(weightObservation, parent)
  119.  
  120.             if ((heightObservation && heightObservation.voided) && (weightObservation && weightObservation.voided)) {
  121.                 voidObs(bmiDataObservation);
  122.                 voidObs(bmiObservation);
  123.                 voidObs(bmiStatusDataObservation);
  124.                 voidObs(bmiStatusObservation);
  125.                 voidObs(bmiAbnormalObservation);
  126.                 return
  127.             }
  128.  
  129.             def previousHeightValue = fetchLatestValue("Height", bahmniEncounterTransaction.getPatientUuid(), heightObservation, nowAsOfEncounter)
  130.             def previousWeightValue = fetchLatestValue("Weight", bahmniEncounterTransaction.getPatientUuid(), weightObservation, nowAsOfEncounter)
  131.  
  132.             Double height = hasValue(heightObservation) && !heightObservation.voided ? heightObservation.getValue() as Double : previousHeightValue
  133.             Double weight = hasValue(weightObservation) && !weightObservation.voided ? weightObservation.getValue() as Double : previousWeightValue
  134.             Date obsDatetime = getDate(weightObservation) != null ? getDate(weightObservation) : getDate(heightObservation)
  135.  
  136.             if (height == null || weight == null) {
  137.                 voidObs(bmiDataObservation)
  138.                 voidObs(bmiObservation)
  139.                 voidObs(bmiStatusDataObservation)
  140.                 voidObs(bmiStatusObservation)
  141.                 voidObs(bmiAbnormalObservation)
  142.                 return
  143.             }
  144.  
  145.             if(encounter != null) {
  146.                 voidPreviousBMIObs(encounter.getObsAtTopLevel(false));
  147.                 voidPreviousBMIObs(encounter.getObs());
  148.             }
  149.  
  150.             bmiDataObservation = bmiDataObservation ?: createObs("BMI Data", null, bahmniEncounterTransaction, obsDatetime) as BahmniObservation
  151.             bmiStatusDataObservation = bmiStatusDataObservation ?: createObs("BMI Status Data", null, bahmniEncounterTransaction, obsDatetime) as BahmniObservation
  152.  
  153.             def bmi = bmi(height, weight)
  154.             bmiObservation = bmiObservation ?: createObs("BMI", bmiDataObservation, bahmniEncounterTransaction, obsDatetime) as BahmniObservation;
  155.             bmiObservation.setValue(bmi);
  156.  
  157.             def bmiStatus = bmiStatus(bmi, patientAgeInMonthsAsOfEncounter, patient.getGender());
  158.             bmiStatusObservation = bmiStatusObservation ?: createObs("BMI Status", bmiStatusDataObservation, bahmniEncounterTransaction, obsDatetime) as BahmniObservation;
  159.             bmiStatusObservation.setValue(bmiStatus);
  160.  
  161.             def bmiAbnormal = bmiAbnormal(bmiStatus);
  162.             bmiAbnormalObservation =  bmiAbnormalObservation ?: createObs("BMI Abnormal", bmiDataObservation, bahmniEncounterTransaction, obsDatetime) as BahmniObservation;
  163.             bmiAbnormalObservation.setValue(bmiAbnormal);
  164.  
  165.             bmiStatusAbnormalObservation =  bmiStatusAbnormalObservation ?: createObs("BMI Status Abnormal", bmiStatusDataObservation, bahmniEncounterTransaction, obsDatetime) as BahmniObservation;
  166.             bmiStatusAbnormalObservation.setValue(bmiAbnormal);
  167.  
  168.             return
  169.         }
  170.  
  171.         BahmniObservation waistCircumferenceObservation = find("Waist Circumference", observations, null)
  172.         BahmniObservation hipCircumferenceObservation = find("Hip Circumference", observations, null)
  173.         if (hasValue(waistCircumferenceObservation) && hasValue(hipCircumferenceObservation)) {
  174.             def calculatedConceptName = "Waist/Hip Ratio"
  175.             BahmniObservation calculatedObs = find(calculatedConceptName, observations, null)
  176.             parent = obsParent(waistCircumferenceObservation, null)
  177.  
  178.             Date obsDatetime = getDate(waistCircumferenceObservation)
  179.             def waistCircumference = waistCircumferenceObservation.getValue() as Double
  180.             def hipCircumference = hipCircumferenceObservation.getValue() as Double
  181.             def waistByHipRatio = waistCircumference/hipCircumference
  182.             if (calculatedObs == null)
  183.                 calculatedObs = createObs(calculatedConceptName, parent, bahmniEncounterTransaction, obsDatetime) as BahmniObservation
  184.  
  185.             calculatedObs.setValue(waistByHipRatio)
  186.             return
  187.         }
  188.  
  189.         BahmniObservation lmpObservation = find("Obstetrics, Last Menstrual Period", observations, null)
  190.         def calculatedConceptName = "Estimated Date of Delivery"
  191.         if (hasValue(lmpObservation)) {
  192.             parent = obsParent(lmpObservation, null)
  193.             def calculatedObs = find(calculatedConceptName, observations, null)
  194.  
  195.             Date obsDatetime = getDate(lmpObservation)
  196.  
  197.             LocalDate edd = new LocalDate(lmpObservation.getValue()).plusMonths(9).plusWeeks(1)
  198.             if (calculatedObs == null)
  199.                 calculatedObs = createObs(calculatedConceptName, parent, bahmniEncounterTransaction, obsDatetime) as BahmniObservation
  200.             calculatedObs.setValue(edd)
  201.             return
  202.         } else {
  203.             def calculatedObs = find(calculatedConceptName, observations, null)
  204.             if (hasValue(calculatedObs)) {
  205.                 voidObs(calculatedObs)
  206.             }
  207.         }
  208.     }
  209.  
  210.     private static BahmniObservation obsParent(BahmniObservation child, BahmniObservation parent) {
  211.         if (parent != null) return parent;
  212.  
  213.         if(child != null) {
  214.             return obsParentMap.get(child)
  215.         }
  216.     }
  217.  
  218.     private static Date getDate(BahmniObservation observation) {
  219.         return hasValue(observation) && !observation.voided ? observation.getObservationDateTime() : null;
  220.     }
  221.  
  222.     private static boolean isSameObs(BahmniObservation observation, Obs editedObs) {
  223.         if(observation && editedObs) {
  224.             return  (editedObs.uuid == observation.encounterTransactionObservation.uuid && editedObs.valueNumeric == observation.value);
  225.         } else if(observation == null && editedObs == null) {
  226.             return true;
  227.         }
  228.         return false;
  229.     }
  230.  
  231.     private static boolean hasValue(BahmniObservation observation) {
  232.         return observation != null && observation.getValue() != null && !StringUtils.isEmpty(observation.getValue().toString());
  233.     }
  234.     private static boolean hasValueDate(BahmniObservation observation) {
  235.         return observation != null && observation.getValue() != null;
  236.     }
  237.  
  238.     private static void voidObs(BahmniObservation bmiObservation) {
  239.         if (hasValue(bmiObservation)) {
  240.             bmiObservation.voided = true
  241.         }
  242.     }
  243.  
  244.     private static void voidPreviousBMIObs(Set<Obs> bmiObs) {
  245.         if(bmiObs) {
  246.             bmiObs.each { Obs obs ->
  247.                 Concept concept = Context.getConceptService().getConceptByUuid(obs.getConcept().uuid);
  248.                 if (concept.getName().name.equalsIgnoreCase("BMI Data") || concept.getName().name.equalsIgnoreCase("BMI") ||
  249.                         concept.getName().name.equalsIgnoreCase("BMI ABNORMAL") || concept.getName().name.equalsIgnoreCase("BMI Status Data")
  250.                         || concept.getName().name.equalsIgnoreCase("BMI STATUS") || concept.getName().name.equalsIgnoreCase("BMI STATUS ABNORMAL")) {
  251.  
  252.                     obs.voided = true;
  253.                     obs.setVoidReason("Replaced with a new one because it was changed");
  254.                     Context.getObsService().saveObs(obs, "Replaced with a new one because it was changed");
  255.                 }
  256.             }
  257.         }
  258.     }
  259.  
  260.     static BahmniObservation createObs(String conceptName, BahmniObservation parent, BahmniEncounterTransaction encounterTransaction, Date obsDatetime) {
  261.         def concept = Context.getConceptService().getConceptByName(conceptName)
  262.         BahmniObservation newObservation = new BahmniObservation()
  263.         newObservation.setConcept(new EncounterTransaction.Concept(concept.getUuid(), conceptName))
  264.         newObservation.setObservationDateTime(obsDatetime);
  265.         parent == null ? encounterTransaction.addObservation(newObservation) : parent.addGroupMember(newObservation)
  266.         return newObservation
  267.     }
  268.  
  269.     static def bmi(Double height, Double weight) {
  270.         if (height == ZERO) {
  271.             throw new IllegalArgumentException("Please enter Height greater than zero")
  272.         } else if (weight == ZERO) {
  273.             throw new IllegalArgumentException("Please enter Weight greater than zero")
  274.         }
  275.         Double heightInMeters = height / 100;
  276.         Double value = weight / (heightInMeters * heightInMeters);
  277.         return new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
  278.     };
  279.  
  280.     static def bmiStatus(Double bmi, Integer ageInMonth, String gender) {
  281.         BMIChart bmiChart = readCSV(OpenmrsUtil.getApplicationDataDirectory() + "obscalculator/BMI_chart.csv");
  282.         def bmiChartLine = bmiChart.get(gender, ageInMonth);
  283.         if(bmiChartLine != null ) {
  284.             return bmiChartLine.getStatus(bmi);
  285.         }
  286.  
  287.         if (bmi < BMI_VERY_SEVERELY_UNDERWEIGHT) {
  288.             return BmiStatus.VERY_SEVERELY_UNDERWEIGHT;
  289.         }
  290.         if (bmi < BMI_SEVERELY_UNDERWEIGHT) {
  291.             return BmiStatus.SEVERELY_UNDERWEIGHT;
  292.         }
  293.         if (bmi < BMI_UNDERWEIGHT) {
  294.             return BmiStatus.UNDERWEIGHT;
  295.         }
  296.         if (bmi < BMI_NORMAL) {
  297.             return BmiStatus.NORMAL;
  298.         }
  299.         if (bmi < BMI_OVERWEIGHT) {
  300.             return BmiStatus.OVERWEIGHT;
  301.         }
  302.         if (bmi < BMI_OBESE) {
  303.             return BmiStatus.OBESE;
  304.         }
  305.         if (bmi < BMI_SEVERELY_OBESE) {
  306.             return BmiStatus.SEVERELY_OBESE;
  307.         }
  308.         if (bmi >= BMI_SEVERELY_OBESE) {
  309.             return BmiStatus.VERY_SEVERELY_OBESE;
  310.         }
  311.         return null
  312.     }
  313.  
  314.     static def bmiAbnormal(BmiStatus status) {
  315.         return status != BmiStatus.NORMAL;
  316.     };
  317.  
  318.     static Double fetchLatestValue(String conceptName, String patientUuid, BahmniObservation excludeObs, Date tillDate) {
  319.         SessionFactory sessionFactory = Context.getRegisteredComponents(SessionFactory.class).get(0)
  320.         def excludedObsIsSaved = excludeObs != null && excludeObs.uuid != null
  321.         String excludeObsClause = excludedObsIsSaved ? " and obs.uuid != :excludeObsUuid" : ""
  322.         Query queryToGetObservations = sessionFactory.getCurrentSession()
  323.                 .createQuery("select obs " +
  324.                 " from Obs as obs, ConceptName as cn " +
  325.                 " where obs.person.uuid = :patientUuid " +
  326.                 " and cn.concept = obs.concept.conceptId " +
  327.                 " and cn.name = :conceptName " +
  328.                 " and obs.voided = false" +
  329.                 " and obs.obsDatetime <= :till" +
  330.                 excludeObsClause +
  331.                 " order by obs.obsDatetime desc ");
  332.         queryToGetObservations.setString("patientUuid", patientUuid);
  333.         queryToGetObservations.setParameterList("conceptName", conceptName);
  334.         queryToGetObservations.setParameter("till", tillDate);
  335.         if (excludedObsIsSaved) {
  336.             queryToGetObservations.setString("excludeObsUuid", excludeObs.uuid)
  337.         }
  338.         queryToGetObservations.setMaxResults(1);
  339.         List<Obs> observations = queryToGetObservations.list();
  340.         if (observations.size() > 0) {
  341.             return observations.get(0).getValueNumeric();
  342.         }
  343.         return null
  344.     }
  345.  
  346.     static BahmniObservation find(String conceptName, Collection<BahmniObservation> observations, BahmniObservation parent) {
  347.         for (BahmniObservation observation : observations) {
  348.             if (conceptName.equalsIgnoreCase(observation.getConcept().getName())) {
  349.                 obsParentMap.put(observation, parent);
  350.                 return observation;
  351.             }
  352.             BahmniObservation matchingObservation = find(conceptName, observation.getGroupMembers(), observation)
  353.             if (matchingObservation) return matchingObservation;
  354.         }
  355.         return null
  356.     }
  357.  
  358.     static BMIChart readCSV(String fileName) {
  359.         def chart = new BMIChart();
  360.         try {
  361.             new File(fileName).withReader { reader ->
  362.                 def header = reader.readLine();
  363.                 reader.splitEachLine(",") { tokens ->
  364.                     chart.add(new BMIChartLine(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]));
  365.                 }
  366.             }
  367.         } catch (FileNotFoundException e) {
  368.         }
  369.         return chart;
  370.     }
  371.  
  372.     static class BMIChartLine {
  373.         public String gender;
  374.         public Integer ageInMonth;
  375.         public Double third;
  376.         public Double fifteenth;
  377.         public Double eightyFifth;
  378.         public Double ninetySeventh;
  379.  
  380.         BMIChartLine(String gender, String ageInMonth, String third, String fifteenth, String eightyFifth, String ninetySeventh) {
  381.             this.gender = gender
  382.             this.ageInMonth = ageInMonth.toInteger();
  383.             this.third = third.toDouble();
  384.             this.fifteenth = fifteenth.toDouble();
  385.             this.eightyFifth = eightyFifth.toDouble();
  386.             this.ninetySeventh = ninetySeventh.toDouble();
  387.         }
  388.  
  389.         public BmiStatus getStatus(Double bmi) {
  390.             if(bmi < third) {
  391.                 return BmiStatus.SEVERELY_UNDERWEIGHT
  392.             } else if(bmi < fifteenth) {
  393.                 return BmiStatus.UNDERWEIGHT
  394.             } else if(bmi < eightyFifth) {
  395.                 return BmiStatus.NORMAL
  396.             } else if(bmi < ninetySeventh) {
  397.                 return BmiStatus.OVERWEIGHT
  398.             } else {
  399.                 return BmiStatus.OBESE
  400.             }
  401.         }
  402.     }
  403.  
  404.     static class BMIChart {
  405.         List<BMIChartLine> lines;
  406.         Map<BMIChartLineKey, BMIChartLine> map = new HashMap<BMIChartLineKey, BMIChartLine>();
  407.  
  408.         public add(BMIChartLine line) {
  409.             def key = new BMIChartLineKey(line.gender, line.ageInMonth);
  410.             map.put(key, line);
  411.         }
  412.  
  413.         public BMIChartLine get(String gender, Integer ageInMonth) {
  414.             def key = new BMIChartLineKey(gender, ageInMonth);
  415.             return map.get(key);
  416.         }
  417.     }
  418.  
  419.     static class BMIChartLineKey {
  420.         public String gender;
  421.         public Integer ageInMonth;
  422.  
  423.         BMIChartLineKey(String gender, Integer ageInMonth) {
  424.             this.gender = gender
  425.             this.ageInMonth = ageInMonth
  426.         }
  427.  
  428.         boolean equals(o) {
  429.             if (this.is(o)) return true
  430.             if (getClass() != o.class) return false
  431.  
  432.             BMIChartLineKey bmiKey = (BMIChartLineKey) o
  433.  
  434.             if (ageInMonth != bmiKey.ageInMonth) return false
  435.             if (gender != bmiKey.gender) return false
  436.  
  437.             return true
  438.         }
  439.  
  440.         int hashCode() {
  441.             int result
  442.             result = (gender != null ? gender.hashCode() : 0)
  443.             result = 31 * result + (ageInMonth != null ? ageInMonth.hashCode() : 0)
  444.             return result
  445.         }
  446.     }
  447. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement