@Test
 public void testHasJobPositionHistory() {
   Project obj = dod.getNewTransientProject(4);
   assertNotNull("Data on demand for 'Project' failed to initialize correctly", obj);
   obj.persist();
   assertFalse(obj.hasJobPositionHistory());
   JobPosition jp = jobPositionDataOnDemand.getNewTransientJobPosition(7);
   assertNotNull("Data on demand for 'JobPosition' failed to initialize correctly", jp);
   jp.setProject(obj);
   obj.getJobPositions().add(jp);
   obj.persist();
   jp.persist();
   JobPositionHistoryEntry he =
       jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(7);
   assertNotNull(
       "Data on demand for 'JobPositionHistoryEntry' failed to initialize correctly", he);
   he.setJobPosition(jp);
   he.persist();
   he.flush();
   Project fetchedObj = Project.findProject(obj.getId());
   assertTrue(fetchedObj.hasJobPositionHistory());
 }
  @Test
  public void testRemoveWhenReferenced() {
    Project obj = dod.getNewTransientProject(5);
    assertNotNull("Data on demand for 'Project' failed to initialize correctly", obj);
    obj.setDateFrom(DateTrimmer.addDays(DateTrimmer.today(), -10));
    obj.setDateTo(DateTrimmer.addDays(DateTrimmer.today(), -5));
    Set<Site> sites = new HashSet<Site>();
    for (int i = 0; i < 5; ++i) {
      while (!sites.add(siteDataOnDemand.getRandomSite())) ;
    }
    obj.getSites().addAll(sites);
    for (Site site : sites) {
      site.getProjects().add(obj);
      site.persist();
    }
    obj.persist();
    Long id = obj.getId();
    obj.remove();
    assertNull("Project failed to remove", Project.findProject(id));
    for (Site site : sites) {
      assertFalse("Project not removed", Site.findSite(site.getId()).getProjects().contains(obj));
    }

    obj = dod.getRandomProject();
    obj.setDateFrom(DateTrimmer.addDays(DateTrimmer.today(), -10));
    obj.setDateTo(DateTrimmer.addDays(DateTrimmer.today(), -5));
    JobPositionHistoryEntry jphe =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(4);
    jphe.getJobPosition().setProject(obj);
    obj.getJobPositions().add(jphe.getJobPosition());
    jphe.getJobPosition().persist();
    jphe.persist();
    obj.persist();
    exception.expect(IllegalStateException.class);
    exception.expectMessage("error_description_project_to_remove_has_history");
    obj.remove();
  }
  @Test
  public void testTerminateWhenEmployeeMismatch() {
    Project obj = dod.getNewTransientProject(4);
    assertNotNull("Data on demand for 'Project' failed to initialize correctly", obj);
    obj.persist();

    Employee emp1 = employeeDataOnDemand.getNewTransientEmployee(5);
    assertNotNull("Data on demand for 'Employee' failed to initialize correctly", emp1);
    emp1.persist();
    Employee emp2 = employeeDataOnDemand.getNewTransientEmployee(6);
    emp2.persist();
    Employee emp3 = employeeDataOnDemand.getNewTransientEmployee(7);
    emp3.persist();

    List<Employee> employeesToDismiss = new ArrayList<Employee>();
    employeesToDismiss.add(emp1);
    employeesToDismiss.add(emp2);
    List<Employee> employeesToLayOff = new ArrayList<Employee>();
    employeesToLayOff.add(emp3);

    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("error_description_project_members_mismatch");
    obj.terminate(DateTrimmer.today(), employeesToDismiss, employeesToLayOff, 0.5, 0.5);
  }
  @Test
  public void testUpdateAndRefreshJobPositions() {
    Project obj = dod.getNewTransientProject(4);
    assertNotNull("Data on demand for 'Project' failed to initialize correctly", obj);
    JobPosition jp1 = jobPositionDataOnDemand.getNewTransientJobPosition(8);
    assertNotNull("Data on demand for 'JobPosition' failed to initialize correctly", jp1);
    JobPosition jp2 = jobPositionDataOnDemand.getNewTransientJobPosition(9);
    JobPosition jp3 = jobPositionDataOnDemand.getNewTransientJobPosition(10);

    Date projDateFrom = DateTrimmer.addDays(DateTrimmer.today(), -20);
    Date projDateTo = DateTrimmer.addDays(DateTrimmer.today(), 20);

    obj.setDateFrom(projDateFrom);
    obj.setDateTo(projDateTo);
    obj.persist();

    jp1.setProject(obj);
    obj.getJobPositions().add(jp1);
    jp2.setProject(obj);
    obj.getJobPositions().add(jp2);
    jp3.setProject(obj);
    obj.getJobPositions().add(jp3);
    obj.persist();

    Date eheDateTo1 = DateTrimmer.addDays(projDateTo, -5);
    Date eheDateTo2 = DateTrimmer.addDays(projDateTo, -10);
    Date eheDateTo3 = DateTrimmer.addDays(projDateTo, 15);

    Employee emp1 = employeeDataOnDemand.getNewTransientEmployee(5);
    assertNotNull("Data on demand for 'Employee' failed to initialize correctly", emp1);
    emp1.persist();
    Employee emp2 = employeeDataOnDemand.getNewTransientEmployee(6);
    emp2.persist();
    Employee emp3 = employeeDataOnDemand.getNewTransientEmployee(7);
    emp3.persist();

    EmploymentHistoryEntry ehe1 =
        employmentHistoryEntryDataOnDemand.getNewTransientEmploymentHistoryEntry(5);
    assertNotNull(
        "Data on demand for 'EmploymentHistoryEntry' failed to initialize correctly", ehe1);
    EmploymentHistoryEntry ehe2 =
        employmentHistoryEntryDataOnDemand.getNewTransientEmploymentHistoryEntry(6);
    EmploymentHistoryEntry ehe3 =
        employmentHistoryEntryDataOnDemand.getNewTransientEmploymentHistoryEntry(7);

    prepareHistoryEntry(eheDateTo1, DateTrimmer.addDays(eheDateTo1, -50), emp1, ehe1);
    prepareHistoryEntry(eheDateTo2, DateTrimmer.addDays(eheDateTo2, -50), emp2, ehe2);
    prepareHistoryEntry(eheDateTo3, DateTrimmer.addDays(eheDateTo3, -50), emp3, ehe3);

    JobPositionHistoryEntry jphe1 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(5);
    assertNotNull(
        "Data on demand for 'JobPositionHistoryEntry' failed to initialize correctly", jphe1);
    jphe1.setJobPosition(jp1);
    jphe1.persist();
    JobPositionHistoryEntry jphe2 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(6);
    jphe2.setJobPosition(jp2);
    jphe2.persist();
    JobPositionHistoryEntry jphe3 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(7);
    jphe3.setJobPosition(jp3);
    jphe3.persist();

    prepareHistoryEntry(projDateTo, DateTrimmer.addDays(projDateTo, -50), emp1, jphe1);
    prepareHistoryEntry(projDateTo, DateTrimmer.addDays(projDateTo, -50), emp2, jphe2);
    prepareHistoryEntry(projDateTo, DateTrimmer.addDays(projDateTo, -50), emp3, jphe3);

    obj = Project.findProject(obj.getId());
    Date newProjEndDate = DateTrimmer.addDays(projDateTo, -7);
    obj.setDateTo(newProjEndDate);
    obj.setDescription("myDesc1");
    obj.setName("myName1");
    obj.setReferenceLink("http://www.mylink1.com/");
    obj.updateAndRefreshJobPositions();
    obj = Project.findProject(obj.getId());
    jphe1 = JobPositionHistoryEntry.findJobPositionHistoryEntry(jphe1.getId());
    assertEquals(
        "Wrong date to assigned to job position history", jphe1.getDateTo(), obj.getDateTo());
    jphe2 = JobPositionHistoryEntry.findJobPositionHistoryEntry(jphe2.getId());
    assertEquals(
        "Wrong date to assigned to job position history", jphe2.getDateTo(), ehe2.getDateTo());
    jphe3 = JobPositionHistoryEntry.findJobPositionHistoryEntry(jphe3.getId());
    assertEquals(
        "Wrong date to assigned to job position history", jphe3.getDateTo(), obj.getDateTo());

    assertEquals(obj.getName(), "myName1");
    assertEquals(obj.getDescription(), "myDesc1");
    assertEquals(obj.getReferenceLink(), "http://www.mylink1.com/");
  }
  @Test
  public void testFindMembersAtDate() {
    Project obj = dod.getNewTransientProject(4);
    assertNotNull("Data on demand for 'Project' failed to initialize correctly", obj);
    JobPosition jp1 = jobPositionDataOnDemand.getNewTransientJobPosition(8);
    assertNotNull("Data on demand for 'JobPosition' failed to initialize correctly", jp1);
    JobPosition jp2 = jobPositionDataOnDemand.getNewTransientJobPosition(9);
    JobPosition jp3 = jobPositionDataOnDemand.getNewTransientJobPosition(10);

    Date projDateFrom = DateTrimmer.addDays(DateTrimmer.today(), -20);
    Date projDateTo = DateTrimmer.addDays(DateTrimmer.today(), 20);

    obj.setDateFrom(projDateFrom);
    obj.setDateTo(projDateTo);
    obj.persist();

    jp1.setProject(obj);
    jp1.persist();
    jp2.setProject(obj);
    jp2.persist();
    jp3.setProject(obj);
    jp3.persist();

    Date eheDateTo1 = DateTrimmer.addDays(projDateTo, -5);
    Date eheDateTo2 = DateTrimmer.addDays(projDateTo, -10);
    Date eheDateTo3 = DateTrimmer.addDays(projDateTo, -15);

    Employee emp1 = employeeDataOnDemand.getNewTransientEmployee(5);
    assertNotNull("Data on demand for 'Employee' failed to initialize correctly", emp1);
    emp1.persist();
    Employee emp2 = employeeDataOnDemand.getNewTransientEmployee(6);
    emp2.persist();
    Employee emp3 = employeeDataOnDemand.getNewTransientEmployee(7);
    emp3.persist();

    JobPositionHistoryEntry jphe1 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(5);
    assertNotNull(
        "Data on demand for 'JobPositionHistoryEntry' failed to initialize correctly", jphe1);
    jphe1.setJobPosition(jp1);
    JobPositionHistoryEntry jphe2 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(6);
    jphe1.setJobPosition(jp2);
    JobPositionHistoryEntry jphe3 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(7);
    jphe1.setJobPosition(jp3);

    prepareHistoryEntry(eheDateTo1, DateTrimmer.addDays(eheDateTo1, -20), emp1, jphe1);
    prepareHistoryEntry(eheDateTo2, DateTrimmer.addDays(eheDateTo2, -4), emp2, jphe2);
    prepareHistoryEntry(eheDateTo3, DateTrimmer.addDays(eheDateTo3, -4), emp3, jphe3);

    List<Employee> fetchedEmps = obj.findMembersAtDate(DateTrimmer.addDays(eheDateTo3, -5));
    assertEquals("Wrong number of employees", fetchedEmps.size(), 1);
    assertTrue("Wrong employees", fetchedEmps.contains(emp1));

    fetchedEmps = obj.findMembersAtDate(DateTrimmer.addDays(eheDateTo3, -4));
    assertEquals("Wrong number of employees", fetchedEmps.size(), 2);
    assertTrue("Wrong employees", fetchedEmps.contains(emp1));
    assertTrue("Wrong employees", fetchedEmps.contains(emp3));

    fetchedEmps = obj.findMembersAtDate(eheDateTo3);
    assertEquals("Wrong number of employees", fetchedEmps.size(), 2);
    assertTrue("Wrong employees", fetchedEmps.contains(emp1));
    assertTrue("Wrong employees", fetchedEmps.contains(emp3));

    fetchedEmps = obj.findMembersAtDate(DateTrimmer.addDays(eheDateTo2, -1));
    assertEquals("Wrong number of employees", fetchedEmps.size(), 2);
    assertTrue("Wrong employees", fetchedEmps.contains(emp1));
    assertTrue("Wrong employees", fetchedEmps.contains(emp2));

    fetchedEmps = obj.findMembersAtDate(DateTrimmer.addDays(eheDateTo1, 3));
    assertTrue("Wrong employees", fetchedEmps.isEmpty());

    fetchedEmps = obj.findMembersAtDate(DateTrimmer.addDays(eheDateTo1, -21));
    assertTrue("Wrong employees", fetchedEmps.isEmpty());
  }
  @Test
  public void testTerminate() {
    Project obj = dod.getNewTransientProject(4);
    assertNotNull("Data on demand for 'Project' failed to initialize correctly", obj);
    JobPosition jp1 = jobPositionDataOnDemand.getNewTransientJobPosition(8);
    assertNotNull("Data on demand for 'JobPosition' failed to initialize correctly", jp1);
    JobPosition jp2 = jobPositionDataOnDemand.getNewTransientJobPosition(9);
    JobPosition jp3 = jobPositionDataOnDemand.getNewTransientJobPosition(10);

    Date projDateFrom = DateTrimmer.addDays(DateTrimmer.today(), -20);
    Date projDateTo = DateTrimmer.addDays(DateTrimmer.today(), 1);

    obj.setDateFrom(projDateFrom);
    obj.setDateTo(projDateTo);
    obj.persist();

    jp1.setProject(obj);
    obj.getJobPositions().add(jp1);
    jp2.setProject(obj);
    obj.getJobPositions().add(jp2);
    jp3.setProject(obj);
    obj.getJobPositions().add(jp3);
    obj.persist();

    Date eheDateTo1 = DateTrimmer.addDays(projDateTo, 5);
    Date eheDateTo2 = DateTrimmer.addDays(projDateTo, 10);
    Date eheDateTo3 = DateTrimmer.addDays(projDateTo, 15);

    Employee emp1 = employeeDataOnDemand.getNewTransientEmployee(5);
    assertNotNull("Data on demand for 'Employee' failed to initialize correctly", emp1);
    emp1.persist();
    Employee emp2 = employeeDataOnDemand.getNewTransientEmployee(6);
    emp2.persist();
    Employee emp3 = employeeDataOnDemand.getNewTransientEmployee(7);
    emp3.persist();

    EmploymentHistoryEntry ehe1 =
        employmentHistoryEntryDataOnDemand.getNewTransientEmploymentHistoryEntry(5);
    assertNotNull(
        "Data on demand for 'EmploymentHistoryEntry' failed to initialize correctly", ehe1);
    EmploymentHistoryEntry ehe2 =
        employmentHistoryEntryDataOnDemand.getNewTransientEmploymentHistoryEntry(6);
    EmploymentHistoryEntry ehe3 =
        employmentHistoryEntryDataOnDemand.getNewTransientEmploymentHistoryEntry(7);

    prepareHistoryEntry(eheDateTo1, DateTrimmer.addDays(eheDateTo1, -50), emp1, ehe1);
    prepareHistoryEntry(eheDateTo2, DateTrimmer.addDays(eheDateTo2, -50), emp2, ehe2);
    prepareHistoryEntry(eheDateTo3, DateTrimmer.addDays(eheDateTo3, -50), emp3, ehe3);

    JobPositionHistoryEntry jphe1 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(5);
    assertNotNull(
        "Data on demand for 'JobPositionHistoryEntry' failed to initialize correctly", jphe1);
    jphe1.setJobPosition(jp1);
    jphe1.persist();
    JobPositionHistoryEntry jphe2 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(6);
    jphe2.setJobPosition(jp2);
    jphe2.persist();
    JobPositionHistoryEntry jphe3 =
        jobPositionHistoryEntryDataOnDemand.getNewTransientJobPositionHistoryEntry(7);
    jphe3.setJobPosition(jp3);
    jphe3.persist();

    prepareHistoryEntry(projDateTo, DateTrimmer.addDays(projDateTo, -50), emp1, jphe1);
    prepareHistoryEntry(projDateTo, DateTrimmer.addDays(projDateTo, -50), emp2, jphe2);
    prepareHistoryEntry(projDateTo, DateTrimmer.addDays(projDateTo, -50), emp3, jphe3);

    List<Employee> employeesToDismiss = new ArrayList<Employee>();
    employeesToDismiss.add(emp1);
    employeesToDismiss.add(emp2);
    List<Employee> employeesToLayOff = new ArrayList<Employee>();
    employeesToLayOff.add(emp3);
    double wagePerCent = 0.75;
    double workingHoursPerCent = 0.75;
    obj.terminate(
        DateTrimmer.addDays(projDateTo, -3),
        employeesToDismiss,
        employeesToLayOff,
        wagePerCent,
        workingHoursPerCent);
    for (Employee employee : employeesToDismiss) {
      assertFalse("Dismissal request ignored", employee.isHired());
    }
    for (Employee employee : employeesToLayOff) {
      assertFalse(
          "Lay off request ignored",
          LayOffHistoryEntry.findActiveLayOffHistoryEntryByEmployee(employee)
              .getResultList()
              .isEmpty());
    }
    assertEquals("State change ignored", obj.getState(), ProjectState.TERMINATED);
    assertEquals("Date to change ignored", obj.getDateTo(), DateTrimmer.addDays(projDateTo, -4));

    // abnormal condition - terminate a terminated project
    exception.expect(IllegalStateException.class);
    exception.expectMessage("error_description_project_already_terminated");
    obj.terminate(
        projDateTo,
        Collections.<Employee>emptyList(),
        Collections.<Employee>emptyList(),
        wagePerCent,
        workingHoursPerCent);
  }