package gov.va.vinci.dart.biz;

import java.util.List;

import gov.va.vinci.dart.common.SingletonShim;
import gov.va.vinci.dart.common.exception.ValidationException;
import gov.va.vinci.dart.common.test.BusinessIntegrationTest;
import gov.va.vinci.dart.service.DartObjectFactory;
import gov.va.vinci.dart.wf2.WfOperationalRequest;
import gov.va.vinci.dart.wf2.WorkflowResolver;

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestOperationalRequest extends BusinessIntegrationTest {
	@BeforeTest
	public void setup() {
		SingletonShim.getBean(DartObjectFactory.class);
	}

	@Test
	public void testOne() throws Exception {
		
		OperationalRequest req = (OperationalRequest)OperationalRequest.findById(-1);
		Assert.assertNull(req);
	}
	
	@Test
	public void testTwo() throws Exception {
		
		List<OperationalRequest> reqList = OperationalRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		
		OperationalRequest req = reqList.get(0);
		Assert.assertNotNull(req);
		
		Person requestor = req.getRequestor();
		Assert.assertNotNull(requestor);
		Assert.assertTrue(requestor.getId() > 0);

		List<OperationalRequest> reqlist = OperationalRequest.listByName(requestor.getId(), "e");
		Assert.assertNotNull(reqlist);
	}

	@Test
	public void testThree() throws Exception {

		Person pers = Person.findById(1006);
		List<OperationalStudy> activityList = OperationalStudy.listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertNotNull(req.getDataSources());
		
//		Assert.assertNotNull(req.getReviews());
		Assert.assertNotNull(req.getAllReviews());
		
		Assert.assertNotNull(req.getParticipants());
		Assert.assertNotNull(req.getDocuments());
		Assert.assertNotNull(req.getEvents());
		Assert.assertNotNull(req.getNarratives());
		Assert.assertNotNull(req.getSites());
		
		OperationalRequest req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2, req);
		
		try {
			req.modify(null, "office", "justification", "DNS");
			Assert.fail("Expected ValidationException");
		}catch (ValidationException e) {}
		
		// VINCI-58
		req.modify("name one", "office", TestResearchStudy.longString(3000), "DNS"); 
	}

	@Test
	public void testFour() throws Exception {

		List<OperationalRequest> reqList = OperationalRequest.listAll();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
	}

	@Test
	public void testFive() throws Exception {

		Person pers = Person.findById(1006);
		List<OperationalStudy> activityList = OperationalStudy.listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		List<OperationalRequest> reqList = OperationalRequest.listByActivityId(activity.getId());
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		Assert.assertTrue(reqList.contains(req));
	}

	@Test
	public void testSix() throws Exception {

		Person pers = Person.findById(1006);
		List<OperationalStudy> activityList = OperationalStudy.listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		List<OperationalRequest> reqList = OperationalRequest.listByRequestor(pers.getId());
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		Assert.assertTrue(reqList.contains(req));
	}

	@Test
	public void testSeven() throws Exception {

		Person pers = Person.findById(1006);
		List<OperationalStudy> activityList = OperationalStudy.listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		try {
			OperationalRequest.listRecentByRequestor(pers.getId(), 100);
			Assert.fail("Expected ValidationException");
		} catch (ValidationException e) {}
		
		List<OperationalRequest> reqList = OperationalRequest.listRecentByRequestor(pers.getId(), 10);
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.size() > 0);
		Assert.assertTrue(reqList.contains(req));
	}

	@Test
	public void testEight() throws Exception {

		Person pers = Person.findById(1006);
		List<OperationalStudy> activityList = OperationalStudy.listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
//		Assert.assertNotNull(req.getReviews());
//		Assert.assertEquals(req.getReviews().size(), 0);
		Assert.assertNotNull(req.getAllReviews());
		Assert.assertEquals(req.getAllReviews().size(), 0);
		
		OperationalRequest amendment = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		req.submit(pers.getName());
		req.setWorkflowState(WfOperationalRequest.OPS_FINAL_REVIEW_STATE);  // required to mimic the operational request workflow

		req.approve(null, pers.getName());
		
		// now how do you propose to test when it has an amendment?
	}

	@Test
	public void testNine() throws Exception {

		Person pers = Person.findById(1006);
		List<OperationalStudy> activityList = OperationalStudy.listAll();
		Assert.assertNotNull(activityList);
		Assert.assertTrue(activityList.size() > 0);
		
		OperationalStudy activity = activityList.get(0);
		Assert.assertNotNull(activity);
		Assert.assertTrue(activity.getId() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		
		// need to submit that request to guarantee there is something to see in the list
		req.submit(pers.getName()); 

		Assert.assertEquals(req.getStatus(), RequestStatus.SUBMITTED);
		
		List<RequestSummary> rsList = OperationalRequest.listAllButInitiated();
		Assert.assertNotNull(rsList);
		
		boolean foundit = false;
		for (RequestSummary rs : rsList) {
			if (rs.getRequestId() == req.getId()) {
				foundit = true;
				break;
			}
		}
		Assert.assertTrue(foundit);

		List<OperationalRequest> reqList = OperationalRequest.listAllSubmitted();
		Assert.assertNotNull(reqList);
		Assert.assertTrue(reqList.contains(req));
	}
	
	@Test
	public void testTen() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");
		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		Assert.assertFalse(req.isAmendment());
		Assert.assertEquals(req.getHeadId(), 0);
		
		OperationalRequest amendment = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		WorkflowResolver workflowResolver = DartObjectFactory.getInstance().getWorkflowResolver();
		Assert.assertTrue(workflowResolver.resolve(req) instanceof WfOperationalRequest);
		
		workflowResolver.resolve(req).initialize(null, req, "DNS");

		workflowResolver.resolve(req).submit(null, req, "DNS");
		
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

		req.approve(null, pers.getName());

		OperationalRequest amendmentReq = OperationalRequest.create("test amendment 1", pers, activity, "DNS");

		// try the amendment creation method in Request.java
		amendmentReq.createAmendment(req);

		Assert.assertFalse(req.isAmendment());

		OperationalRequest req2 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req2);

		Assert.assertNotEquals(req2, req);
		Assert.assertEquals(req2, amendmentReq);
		Assert.assertTrue(req2.isAmendment());
	}

	@Test
	public void testEleven() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		Assert.assertFalse(req.isAmendment());
		Assert.assertEquals(req.getHeadId(), 0);
		
		OperationalRequest amendment = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		WorkflowResolver workflowResolver = DartObjectFactory.getInstance().getWorkflowResolver();
		Assert.assertTrue(workflowResolver.resolve(req) instanceof WfOperationalRequest);
		
		workflowResolver.resolve(req).initialize(null, req, "DNS");

		workflowResolver.resolve(req).submit(null, req, "DNS");
		
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

