private Encounter buildEncounter(
     EncounterType encounterType,
     Patient patient,
     Location location,
     Form form,
     Date when,
     List<Obs> obsToCreate,
     List<Order> ordersToCreate) {
   Encounter encounter = new Encounter();
   encounter.setPatient(patient);
   encounter.setEncounterType(encounterType);
   encounter.setLocation(location);
   encounter.setForm(form);
   encounter.setEncounterDatetime(when);
   if (obsToCreate != null) {
     for (Obs obs : obsToCreate) {
       obs.setObsDatetime(new Date());
       encounter.addObs(obs);
     }
   }
   if (ordersToCreate != null) {
     for (Order order : ordersToCreate) {
       encounter.addOrder(order);
     }
   }
   return encounter;
 }
  /**
   * Adds a new encounter with the given observations and orders.
   *
   * @param observations a list of observations
   * @param orderUuids a list of order UUIDs
   * @param patient the patient for whom to add the encounter
   * @param encounterTime the time of the encounter
   * @param changeMessage a message to be recorded with the observation
   * @param encounterTypeName the OpenMRS name for the encounter type, configured in OpenMRS
   * @param locationUuid the UUID of the location where the encounter happened
   */
  public static Encounter addEncounter(
      List observations,
      List orderUuids,
      Patient patient,
      Date encounterTime,
      String changeMessage,
      String encounterTypeName,
      String locationUuid) {
    // OpenMRS will reject the encounter if the time is in the past, even if
    // the client's clock is off by only one millisecond; work around this.
    encounterTime = Utils.fixEncounterDateTime(encounterTime);

    EncounterService encounterService = Context.getEncounterService();
    final Location location = Context.getLocationService().getLocationByUuid(locationUuid);
    if (location == null) {
      throw new InvalidObjectDataException("Location not found: " + locationUuid);
    }
    EncounterType encounterType = encounterService.getEncounterType(encounterTypeName);
    if (encounterType == null) {
      throw new InvalidObjectDataException("Encounter type not found: " + encounterTypeName);
    }

    List<Obs> obsList = new ArrayList<>();
    if (observations != null) {
      for (Object observation : observations) {
        obsList.add(jsonObservationToObs(observation, patient, encounterTime, location));
      }
    }

    if (orderUuids != null) {
      for (Object item : orderUuids) {
        obsList.add(orderUuidToObs((String) item, patient, encounterTime, location));
      }
    }

    // Write the encounter and all the observations to the database.
    Encounter encounter = new Encounter();
    encounter.setEncounterDatetime(encounterTime);
    encounter.setPatient(patient);
    encounter.setLocation(location);
    encounter.setEncounterType(encounterType);
    encounter = encounterService.saveEncounter(encounter);

    ObsService obsService = Context.getObsService();
    for (Obs obs : obsList) {
      if (obs != null) {
        encounter.addObs(obs);
        obsService.saveObs(obs, changeMessage);
      }
    }
    return encounter;
  }
  @RequestMapping("/module/hirifxray/uploadXray.form")
  public String uploadXray(
      ModelMap model,
      @RequestParam(value = "patientId", required = true) Patient patient,
      @RequestParam(value = "xrayId", required = false) Encounter encounter,
      @RequestParam(value = "xrayDate", required = false) Date encounterDate,
      @RequestParam(value = "type", required = true) Concept type,
      @RequestParam(value = "status", required = false) Concept status,
      @RequestParam(value = "location", required = false) Concept location,
      @RequestParam(value = "xrayFile", required = false) MultipartFile xrayFile)
      throws Exception {

    ComplexData xrayData = null;
    if (xrayFile != null && !xrayFile.isEmpty()) {
      String identifier = patient.getPatientIdentifier().getIdentifier();
      String[] fileParts = xrayFile.getOriginalFilename().split("\\.");
      String xrayKey = identifier + "_" + type + "." + fileParts[fileParts.length - 1];
      xrayData = new ComplexData(xrayKey, xrayFile.getInputStream());
    }

    if (encounter == null) {
      encounter = new Encounter();
      encounter.setPatient(patient);
      encounter.setEncounterType(HirifMetadata.getEncounterType());
    }
    encounter.setEncounterDatetime(
        encounterDate == null ? HirifUtil.dateMidnight() : encounterDate);

    HirifUtil.updateCodedObs(encounter, HirifMetadata.getXrayTypeConcept(), type);
    HirifUtil.updateCodedObs(encounter, HirifMetadata.getXrayStatusConcept(), status);
    HirifUtil.updateCodedObs(encounter, HirifMetadata.getXrayLocationConcept(), location);
    HirifUtil.updateComplexObs(encounter, HirifMetadata.getXrayImageConcept(), xrayData);

    encounter = Context.getEncounterService().saveEncounter(encounter);

    return "redirect:/module/hirifxray/participant.form?id="
        + patient.getPatientId()
        + "&type="
        + type
        + "&xrayId="
        + encounter.getEncounterId();
  }
  @Test
  public void shouldEvaluateOBRORUR01TemplateForOBSGroup() throws Exception {
    // given
    Encounter encounter = new Encounter();

    Date date = new Date();
    encounter.setEncounterDatetime(date);
    encounter.setUuid("ENCOUNTER UUID");

    EncounterType encounterType = new EncounterType();
    encounterType.setName("ENCOUNTER TYPE NAME");
    encounter.setEncounterType(encounterType);

    Location location = new Location(1);
    location.setUuid("LOCATION UUID");
    location.setName("LOCATION NAME");
    encounter.setLocation(location);

    Person provider = new Person(1);
    provider.setUuid("PROVIDER UUID");
    provider.addName(
        new PersonName("PROVIDER GIVENNAME", "PROVIDER MIDDLENAME", "PROVIDER FAMILYNAME"));
    encounter.setProvider(provider);

    ConceptSource source = new ConceptSource();
    source.setName("AMPATH");

    ConceptMap map = new ConceptMap();
    map.setSourceCode("200");
    map.setSource(source);

    ConceptDatatype datatype = new ConceptDatatype();
    datatype.setUuid(ConceptDatatype.NUMERIC_UUID);
    datatype.setHl7Abbreviation(ConceptDatatype.NUMERIC);

    ConceptNumeric concept = new ConceptNumeric();
    concept.setDatatype(datatype);
    concept.addConceptMapping(map);
    concept.addName(new ConceptName("NumericConcept", Locale.ENGLISH));
    concept.setUnits("mg");

    Date dateCreated = new Date(213231421890234L);

    Obs obs = new Obs(2);
    obs.setConcept(concept);
    obs.setDateCreated(dateCreated);
    obs.setValueNumeric(10d);

    obs.setObsGroup(getObsGroup());
    obs.getObsGroup().addGroupMember(obs);

    encounter.addObs(obs);

    obs = new Obs(3);
    obs.setConcept(concept);
    obs.setDateCreated(dateCreated);
    obs.setValueNumeric(23d);
    encounter.addObs(obs);

    Map<String, Object> bindings = new HashMap<String, Object>();
    bindings.put("encounter", encounter);
    bindings.put("implementationId", "MVP");

    // when
    HL7Template hl7Template = hl7QueryService.getHL7TemplateByName("Generic Obs Group");
    String evaluatedTemplate = hl7QueryService.evaluateTemplate(hl7Template, bindings);

    // then
    evaluatedTemplate = StringUtils.deleteWhitespace(evaluatedTemplate);
    Assert.assertEquals(
        "<ORU_R01.ORDER_OBSERVATION><OBR><OBR.1>0</OBR.1><OBR.4><CE.1>100</CE.1>"
            + "<CE.2>MEDICALRECORDOBSERVATIONS</CE.2><CE.3>LOCAL</CE.3></OBR.4><OBR.18>0</OBR.18>"
            + "<OBR.29><EIP.2><EI.3>ENCOUNTERUUID</EI.3></EIP.2></OBR.29></OBR><ORU_R01.OBSERVATION>"
            + "<OBX><OBX.1>1</OBX.1><OBX.2>NM</OBX.2><OBX.3><CE.1>200</CE.1><CE.2>NumericConcept</CE.2>"
            + "<CE.3>AMPATH</CE.3></OBX.3><OBX.5>23.0</OBX.5><OBX.6><CE.1>mg</CE.1><CE.3>UCUM</CE.3></OBX.6>"
            + "<OBX.14><TS.1>"
            + new HL7TemplateFunctions().formatDate(dateCreated, null)
            + "</TS.1>"
            + "</OBX.14></OBX></ORU_R01.OBSERVATION></ORU_R01.ORDER_OBSERVATION>"
            + "<ORU_R01.ORDER_OBSERVATION><OBR><OBR.1>2</OBR.1><OBR.4><CE.1>100</CE.1><CE.2>MedSet</CE.2>"
            + "<CE.3>LOCAL</CE.3></OBR.4><OBR.18>0</OBR.18><OBR.29><EIP.2><EI.3>ENCOUNTERUUID</EI.3></EIP.2></OBR.29"
            + "></OBR><ORU_R01.OBSERVATION><OBX><OBX.1>2</OBX.1><OBX.2>NM</OBX.2><OBX.3><CE.1>200</CE.1>"
            + "<CE.2>NumericConcept</CE.2><CE.3>AMPATH</CE.3></OBX.3><OBX.5>10.0</OBX.5><OBX.6><CE.1>mg</CE.1>"
            + "<CE.3>UCUM</CE.3></OBX.6><OBX.14><TS.1>"
            + new HL7TemplateFunctions().formatDate(dateCreated, null)
            + "</TS.1></OBX.14></OBX></ORU_R01.OBSERVATION></ORU_R01.ORDER_OBSERVATION>",
        evaluatedTemplate);
  }