/**
   * @see
   *     org.openmrs.module.kenyaemr.calculation.library.hiv.MissedAppointmentsOrDefaultedCalculation#evaluate(java.util.Collection,
   *     java.util.Map, org.openmrs.calculation.patient.PatientCalculationContext)
   * @verifies determine whether patients have a Missed appointments or defaulted
   */
  @Test
  public void evaluate_shouldDetermineWhetherPatientsWhoMissedAppointmentsOrDefaulted()
      throws Exception {

    // Get HIV Program
    Program hivProgram = MetadataUtils.getProgram(Metadata.HIV_PROGRAM);

    // Enroll patients #6, #7, #8 in the HIV Program
    PatientService ps = Context.getPatientService();
    for (int i = 6; i <= 8; ++i) {
      TestUtils.enrollInProgram(ps.getPatient(i), hivProgram, TestUtils.date(2011, 1, 1));
    }

    // Give patient #7 a return visit obs of 10 days ago
    Concept returnVisit = Context.getConceptService().getConcept(5096);
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE, -10);
    TestUtils.saveObs(
        Context.getPatientService().getPatient(7),
        returnVisit,
        calendar.getTime(),
        calendar.getTime());

    // Give patient #8 a return visit obs of 10 days in the future
    calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE, 10);
    TestUtils.saveObs(
        Context.getPatientService().getPatient(8),
        returnVisit,
        calendar.getTime(),
        calendar.getTime());

    Context.flushSession();

    List<Integer> ptIds = Arrays.asList(6, 7, 8, 9);

    CalculationResultMap resultMap =
        new MissedAppointmentsOrDefaultedCalculation()
            .evaluate(
                ptIds,
                null,
                Context.getService(PatientCalculationService.class).createCalculationContext());
    Assert.assertFalse(
        (Boolean) resultMap.get(6).getValue()); // patient in HIV program but no return visit obs
    Assert.assertTrue((Boolean) resultMap.get(7).getValue()); // patient has missed visit
    Assert.assertFalse(
        (Boolean) resultMap.get(8).getValue()); // patient has future return visit date
    Assert.assertFalse((Boolean) resultMap.get(9).getValue()); // patient not in HIV Program
  }
  @Test
  public void evaluate_shouldReturnTrueForAllAlivePatients() {

    // Mark patient #8 as deceased on 1st Jan 2012
    TestUtils.getPatient(8).setDead(true);
    TestUtils.getPatient(8).setDeathDate(TestUtils.date(2012, 1, 1));

    List<Integer> ptIds = Arrays.asList(2, 6, 7, 8);
    CalculationResultMap resultMap =
        Context.getService(PatientCalculationService.class)
            .evaluate(ptIds, new EligibleForTbProgramCalculation());
    Assert.assertTrue((Boolean) resultMap.get(2).getValue());
    Assert.assertTrue((Boolean) resultMap.get(6).getValue());
    Assert.assertTrue((Boolean) resultMap.get(7).getValue());
    Assert.assertFalse((Boolean) resultMap.get(8).getValue()); // Deceased
  }
  @Test
  public void test() throws Exception {
    ReportDefinition rd = builder.build(report);

    // Run report on all patients for June 2012
    EvaluationContext context =
        ReportingTestUtils.reportingContext(
            Arrays.asList(2, 6, 7, 8, 999),
            TestUtils.date(2012, 6, 1),
            TestUtils.date(2012, 6, 30));

    ReportData data = Context.getService(ReportDefinitionService.class).evaluate(rd, context);

    // ReportingTestUtils.printReport(data);

    Assert.assertThat(data.getDataSets().size(), is(1));

    // Check that report definition can be serialized/de-serialized
    Context.getService(ReportDefinitionService.class).saveDefinition(rd);
    Context.getService(ReportDefinitionService.class).getDefinition(rd.getId());
  }
  @Test
  public void evaluate_shouldReturnHivPatientsNotScreenedForTb() throws Exception {

    // Get HIV Program and TB screening encounter type
    Program hivProgram = MetadataUtils.getProgram(Metadata.HIV_PROGRAM);
    EncounterType screeningEncType =
        MetadataUtils.getEncounterType(Metadata.TB_SCREENING_ENCOUNTER_TYPE);

    // Enroll patients #6 and #7
    PatientService ps = Context.getPatientService();
    TestUtils.enrollInProgram(ps.getPatient(6), hivProgram, TestUtils.date(2011, 1, 1));
    TestUtils.enrollInProgram(ps.getPatient(7), hivProgram, TestUtils.date(2011, 1, 1));

    // Screen patient #6 for TB a year later
    TestUtils.saveEncounter(ps.getPatient(6), screeningEncType, TestUtils.date(2012, 1, 1));

    Context.flushSession();

    List<Integer> cohort = Arrays.asList(6, 7, 8);
    CalculationResultMap resultMap =
        Context.getService(PatientCalculationService.class)
            .evaluate(cohort, new NeverScreenedForTbCalculation());
    Assert.assertFalse((Boolean) resultMap.get(6).getValue());
    Assert.assertTrue((Boolean) resultMap.get(7).getValue());
    Assert.assertNull(resultMap.get(8)); // not in HIV program
  }
  /**
   * @see VisitsOnDayCalculation#evaluate(java.util.Collection, java.util.Map,
   *     org.openmrs.calculation.patient.PatientCalculationContext)
   */
  @Test
  public void evaluate_shouldFetchAllPatientVisitsOnDate() throws Exception {
    List<Integer> ptIds = Arrays.asList(7, 8);
    Map<String, Object> paramValues = new HashMap<String, Object>();
    paramValues.put("date", TestUtils.date(2012, 1, 1));

    CalculationResultMap resultMap =
        new VisitsOnDayCalculation()
            .evaluate(
                ptIds,
                paramValues,
                Context.getService(PatientCalculationService.class).createCalculationContext());

    Assert.assertThat(((ListResult) resultMap.get(7)).getValues().size(), is(2)); // Has two visit
    Assert.assertThat(resultMap.get(8).isEmpty(), is(true)); // No visits on that day
  }
  /** @see EmrVisitAssignmentHandler#checkLocations(org.openmrs.Visit, org.openmrs.Encounter) */
  @Test
  public void checkLocations() {
    Patient patient = TestUtils.getPatient(7);
    Form moh257 = MetadataUtils.getForm(HivMetadata._Form.MOH_257_VISIT_SUMMARY);
    VisitType outpatient = MetadataUtils.getVisitType(CommonMetadata._VisitType.OUTPATIENT);

    // Save regular visit on Jan 1st at no specific location
    Visit visit0 = TestUtils.saveVisit(patient, outpatient, TestUtils.date(2012, 1, 1), null);

    // Save regular visit on Jan 1st at location #2
    Visit visit1 = TestUtils.saveVisit(patient, outpatient, TestUtils.date(2012, 1, 1), null);
    visit1.setLocation(Context.getLocationService().getLocation(1));

    // Save regular visit on Jan 1st at location #2
    Visit visit2 = TestUtils.saveVisit(patient, outpatient, TestUtils.date(2012, 1, 1), null);
    visit2.setLocation(Context.getLocationService().getLocation(2));

    // Save MOH257 for that day (will default to location #1)
    Encounter encounter = TestUtils.saveEncounter(patient, moh257, TestUtils.date(2012, 1, 1));

    Assert.assertThat(EmrVisitAssignmentHandler.checkLocations(visit0, encounter), is(true));
    Assert.assertThat(EmrVisitAssignmentHandler.checkLocations(visit1, encounter), is(true));
    Assert.assertThat(EmrVisitAssignmentHandler.checkLocations(visit2, encounter), is(false));
  }
  /**
   * @see EligibleForArtTriggerCalculation#evaluate(java.util.Collection, java.util.Map,
   *     org.openmrs.calculation.patient.PatientCalculationContext)
   * @verifies calculate the obs which triggered a patient to become eligible for ART
   * @verifies return null for patients who have never been eligible for ART
   */
  @Test
  public void evaluate_shouldCalculateEligibilityTrigger() throws Exception {

    PatientService ps = Context.getPatientService();

    // Confirm patient #6 HIV+ when they're 1 year old and give them very low CD4 soon after
    TestUtils.saveObs(
        ps.getPatient(6),
        Dictionary.getConcept(Dictionary.DATE_OF_HIV_DIAGNOSIS),
        TestUtils.date(2008, 05, 27),
        TestUtils.date(2010, 1, 1));
    TestUtils.saveObs(
        ps.getPatient(6),
        Dictionary.getConcept(Dictionary.CD4_COUNT),
        300.0,
        TestUtils.date(2009, 1, 1));

    // Give patient #7 low CD4 when they're 3 years old and very low CD4 after
    TestUtils.saveObs(
        ps.getPatient(7),
        Dictionary.getConcept(Dictionary.CD4_COUNT),
        900.0,
        TestUtils.date(1979, 8, 25));
    TestUtils.saveObs(
        ps.getPatient(7),
        Dictionary.getConcept(Dictionary.CD4_COUNT),
        300.0,
        TestUtils.date(2009, 1, 1));

    // Give patient #8 WHO stage of 3
    TestUtils.saveObs(
        ps.getPatient(8),
        Dictionary.getConcept(Dictionary.CURRENT_WHO_STAGE),
        Dictionary.getConcept(Dictionary.WHO_STAGE_3_PEDS),
        TestUtils.date(2009, 1, 1));

    Context.flushSession();

    List<Integer> cohort = Arrays.asList(6, 7, 8, 999);

    CalculationResultMap resultMap =
        new EligibleForArtTriggerCalculation()
            .evaluate(
                cohort,
                null,
                Context.getService(PatientCalculationService.class).createCalculationContext());

    Obs patient6Trigger = (Obs) resultMap.get(6).getValue(); // Eligible through HIV confirmation
    Assert.assertEquals(Dictionary.DATE_OF_HIV_DIAGNOSIS, patient6Trigger.getConcept().getUuid());
    Assert.assertEquals(TestUtils.date(2008, 05, 27), patient6Trigger.getValueDate());

    Obs patient7Trigger = (Obs) resultMap.get(7).getValue(); // Eligible through CD4 count
    Assert.assertEquals(Dictionary.CD4_COUNT, patient7Trigger.getConcept().getUuid());
    Assert.assertEquals(TestUtils.date(1979, 8, 25), patient7Trigger.getObsDatetime());

    Obs patient8Trigger = (Obs) resultMap.get(8).getValue(); // Eligible through WHO stage
    Assert.assertEquals(Dictionary.CURRENT_WHO_STAGE, patient8Trigger.getConcept().getUuid());
    Assert.assertEquals(TestUtils.date(2009, 1, 1), patient8Trigger.getObsDatetime());

    Assert.assertNull(resultMap.get(999)); // Was never eligible for ART
  }
  /** @see Moh731CohortLibrary#revisitsArt() */
  @Test
  public void revisitsArt() throws Exception {
    EncounterType hivConsult =
        MetadataUtils.getEncounterType(HivMetadata._EncounterType.HIV_CONSULTATION);
    Concept stavudine = Context.getConceptService().getConcept(84309);

    // Start patient #6 this month and give them a visit in the reporting period + 2 months
    TestUtils.saveDrugOrder(TestUtils.getPatient(6), stavudine, TestUtils.date(2012, 6, 10), null);
    TestUtils.saveEncounter(TestUtils.getPatient(6), hivConsult, TestUtils.date(2012, 6, 20));

    // Start patient #7 in previous month and give them a visit in the reporting period + 2 months
    TestUtils.saveDrugOrder(TestUtils.getPatient(7), stavudine, TestUtils.date(2012, 5, 10), null);
    TestUtils.saveEncounter(TestUtils.getPatient(7), hivConsult, TestUtils.date(2012, 6, 20));

    // Start patient #8 and give them visit outside of reporting period + 2 month window
    TestUtils.saveDrugOrder(TestUtils.getPatient(8), stavudine, TestUtils.date(2012, 1, 10), null);
    TestUtils.saveEncounter(TestUtils.getPatient(8), hivConsult, TestUtils.date(2012, 1, 20));

    CohortDefinition cd = moh731Cohorts.revisitsArt();
    context.addParameterValue("fromDate", PERIOD_START);
    context.addParameterValue("toDate", PERIOD_END);
    EvaluatedCohort evaluated =
        Context.getService(CohortDefinitionService.class).evaluate(cd, context);
    ReportingTestUtils.assertCohortEquals(Arrays.asList(7), evaluated);
  }
  /** @see Moh731CohortLibrary#currentlyInCare() */
  @Test
  public void currentlyInCare() throws Exception {
    EncounterType triage = MetadataUtils.getEncounterType(CommonMetadata._EncounterType.TRIAGE);
    EncounterType hivConsult =
        MetadataUtils.getEncounterType(HivMetadata._EncounterType.HIV_CONSULTATION);

    // Give patient #2 irrelevant encounter during 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(2), triage, TestUtils.date(2012, 6, 15));

    // Give patient #6 relevant encounter before and after 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(6), hivConsult, TestUtils.date(2012, 3, 31));
    TestUtils.saveEncounter(TestUtils.getPatient(6), hivConsult, TestUtils.date(2012, 7, 1));

    // Give patient #7 relevant encounter at start of 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(7), hivConsult, TestUtils.date(2012, 4, 1));

    // Give patient #8 relevant encounter at end of 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(8), hivConsult, TestUtils.date(2012, 6, 30));

    CohortDefinition cd = moh731Cohorts.currentlyInCare();
    context.addParameterValue("onDate", PERIOD_END);
    EvaluatedCohort evaluated =
        Context.getService(CohortDefinitionService.class).evaluate(cd, context);
    ReportingTestUtils.assertCohortEquals(Arrays.asList(7, 8), evaluated);
  }