//		Assert.assertNotNull(req.getReviews());
//		Assert.assertEquals(req.getReviews().size(), 0);
//		Assert.assertTrue(req.allReviewsApproved());
		Assert.assertNotNull(req.getAllReviews());
		Assert.assertEquals(req.getAllReviews().size(), 0);
		Assert.assertTrue(req.allReviewsApproved(null));

		req.approve(null, pers.getName());
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

		// try the amendment creation method in OperationalRequest.java
		OperationalRequest amendmentReq = req.createAmendment("DNS");
		Assert.assertNotNull(amendmentReq);
		workflowResolver.resolve(req).initialize(null, amendmentReq, "DNS");
		
		Assert.assertFalse(req.isAmendment());
		Assert.assertTrue(amendmentReq.isAmendment());

		OperationalRequest req2 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req2);

		Assert.assertNotEquals(req2, req);
		Assert.assertEquals(req2, amendmentReq);
		Assert.assertTrue(req2.isAmendment());
	}

	@Test
	public void testTwelve() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		
		req.modify("test","office", "justification", req.getUpdatedBy());
		
		OperationalRequest req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
				
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2.getName(), "test");

		req.modify("test", "two", "justification", req.getUpdatedBy());
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req.getProgramOffice(), "two");

		req.modify("test", "office", "three", req.getUpdatedBy());
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req.getJustification(), "three");

		req.modify("test", "office", "justification", "updated");
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req.getUpdatedBy(), "updated");

		Assert.assertFalse(req.isLocalServer());
		req.setLocalServer(true);
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertTrue(req2.isLocalServer());

		Assert.assertFalse(req.isDataMart());
		req.setDataMart(true);
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertTrue(req2.isDataMart());

		Assert.assertNull(req.getLocalServerLocation());
		req.setLocalServerLocation("two");
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2.getLocalServerLocation(), "two");

		Assert.assertNull(req.getLocalServerAddress());
		req.setLocalServerAddress("three");
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2.getLocalServerAddress(), "three");
		
		Assert.assertNull(req.getLocalServerBuilding());
		req.setLocalServerBuilding("four");
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2.getLocalServerBuilding(), "four");

		Assert.assertNull(req.getLocalServerRoomNumber());
		req.setLocalServerRoomNumber("five");
		
		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertEquals(req2.getLocalServerRoomNumber(), "five");
		
		Assert.assertNotNull(req.getDataSources());
		Assert.assertEquals(req.getDataSources().size(), 0);

		DataSource ds = DataSource.findById(1);
		Assert.assertNotNull(ds);
		Assert.assertEquals(ds.getId(), 1);
		req.getDataSources().add(ds);

		req2 = (OperationalRequest)OperationalRequest.findById(req.getId());
		Assert.assertNotNull(req2);
		Assert.assertNotNull(req2.getDataSources());
		Assert.assertTrue(req2.getDataSources().contains(ds));

		
