public void controller(
      @FragmentParam("patient") Patient patient,
      FragmentModel model,
      UiUtils ui,
      @SpringBean CoreContext emr) {

    String[] page1FormUuids = {Metadata.FAMILY_HISTORY_FORM, Metadata.HIV_PROGRAM_ENROLLMENT_FORM};

    List<SimpleObject> page1AvailableForms = new ArrayList<SimpleObject>();
    List<Encounter> page1Encounters = new ArrayList<Encounter>();

    for (String page1FormUuid : page1FormUuids) {
      Form page1Form = MetadataUtils.getForm(page1FormUuid);
      List<Encounter> formEncounters = getPatientEncounterByForm(patient, page1Form);

      if (formEncounters.size() == 0) {
        page1AvailableForms.add(ui.simplifyObject(page1Form));
      } else {
        page1Encounters.addAll(formEncounters);
      }
    }

    Form moh257VisitForm = MetadataUtils.getForm(Metadata.MOH_257_VISIT_SUMMARY_FORM);
    List<Encounter> moh257VisitSummaryEncounters =
        getPatientEncounterByForm(patient, moh257VisitForm);

    model.addAttribute("page1AvailableForms", page1AvailableForms);
    model.addAttribute("page1Encounters", page1Encounters);
    model.addAttribute("page2Form", moh257VisitForm);
    model.addAttribute("page2Encounters", moh257VisitSummaryEncounters);

    Concept masterSet = emr.getRegimenManager().getMasterSetConcept("ARV");
    RegimenChangeHistory arvHistory = RegimenChangeHistory.forPatient(patient, masterSet);
    model.addAttribute("arvHistory", arvHistory);
  }
  SimpleObject simplify(UiUtils ui, EmrApiProperties emrApiProperties, Patient patient) {
    PersonName name = patient.getPersonName();
    SimpleObject preferredName =
        SimpleObject.fromObject(name, ui, "givenName", "middleName", "familyName", "familyName2");
    preferredName.put("name", ui.format(name));

    PatientIdentifierType primaryIdentifierType = emrApiProperties.getPrimaryIdentifierType();
    List<PatientIdentifier> primaryIdentifiers =
        patient.getPatientIdentifiers(primaryIdentifierType);

    SimpleObject o =
        SimpleObject.fromObject(
            patient, ui, "patientId", "gender", "age", "birthdate", "birthdateEstimated");
    o.put("preferredName", preferredName);
    o.put("primaryIdentifiers", SimpleObject.fromCollection(primaryIdentifiers, ui, "identifier"));

    return o;
  }
  /** Validate patient records */
  @AppAction(EmrConstants.APP_DEVELOPER)
  public List<SimpleObject> validatePatients(UiUtils ui) {
    List<SimpleObject> problems = new ArrayList<SimpleObject>();

    for (Patient patient : Context.getPatientService().getAllPatients()) {
      BindException errors = new BindException(patient, "");
      Context.getAdministrationService().validate(patient, errors);

      if (errors.hasErrors()) {
        SimpleObject problem = new SimpleObject();
        problem.put("patient", ui.simplifyObject(patient));
        problem.put("errors", uniqueErrorMessages(errors));
        problem.put("cause", errors.getCause());
        problems.add(problem);
      }
    }

    return problems;
  }
  public void controller(
      FragmentModel model,
      @FragmentParam("visit") Visit visit,
      UiUtils ui,
      PageRequest request,
      @SpringBean CoreContext emr,
      @SpringBean KenyaUiUtils kenyaUi) {

    AppDescriptor currentApp = kenyaUi.getCurrentApp(request);

    List<SimpleObject> availableForms = new ArrayList<SimpleObject>();

    for (FormDescriptor descriptor :
        emr.getFormManager().getUncompletedFormsForVisit(currentApp, visit)) {
      availableForms.add(ui.simplifyObject(descriptor.getTarget()));
    }

    model.addAttribute("availableForms", availableForms);
  }
  public void controller(
      @RequestParam(value = "patientId", required = false) Patient patient,
      @RequestParam(value = "headerForm") String headerForm,
      @RequestParam(value = "flowsheets") String[] flowsheets,
      @RequestParam(value = "viewOnly", required = false) Boolean viewOnly,
      @RequestParam(value = "requireEncounter", required = false) Boolean requireEncounter,
      UiUtils ui,
      PageModel model,
      @SpringBean("htmlFormEntryService") HtmlFormEntryService htmlFormEntryService,
      @SpringBean("formService") FormService formService,
      @SpringBean("locationService") LocationService locationService,
      @SpringBean("coreResourceFactory") ResourceFactory resourceFactory,
      @InjectBeans PatientDomainWrapper patientDomainWrapper,
      PageRequest pageRequest) {

    patientDomainWrapper.setPatient(patient);
    model.addAttribute("patient", patientDomainWrapper);
    model.addAttribute("headerForm", headerForm);
    model.addAttribute("flowsheets", flowsheets);
    model.addAttribute("requireEncounter", (requireEncounter == null || requireEncounter));

    Location defaultLocation = null;
    Integer locationId =
        pageRequest
            .getSession()
            .getAttribute(PihMalawiWebConstants.SESSION_LOCATION_ID, Integer.TYPE);
    if (locationId != null) {
      defaultLocation = locationService.getLocation(locationId);
    }

    List<Encounter> allEncounters = new ArrayList<Encounter>();

    List<String> alerts = new ArrayList<String>();

    String headerFormResource = "pihmalawi:htmlforms/" + headerForm + ".xml";

    HtmlForm headerHtmlForm =
        getHtmlFormFromResource(
            headerFormResource, resourceFactory, formService, htmlFormEntryService);
    model.addAttribute("headerForm", headerForm);

    Encounter headerEncounter = null;
    List<Encounter> headerEncounters = getEncountersForForm(patient, headerHtmlForm);
    if (headerEncounters.size() > 0) {
      headerEncounter = headerEncounters.get(headerEncounters.size() - 1); // Most recent
      if (headerEncounters.size() > 1) {
        alerts.add(
            "WARNING:  More than one "
                + headerHtmlForm.getName()
                + " encounters exist for this patient.  Displaying the most recent only.");
      }
      allEncounters.add(headerEncounter);
    }
    model.addAttribute("headerEncounter", headerEncounter);

    Map<String, HtmlForm> flowsheetForms = new LinkedHashMap<String, HtmlForm>();
    Map<String, List<Integer>> flowsheetEncounters = new LinkedHashMap<String, List<Integer>>();
    if (flowsheets != null) {
      for (String flowsheet : flowsheets) {
        String flowsheetResource = "pihmalawi:htmlforms/" + flowsheet + ".xml";
        HtmlForm htmlForm =
            getHtmlFormFromResource(
                flowsheetResource, resourceFactory, formService, htmlFormEntryService);
        flowsheetForms.put(flowsheet, htmlForm);
        List<Integer> encIds = new ArrayList<Integer>();
        List<Encounter> encounters = getEncountersForForm(patient, htmlForm);
        for (Encounter e : encounters) {
          encIds.add(e.getEncounterId());
          allEncounters.add(e);
        }
        flowsheetEncounters.put(flowsheet, encIds);
      }
    }
    model.addAttribute("flowsheetForms", flowsheetForms);
    model.addAttribute("flowsheetEncounters", flowsheetEncounters);

    model.addAttribute("alerts", alerts);

    if (defaultLocation == null) {
      Date maxDate = null;
      if (allEncounters.size() > 0) {
        for (Encounter e : allEncounters) {
          if (maxDate == null || maxDate.compareTo(e.getEncounterDatetime()) < 0) {
            maxDate = e.getEncounterDatetime();
            defaultLocation = e.getLocation();
          }
        }
      }
    }
    model.addAttribute(
        "defaultLocationId", defaultLocation == null ? null : defaultLocation.getLocationId());
    model.addAttribute("viewOnly", viewOnly == Boolean.TRUE);

    model.addAttribute(
        "returnUrl",
        ui.pageLink(
            "pihmalawi",
            "mastercard",
            SimpleObject.create(
                "patientId",
                patient.getId(),
                "headerForm",
                headerForm,
                "flowsheets",
                flowsheets,
                "viewOnly",
                viewOnly)));
  }
  /**
   * @should void the old person address and replace it with a new one when it is edited
   * @should void the old person address and replace it with a new one when it is edited
   * @should not void the existing address if there are no changes
   */
  public String post(
      UiSessionContext sessionContext,
      PageModel model,
      @RequestParam("patientId") @BindParams Patient patient,
      @BindParams PersonAddress address,
      @SpringBean("patientService") PatientService patientService,
      @RequestParam("appId") AppDescriptor app,
      @RequestParam("returnUrl") String returnUrl,
      @SpringBean("adminService") AdministrationService administrationService,
      HttpServletRequest request,
      @SpringBean("messageSourceService") MessageSourceService messageSourceService,
      Session session,
      @SpringBean("patientValidator") PatientValidator patientValidator,
      UiUtils ui)
      throws Exception {

    sessionContext.requireAuthentication();

    if (patient.getPersonAddress() != null && address != null) {
      PersonAddress currentAddress = patient.getPersonAddress();
      if (!currentAddress.equalsContent(address)) {
        // void the old address and replace it with the new one
        patient.addAddress(address);
        currentAddress.setVoided(true);
      }
    }

    NavigableFormStructure formStructure = RegisterPatientFormBuilder.buildFormStructure(app);

    BindingResult errors = new BeanPropertyBindingResult(patient, "patient");
    patientValidator.validate(patient, errors);
    RegistrationAppUiUtils.validateLatitudeAndLongitudeIfNecessary(address, errors);

    if (formStructure != null) {
      RegisterPatientFormBuilder.resolvePersonAttributeFields(
          formStructure, patient, request.getParameterMap());
    }

    if (!errors.hasErrors()) {
      try {
        // The person address changes get saved along as with the call to save patient
        patientService.savePatient(patient);
        InfoErrorMessageUtil.flashInfoMessage(
            request.getSession(),
            ui.message("registrationapp.editContactInfoMessage.success", patient.getPersonName()));

        return "redirect:" + returnUrl;
      } catch (Exception e) {
        log.warn("Error occurred while saving patient's contact info", e);
        session.setAttribute(
            UiCommonsConstants.SESSION_ATTRIBUTE_ERROR_MESSAGE, "registrationapp.save.fail");
      }

    } else {
      model.addAttribute("errors", errors);
      StringBuffer errorMessage =
          new StringBuffer(messageSourceService.getMessage("error.failed.validation"));
      errorMessage.append("<ul>");
      for (ObjectError error : errors.getAllErrors()) {
        errorMessage.append("<li>");
        errorMessage.append(
            messageSourceService.getMessage(
                error.getCode(), error.getArguments(), error.getDefaultMessage(), null));
        errorMessage.append("</li>");
      }
      errorMessage.append("</ul>");
      session.setAttribute(
          UiCommonsConstants.SESSION_ATTRIBUTE_ERROR_MESSAGE, errorMessage.toString());
    }

    addModelAttributes(model, patient, formStructure, administrationService, returnUrl);
    // redisplay the form
    return null;
  }