/** Tests for {@link Moh731CohortLibrary} */
public class Moh731CohortLibraryTest extends BaseModuleContextSensitiveTest {

  @Autowired private CommonMetadata commonMetadata;

  @Autowired private HivMetadata hivMetadata;

  @Autowired private Moh731CohortLibrary moh731Cohorts;

  private EvaluationContext context;

  private static final Date PERIOD_START = TestUtils.date(2012, 6, 1),
      PERIOD_END = TestUtils.date(2012, 6, 30);

  /** Setup each test */
  @Before
  public void setup() throws Exception {
    executeDataSet("dataset/test-concepts.xml");

    commonMetadata.install();
    hivMetadata.install();

    List<Integer> cohort = Arrays.asList(2, 6, 7, 8, 999);
    context = ReportingTestUtils.reportingContext(cohort, PERIOD_START, PERIOD_END);
  }

  /** @see Moh731CohortLibrary#currentlyInCare() */
  @Test
  public void currentlyInCare() throws Exception {
    EncounterType triage = MetadataUtils.getEncounterType(CommonMetadata._EncounterType.TRIAGE);
    EncounterType hivConsult =
        MetadataUtils.getEncounterType(HivMetadata._EncounterType.HIV_CONSULTATION);

    // Give patient #2 irrelevant encounter during 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(2), triage, TestUtils.date(2012, 6, 15));

    // Give patient #6 relevant encounter before and after 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(6), hivConsult, TestUtils.date(2012, 3, 31));
    TestUtils.saveEncounter(TestUtils.getPatient(6), hivConsult, TestUtils.date(2012, 7, 1));

    // Give patient #7 relevant encounter at start of 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(7), hivConsult, TestUtils.date(2012, 4, 1));

    // Give patient #8 relevant encounter at end of 90 day window
    TestUtils.saveEncounter(TestUtils.getPatient(8), hivConsult, TestUtils.date(2012, 6, 30));

    CohortDefinition cd = moh731Cohorts.currentlyInCare();
    context.addParameterValue("onDate", PERIOD_END);
    EvaluatedCohort evaluated =
        Context.getService(CohortDefinitionService.class).evaluate(cd, context);
    ReportingTestUtils.assertCohortEquals(Arrays.asList(7, 8), evaluated);
  }