//TODO: update to use the workflowresolver		
//		Assert.assertFalse(req.isReadyForInitialReview());
//		Assert.assertFalse(req.isInitialReviewCompleted());
//		Assert.assertFalse(req.isReadyForFinalReview());
//		Assert.assertFalse(req.isFinalReviewCompleted());
	}
	
	@Test
	public void testThirteen() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);

		DataSource ds = DataSource.findById(1005);  // an operations data source
		Assert.assertNotNull(ds);
		Assert.assertEquals(ds.getId(), 1005);
		Assert.assertNotNull(ds.getEvaluator());
		req.getDataSources().add(ds);

		// request needs a site
		req.getSites().add(pers.getLocation());

		// request needs a participant
		Participant part = Participant.create(pers, req, pers.getLocation(), true, true, true);
		Assert.assertNotNull(part);
		Assert.assertTrue(part.getId() > 0);
		
		Assert.assertNotNull(req.getDocuments());
		Assert.assertEquals(req.getDocuments().size(), 0);
		
		// call the document rule evaluator
		req.createDocuments("DNS");
		
		Assert.assertNotNull(req.getDocuments());
		Assert.assertTrue(req.getDocuments().size() > 0);
		
		List<RequestLocationDocument> rldList = RequestLocationDocument.listByRequestId(req.getId());
		Assert.assertNotNull(rldList);
		Assert.assertEquals(rldList.size(), 0);  // operational requests do not require location documents 

		List<RequestParticipantDocument> rpdList = RequestParticipantDocument.listByRequestId(req.getId());
		Assert.assertNotNull(rpdList);
		Assert.assertTrue(rpdList.size() > 0);
	}

	@Test
	public void testFourteen() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");
		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine
		
		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);

		WorkflowResolver workflowResolver = DartObjectFactory.getInstance().getWorkflowResolver();
		workflowResolver.resolve(req).initialize(null, req, "DNS");
		
		DataSource ds = DataSource.findById(1003);	//OperationalRequest Data Source (OperationalDocumentRuleEvaluator)
		Assert.assertNotNull(ds);
		Assert.assertEquals(ds.getId(), 1003);
		Assert.assertNotNull(ds.getEvaluator());
		req.getDataSources().add(ds);

		// request needs a site
		req.getSites().add(pers.getLocation());

		// request needs a participant
		Participant part = Participant.create(pers, req, pers.getLocation(), true, true, true);
		Assert.assertNotNull(part);
		Assert.assertTrue(part.getId() > 0);
		
		Assert.assertNotNull(req.getDocuments());
		Assert.assertEquals(req.getDocuments().size(), 0);
		
		// call the document rule evaluator
		req.createDocuments("DNS");
		
		Assert.assertNotNull(req.getDocuments());
		Assert.assertTrue(req.getDocuments().size() > 0);
		
