/** @see {@link HtmlFormEntryUtil#isEnrolledInProgram(Patient,Program,Date)} */
  @Test
  @Verifies(
      value =
          "should return false if the date is before the existing patient program enrollment date",
      method = "isEnrolledInProgram(Patient,Program,Date)")
  public void
      isEnrolledInProgram_shouldReturnFalseIfTheDateIsBeforeTheExistingPatientProgramEnrollmentDateIgnoringTimeFields()
          throws Exception { // 2008-08-01 00:00:00.0
    ProgramWorkflowService pws = Context.getProgramWorkflowService();
    Patient patient = Context.getPatientService().getPatient(2);
    Program program = pws.getProgram(1);
    PatientProgram pp = pws.getPatientProgram(1);

    Calendar cal = Calendar.getInstance();
    cal.set(2008, 6, 31);
    Date newEnrollmentDate = cal.getTime();
    Assert.assertTrue(newEnrollmentDate.before(pp.getDateEnrolled())); // sanity check
    Assert.assertFalse(
        HtmlFormEntryUtil.isEnrolledInProgramOnDate(patient, program, newEnrollmentDate));
  }
  public DataSetRow renderRow(
      Patient p,
      PatientIdentifierType patientIdentifierType,
      Location location,
      Date startDate,
      Date endDate) {

    PatientDataHelper pdh = new PatientDataHelper();
    ProgramHelper ph = new ProgramHelper();
    HivMetadata hivMetadata = new HivMetadata();

    DataSetRow row = new DataSetRow();
    pdh.addCol(row, "#", p.getPatientId());
    pdh.addCol(row, "KS ID", pdh.preferredIdentifierAtLocation(p, patientIdentifierType, location));
    pdh.addCol(
        row,
        "ART ID",
        pdh.preferredIdentifierAtLocation(p, lookupPatientIdentifierType("ARV Number"), location));
    pdh.addCol(row, "Birthdate", pdh.getBirthdate(p));
    pdh.addCol(row, "Gender", pdh.getGender(p));
    pdh.addCol(row, "VHW", pdh.vhwName(p, false));
    pdh.addCol(row, "Village", pdh.getVillage(p));

    PatientProgram latestKsProgram =
        ph.getMostRecentProgramEnrollmentAtLocation(
            p, lookupProgram("Kaposis sarcoma program"), location);

    Date latestKsProgramDate = null;
    if (latestKsProgram != null) {
      latestKsProgramDate = latestKsProgram.getDateEnrolled();
      pdh.addCol(row, "KS Program Enrollment Date", pdh.formatYmd(latestKsProgramDate));

      for (PatientState ps : ph.getActiveStatesOnDate(p, latestKsProgramDate)) {
        String programName = ps.getPatientProgram().getProgram().getName();
        pdh.addCol(row, programName + " Status at Enrollment", pdh.formatStateName(ps));
        pdh.addCol(row, programName + " Status Date at Enrollment", pdh.formatStateStartDate(ps));
      }
    }

    Obs mostRecentDxDate = pdh.getLatestObs(p, "DATE OF HIV DIAGNOSIS", null, endDate);
    pdh.addCol(row, "Date HIV Diagnosis", pdh.formatValueDatetime(mostRecentDxDate));

    Program hivProgram = hivMetadata.getHivProgram();
    ProgramWorkflowState onArvState = hivMetadata.getOnArvsState();

    PatientState earliestOnArvsState = ph.getFirstTimeInState(p, hivProgram, onArvState, endDate);
    Date arvStartDate = (earliestOnArvsState == null ? null : earliestOnArvsState.getStartDate());

    if (latestKsProgramDate != null) {
      pdh.addCol(
          row,
          "On ART at KS Enrollment",
          arvStartDate != null && arvStartDate.compareTo(latestKsProgramDate) <= 0);
    }

    Map<String, String> reasonsForStartingArvs = pdh.getReasonStartingArvs(p, endDate);
    for (String reasonKey : reasonsForStartingArvs.keySet()) {
      pdh.addCol(row, "ARV Reason " + reasonKey, reasonsForStartingArvs.get(reasonKey));
    }

    if (arvStartDate != null) {
      pdh.addCol(row, "Start Date for ART", pdh.formatStateStartDate(earliestOnArvsState));
      if (latestKsProgramDate != null) {
        pdh.addCol(
            row,
            "Months on ART at KS Enrollment",
            DateUtil.monthsBetween(arvStartDate, latestKsProgramDate));
      }
    }

    if (latestKsProgramDate != null) {
      Obs artRegimen =
          pdh.getLatestObs(p, "Malawi Antiretroviral drugs received", null, latestKsProgramDate);
      pdh.addCol(row, "ART Regimen Obs at Enrollment", pdh.formatValue(artRegimen));

      Set<Concept> drugOrdersAtEnrollment = pdh.getDrugsTakingOnDate(p, latestKsProgramDate);
      pdh.addCol(
          row, "Drugs Taking at Enrollment", pdh.formatConcepts(drugOrdersAtEnrollment, "+"));

      Obs cd4 = pdh.getLatestObs(p, "CD4 count", null, latestKsProgramDate);
      pdh.addCol(row, "CD4 at enrollment", pdh.formatValue(cd4));
      pdh.addCol(row, "CD4 at enrollment date", pdh.formatObsDatetime(cd4));
    }

    Obs height = pdh.getLatestObs(p, "Height (cm)", null, endDate);
    pdh.addCol(row, "Latest Height", pdh.formatValue(height));
    pdh.addCol(row, "Latest Height Date", pdh.formatObsDatetime(height));

    Obs firstTaxolObs = pdh.getEarliestObs(p, "Paclitaxel (taxol) dose received", null, endDate);
    pdh.addCol(row, "First Taxol Dose Received Date", pdh.formatObsDatetime(firstTaxolObs));

    DrugOrder firstTaxolOrder = pdh.getEarliestDrugOrder(p, "Paclitaxel", endDate);
    pdh.addCol(row, "First Taxol Drug Order Date", pdh.formatOrderStartDate(firstTaxolOrder));

    Date firstTaxolDate = null;
    if (firstTaxolObs != null) {
      firstTaxolDate = firstTaxolObs.getObsDatetime();
    }
    if (firstTaxolOrder != null) {
      if (firstTaxolDate == null || firstTaxolOrder.getStartDate().before(firstTaxolDate)) {
        firstTaxolDate = firstTaxolOrder.getStartDate();
      }
    }
    pdh.addCol(row, "First Taxol Date", pdh.formatYmd(firstTaxolDate));

    if (firstTaxolDate != null) {
      Obs cd4AtTaxol = pdh.getLatestObs(p, "CD4 count", null, firstTaxolDate);
      pdh.addCol(row, "Most recent CD4 at First Taxol", pdh.formatValue(cd4AtTaxol));
      pdh.addCol(row, "Most recent CD4 at First Taxol Date", pdh.formatObsDatetime(cd4AtTaxol));
    }

    for (PatientState ps : ph.getActiveStatesOnDate(p, endDate)) {
      String ed = pdh.formatYmd(endDate);
      String programName = ps.getPatientProgram().getProgram().getName();
      pdh.addCol(row, programName + " Status on " + ed, pdh.formatStateName(ps));
      pdh.addCol(row, programName + " Status Date on " + ed, pdh.formatStateStartDate(ps));
    }

    pdh.addCol(row, "Death Date", pdh.formatYmd(p.getDeathDate()));

    return row;
  }
  @Override
  public String getOverrideContent(String str) {
    if (!Context.isAuthenticated()) {
      return "";
    }
    String gp =
        Context.getAdministrationService()
            .getGlobalProperty("htmlformflowsheet.patientChartFormIds");

    if (StringUtils.isEmpty(gp)) {
      return "";
    }

    StringBuilder sbExisting = new StringBuilder("");
    StringBuilder sbNonExisting = new StringBuilder("");
    try {
      String patientId = this.getParameterMap().get("patientId");
      Patient p = Context.getPatientService().getPatient(Integer.valueOf(patientId));

      for (StringTokenizer st = new StringTokenizer(gp, ","); st.hasMoreTokens(); ) {

        Map<Integer, Set<Integer>> progForms = new HashMap<Integer, Set<Integer>>();
        Set<Integer> programIds = new HashSet<Integer>();

        String formId = st.nextToken().trim();
        if (formId.contains(":")) {
          String[] formIdSplit = formId.split(":");
          formId = formIdSplit[0];
          // check for required programs:
          String programInfo = formIdSplit[1];
          if (programInfo.contains("|")) {
            for (StringTokenizer strTok = new StringTokenizer(programInfo, "|");
                strTok.hasMoreTokens(); ) {
              String sTmp = strTok.nextToken().trim();
              addFormToProgramList(progForms, Integer.valueOf(formId), Integer.valueOf(sTmp));
              programIds.add(Integer.valueOf(sTmp));
            }
          } else {
            // todo: support lookup programs by uuid and forms by uuid?
            addFormToProgramList(progForms, Integer.valueOf(formId), Integer.valueOf(programInfo));
            programIds.add(Integer.valueOf(programInfo));
          }
        }
        Form form = HtmlFormFlowsheetUtil.getFormFromString(formId);
        List<PatientProgram> pps =
            Context.getProgramWorkflowService()
                .getPatientPrograms(p, null, null, null, null, null, false);
        List<Encounter> encs =
            Context.getEncounterService()
                .getEncounters(
                    p, null, null, null, Collections.singletonList(form), null, null, false);

        //	            for (Map.Entry<Integer, Set<Integer>> m : progForms.entrySet()){
        //	            	System.out.println(m.getKey()+ ":" + m.getValue());
        //	            }

        // 1. no program association to form.  always show.
        if (progForms.get(Integer.valueOf(formId)) == null
            || progForms.get(Integer.valueOf(formId)).size() == 0) {
          if (encs.size() == 0) {
            // if no encs, show add new
            sbNonExisting.append(
                " | <a href=\"/"
                    + WebConstants.WEBAPP_NAME
                    + "/module/htmlformentry/htmlFormEntry.form?personId="
                    + p.getPersonId()
                    + "&patientId="
                    + p.getPatientId()
                    + "&returnUrl=&formId="
                    + form.getFormId()
                    + "\">"
                    + form.getName()
                    + "</a> | ");
          } else {
            // if encs, show existing flowsheet parent(s)
            for (Encounter e : encs) {
              sbExisting.append(
                  " | <a href=\"/"
                      + WebConstants.WEBAPP_NAME
                      + "/module/htmlformentry/htmlFormEntry.form?encounterId="
                      + e.getEncounterId()
                      + "&mode=EDIT\">"
                      + form.getName()
                      + " "
                      + "("
                      + Context.getDateFormat().format(e.getEncounterDatetime())
                      + ")</a> | ");
            }
          }
        } else {
          // 2. program(s) specified for form
          // this builds a map of encounter corresponding to the parent form creation to the
          // patientProgram is was created in.
          Map<Encounter, PatientProgram> encounterToPatientProgram =
              new HashMap<Encounter, PatientProgram>();
          for (Encounter e : encs) {
            for (PatientProgram pp : pps) {

              // if encounter is later than start date and less than end date or end date is null
              if (programIds.contains(pp.getProgram().getProgramId())
                  && e.getEncounterDatetime().getTime() >= pp.getDateEnrolled().getTime()
                  && ((pp.getDateCompleted() == null
                      || pp.getDateCompleted().getTime() >= e.getEncounterDatetime().getTime()))) {
                // encounter is in patientprogram
                encounterToPatientProgram.put(e, pp);
              }
            }
          }
          // show existing based on the map
          for (Map.Entry<Encounter, PatientProgram> m : encounterToPatientProgram.entrySet()) {
            sbExisting.append(
                " | <a href=\"/"
                    + WebConstants.WEBAPP_NAME
                    + "/module/htmlformentry/htmlFormEntry.form?encounterId="
                    + m.getKey().getEncounterId()
                    + "&mode=EDIT\">"
                    + form.getName());
            if (m.getValue() != null) {
              sbExisting.append(
                  " "
                      + "("
                      + Context.getDateFormat().format(m.getValue().getDateEnrolled())
                      + " - ");
              if (m.getValue().getDateCompleted() != null)
                sbExisting.append(Context.getDateFormat().format(m.getValue().getDateCompleted()));
              sbExisting.append(")");
            }
            sbExisting.append("</a> | ");
          }

          // show add new
          // if patient is in program currently, AND patient doesn't have an encounter for this
          // program
          PatientProgram ppActive = activePatientProgram(pps, programIds);
          boolean found = false;
          if (ppActive != null) {
            for (Map.Entry<Encounter, PatientProgram> m : encounterToPatientProgram.entrySet()) {
              if (m.getValue() != null && m.getValue().equals(ppActive)) found = true;
            }
            if (!found)
              sbNonExisting.append(
                  " | <a href=\"/"
                      + WebConstants.WEBAPP_NAME
                      + "/module/htmlformentry/htmlFormEntry.form?personId="
                      + p.getPersonId()
                      + "&patientId="
                      + p.getPatientId()
                      + "&returnUrl=&formId="
                      + form.getFormId()
                      + "\"> "
                      + form.getName()
                      + "</a> | ");
          }
        }
      }
      String retString = "<table><tr><td>";
      if (!sbExisting.toString().equals(""))
        retString += "Existing Patient Chart(s): " + sbExisting.toString();
      retString += "</td></tr><tr><td>";
      if (!sbNonExisting.toString().equals(""))
        retString += "Create A New Patient Charts: " + sbNonExisting.toString();
      retString += "</td></tr></table>";
      return retString.replace("|  |", " | ");

    } catch (Exception ex) {
      ex.printStackTrace();
      return "";
    }
  }