  /** @see Moh731CohortLibrary#revisitsArt() */
  @Test
  public void revisitsArt() throws Exception {
    EncounterType hivConsult =
        MetadataUtils.getEncounterType(HivMetadata._EncounterType.HIV_CONSULTATION);
    Concept stavudine = Context.getConceptService().getConcept(84309);

    // Start patient #6 this month and give them a visit in the reporting period + 2 months
    TestUtils.saveDrugOrder(TestUtils.getPatient(6), stavudine, TestUtils.date(2012, 6, 10), null);
    TestUtils.saveEncounter(TestUtils.getPatient(6), hivConsult, TestUtils.date(2012, 6, 20));

    // Start patient #7 in previous month and give them a visit in the reporting period + 2 months
    TestUtils.saveDrugOrder(TestUtils.getPatient(7), stavudine, TestUtils.date(2012, 5, 10), null);
    TestUtils.saveEncounter(TestUtils.getPatient(7), hivConsult, TestUtils.date(2012, 6, 20));

    // Start patient #8 and give them visit outside of reporting period + 2 month window
    TestUtils.saveDrugOrder(TestUtils.getPatient(8), stavudine, TestUtils.date(2012, 1, 10), null);
    TestUtils.saveEncounter(TestUtils.getPatient(8), hivConsult, TestUtils.date(2012, 1, 20));

    CohortDefinition cd = moh731Cohorts.revisitsArt();
    context.addParameterValue("fromDate", PERIOD_START);
    context.addParameterValue("toDate", PERIOD_END);
    EvaluatedCohort evaluated =
        Context.getService(CohortDefinitionService.class).evaluate(cd, context);
    ReportingTestUtils.assertCohortEquals(Arrays.asList(7), evaluated);
  }
}
  /** Setup each test */
  @Before
  public void setup() throws Exception {
    commonMetadata.install();

    VisitType outpatient = MetadataUtils.getVisitType(CommonMetadata._VisitType.OUTPATIENT);

    // Patient #7 has two visits on 1-Jan-2012 (from 9am to 10am and another from 11am to 12pm)
    TestUtils.saveVisit(
        TestUtils.getPatient(7),
        outpatient,
        TestUtils.date(2012, 1, 1, 9, 0, 0),
        TestUtils.date(2012, 1, 1, 10, 0, 0));
    TestUtils.saveVisit(
        TestUtils.getPatient(7),
        outpatient,
        TestUtils.date(2012, 1, 1, 11, 0, 0),
        TestUtils.date(2012, 1, 1, 12, 0, 0));

    // Patient #8 has visit on 2-Jan-2012
    TestUtils.saveVisit(
        TestUtils.getPatient(8),
        outpatient,
        TestUtils.date(2012, 1, 2, 9, 0, 0),
        TestUtils.date(2012, 1, 2, 10, 0, 0));
  }