//TODO: update to use the workflowresolver		
//		Assert.assertFalse(req.isReadyForInitialReview());

		workflowResolver.resolve(req).submit(null, req, "DNS");
		
		req.submit("DNS");

//TODO: update to use the workflowresolver
//		Assert.assertTrue(req.isReadyForInitialReview());
//		Assert.assertFalse(req.isInitialReviewCompleted());

		workflowResolver.resolve(req).approve(null, null, req, "DNS");  // operational request gets an initial and a final review from NDS
		
//		Assert.assertNotNull(req.getReviews());
//		Assert.assertEquals(req.getReviews().size(), 0);
//		Assert.assertTrue(req.allReviewsApproved());
		Assert.assertNotNull(req.getAllReviews());
		Assert.assertEquals(req.getAllReviews().size(), 0);
		Assert.assertTrue(req.allReviewsApproved(null));

		req.approve(null, "DNS");

		workflowResolver.resolve(req).approve(null, null, req, "DNS");

		// why doesn't the approve transition go to the final state?
	}
		
	@Test
	public void testFifteen() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		Assert.assertFalse(req.isAmendment());
		Assert.assertEquals(req.getHeadId(), 0);

		DataSource ds = DataSource.findById(1);
		Assert.assertNotNull(ds);
		Assert.assertEquals(ds.getId(), 1);
		Assert.assertNotNull(ds.getEvaluator());
		req.getDataSources().add(ds);

		Assert.assertNotNull(req.getDataSources());
		Assert.assertEquals(req.getDataSources().size(), 1);
		Assert.assertTrue(req.getDataSources().contains(ds));
		
		OperationalRequest amendment = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		WorkflowResolver workflowResolver = DartObjectFactory.getInstance().getWorkflowResolver();
		Assert.assertTrue(workflowResolver.resolve(req) instanceof WfOperationalRequest);
		
		workflowResolver.resolve(req).initialize(null, req, "DNS");

		workflowResolver.resolve(req).submit(null, req, "DNS");
		
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

//		Assert.assertNotNull(req.getReviews());
//		Assert.assertEquals(req.getReviews().size(), 0);
//		Assert.assertTrue(req.allReviewsApproved());
		Assert.assertNotNull(req.getAllReviews());
		Assert.assertEquals(req.getAllReviews().size(), 0);
		Assert.assertTrue(req.allReviewsApproved(null));

		req.approve(null, pers.getName());
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

		// create an amendment
		OperationalRequest amendmentReq = req.createAmendment("DNS");

		OperationalRequest req2 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req2);

		Assert.assertNotEquals(req2, req);
		Assert.assertEquals(req2, amendmentReq);
		Assert.assertTrue(req2.isAmendment());

		Assert.assertNotNull(req2.getDataSources());
		Assert.assertEquals(req2.getDataSources().size(), 1);
		Assert.assertTrue(req2.getDataSources().contains(ds));  // data sources are copied from the original request

		DataSource ds2 = DataSource.findById(2);
		Assert.assertNotNull(ds2);
		Assert.assertEquals(ds2.getId(), 2);
		amendmentReq.getDataSources().clear();
		amendmentReq.getDataSources().add(ds2);

		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		workflowResolver.resolve(amendmentReq).initialize(null, amendmentReq, "DNS");

		workflowResolver.resolve(amendmentReq).submit(null, amendmentReq, "DNS");
		
		workflowResolver.resolve(amendmentReq).approve(null, null, amendmentReq, "DNS");

//		Assert.assertNotNull(amendmentReq.getReviews());
//		Assert.assertEquals(amendmentReq.getReviews().size(), 0);
//		Assert.assertTrue(amendmentReq.allReviewsApproved());
		Assert.assertNotNull(amendmentReq.getAllReviews());
		Assert.assertEquals(amendmentReq.getAllReviews().size(), 0);
		Assert.assertTrue(amendmentReq.allReviewsApproved(null));

		amendmentReq.approve(null, pers.getName());
		workflowResolver.resolve(amendmentReq).approve(null, null, amendmentReq, "DNS");

		// create an amendment of the amendment
		OperationalRequest amendmentReq2 = amendmentReq.createAmendment("DNS");

		OperationalRequest req3 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req3);

		Assert.assertNotEquals(req3, req);
		Assert.assertEquals(req3, amendmentReq2);
		Assert.assertTrue(req3.isAmendment());

		// VINCI-298  data sources in the amendment of an amendment

		Assert.assertNotNull(req3.getDataSources());
		Assert.assertEquals(req3.getDataSources().size(), 1);
		Assert.assertTrue(req3.getDataSources().contains(ds2));  // data sources are copied from the recent amendment
		Assert.assertFalse(req3.getDataSources().contains(ds));  // data sources are *NOT* copied from the original request
	}

	@Test
	public void testSixteen() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");
		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		Assert.assertFalse(req.isAmendment());
		Assert.assertEquals(req.getHeadId(), 0);

		Location loc = Location.findById(1);
		Assert.assertNotNull(loc);
		Assert.assertEquals(loc.getId(), 1);
		req.getSites().add(loc);
		req.setPrimaryLocation(loc);

		Assert.assertNotNull(req.getSites());
		Assert.assertEquals(req.getSites().size(), 1);
		Assert.assertTrue(req.getSites().contains(loc));
		Assert.assertEquals(req.getPrimaryLocation(), loc);
		
		OperationalRequest amendment = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		WorkflowResolver workflowResolver = DartObjectFactory.getInstance().getWorkflowResolver();
		Assert.assertTrue(workflowResolver.resolve(req) instanceof WfOperationalRequest);
		
		workflowResolver.resolve(req).initialize(null, req, "DNS");

		workflowResolver.resolve(req).submit(null, req, "DNS");
		
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

		req.approve(null, pers.getName());

		// create an amendment
		OperationalRequest amendmentReq = req.createAmendment("DNS");
		amendmentReq.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		OperationalRequest req2 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req2);

		Assert.assertNotEquals(req2, req);
		Assert.assertEquals(req2, amendmentReq);
		Assert.assertTrue(req2.isAmendment());

		Assert.assertNotNull(req2.getSites());
		Assert.assertEquals(req2.getSites().size(), 1);
		Assert.assertTrue(req2.getSites().contains(loc));  // data sources are copied from the original request

		Location loc2 = Location.findById(26);
		Assert.assertNotNull(loc2);
		Assert.assertEquals(loc2.getId(), 26);
		amendmentReq.getSites().clear();
		amendmentReq.getSites().add(loc2);
		amendmentReq.setPrimaryLocation(loc2);
		Assert.assertEquals(req.getPrimaryLocation(), loc);
		Assert.assertEquals(amendmentReq.getPrimaryLocation(), loc2);

		workflowResolver.resolve(amendmentReq).initialize(null, amendmentReq, "DNS");

		workflowResolver.resolve(amendmentReq).submit(null, amendmentReq, "DNS");
		
		workflowResolver.resolve(amendmentReq).approve(null, null, amendmentReq, "DNS");

		amendmentReq.approve(null, pers.getName());

		// create an amendment of the amendment
		OperationalRequest amendmentReq2 = amendmentReq.createAmendment("DNS");
		amendmentReq2.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		workflowResolver.resolve(amendmentReq2).initialize(null, amendmentReq2, "DNS");
		
		OperationalRequest req3 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req3);

		Assert.assertNotEquals(req3, req);
		Assert.assertEquals(req3, amendmentReq2);
		Assert.assertTrue(req3.isAmendment());

		// sites in the amendment of an amendment

		Assert.assertNotNull(req3.getSites());
		Assert.assertEquals(req3.getSites().size(), 1);
		Assert.assertTrue(req3.getSites().contains(loc2));  // site locations are copied from the recent amendment
		Assert.assertFalse(req3.getSites().contains(loc));  // site locations are *NOT* copied from the original request
		
		Assert.assertEquals(req.getPrimaryLocation(), loc);
		Assert.assertEquals(amendmentReq.getPrimaryLocation(), loc2);
		Assert.assertEquals(amendmentReq2.getPrimaryLocation(), loc2);

	}
	
	@Test
	public void testSeventeen() throws Exception {

		Person pers = Person.findById(1006);
		OperationalStudy activity = OperationalStudy.listAll().get(0);

		Assert.assertNotNull(pers);
		Assert.assertNotNull(pers.getName());
		Assert.assertTrue(pers.getName().length() > 0);
		
		// create request 1 so we'll have something to work with
		OperationalRequest req = OperationalRequest.create("test request 1", pers, activity, "DNS");
		req.setWorkflowTypeId(WorkflowResolver.WF_OPERATIONAL_REQUEST);  // required for the workflow engine

		Assert.assertNotNull(req);
		Assert.assertTrue(req.getId() > 0);
		Assert.assertEquals(req.getActivity(), activity);
		Assert.assertFalse(req.isAmendment());
		Assert.assertEquals(req.getHeadId(), 0);

		Location loc = Location.findById(1);
		Assert.assertNotNull(loc);
		Assert.assertEquals(loc.getId(), 1);
		
		// request needs a primary investigator
		Participant part = Participant.create(pers, req, pers.getLocation(), true, true, true);
		Assert.assertNotNull(part);
		Assert.assertTrue(part.getId() > 0);

		Assert.assertNotNull(req.getParticipants());
		Assert.assertEquals(req.getParticipants().size(), 1);
		
		OperationalRequest amendment = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNull(amendment);
		
		WorkflowResolver workflowResolver = DartObjectFactory.getInstance().getWorkflowResolver();
		Assert.assertTrue(workflowResolver.resolve(req) instanceof WfOperationalRequest);
		
		workflowResolver.resolve(req).initialize(null, req, "DNS");

		workflowResolver.resolve(req).submit(null, req, "DNS");
		
		workflowResolver.resolve(req).approve(null, null, req, "DNS");

		req.approve(null, pers.getName());

		// create an amendment
		OperationalRequest amendmentReq = req.createAmendment("DNS");

		OperationalRequest req2 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req2);

		Assert.assertNotEquals(req2, req);
		Assert.assertEquals(req2, amendmentReq);
		Assert.assertTrue(req2.isAmendment());

		// amendment gets a copy of original request participants
		Assert.assertNotNull(amendmentReq.getParticipants());
		Assert.assertEquals(amendmentReq.getParticipants().size(), 1);
		Participant tstPart = amendmentReq.getParticipants().iterator().next();
		Assert.assertNotNull(tstPart);
		Assert.assertEquals(tstPart.getPerson(), pers);
		
		// request needs a primary investigator
		Person pers2 = Person.findById(1004);
		Assert.assertNotNull(pers2);
		Assert.assertTrue(pers2.getId() > 0);
		
		Participant part2 = Participant.create(pers2, req, pers2.getLocation(), true, true, true);
		Assert.assertNotNull(part2);
		Assert.assertTrue(part2.getId() > 0);

		amendmentReq.getParticipants().clear();
		amendmentReq.getParticipants().add(part2);

		Assert.assertTrue(workflowResolver.resolve(amendmentReq) instanceof WfOperationalRequest);
		
		workflowResolver.resolve(amendmentReq).initialize(null, amendmentReq, "DNS");

		workflowResolver.resolve(amendmentReq).submit(null, amendmentReq, "DNS");
		
		workflowResolver.resolve(amendmentReq).approve(null, null, amendmentReq, "DNS");

		amendmentReq.approve(null, pers.getName());

		// create an amendment of the amendment
		OperationalRequest amendmentReq2 = amendmentReq.createAmendment("DNS");

		OperationalRequest req3 = OperationalRequest.findMostRecentAmendment(req.getId());
		Assert.assertNotNull(req3);

		Assert.assertNotEquals(req3, req);
		Assert.assertEquals(req3, amendmentReq2);
		Assert.assertTrue(req3.isAmendment());

		// principal investigator in the amendment of an amendment

		Assert.assertNotNull(req3.getParticipants());
		Assert.assertEquals(req3.getParticipants().size(), 1);
		Participant tstPart2 = req3.getParticipants().iterator().next();
		Assert.assertNotNull(tstPart2);
		Assert.assertNotEquals(tstPart2.getPerson(), pers);
		Assert.assertEquals(tstPart2.getPerson(), pers2);
	}

}
