/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.labo.ejb.entity.beans;

import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import lu.tudor.santec.gecamed.addressbook.ejb.entity.beans.Contact;
import lu.tudor.santec.gecamed.core.ejb.entity.beans.GECAMedEntityBean;
import lu.tudor.santec.gecamed.labo.ejb.session.interfaces.ImportInterface;
import lu.tudor.santec.gecamed.office.ejb.entity.beans.Physician;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

@Entity
@Table(name = "result", schema = "labo")

@javax.persistence.NamedQueries 
	({
	@NamedQuery(name = Result.c_ResultById        		   ,  query = "SELECT OBJECT(o) FROM Result o WHERE o.id = :" + Result.c_IdParameter),

	@NamedQuery(name = Result.c_ResultByIncidentEntryId    ,  query = "SELECT OBJECT(o) FROM Result o WHERE o.incidentEntryId = :" + Result.c_IncidentEntryIdParameter),

	@NamedQuery(name = Result.c_ResultsForPhysician        ,  query = "SELECT OBJECT(o) FROM Result o WHERE o.prescriber.id = :" + Result.c_PhysicianIdParameter +
			 																				        " ORDER BY o.downloaded DESC"),

	@NamedQuery(name = Result.c_ResultsForPhysicianByPeriod,  query = "SELECT OBJECT(o) FROM Result o WHERE o.prescriber.id = :" + Result.c_PhysicianIdParameter +
			 																				              " AND o.downloaded >= :" + Result.c_BeginOfPeriodParameter +
																							              " AND o.downloaded <= :" + Result.c_EndOfPeriodParameter +
																							              " ORDER BY o.downloaded DESC"),
	
	@NamedQuery(name = Result.c_AlreadyExistingResult      ,  query = "SELECT OBJECT(o) FROM Result o WHERE o.laboratory.id = :"     + Result.c_LaboratoryIdParameter +
																										  " AND o.prescriber.id = :" + Result.c_PhysicianIdParameter +
																										  " AND o.resultNumber = :"  + Result.c_ResultNumberParameter)																					              
	})

	public class Result extends GECAMedEntityBean
	{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Laboratory			m_Laboratory;
	private Physician			m_Prescriber;
	private Patient				m_Patient;
	private Integer				m_IncidentEntryId;
	private Integer				m_ResultNumber;
	private Date				m_PrescriptionDate;
	private Date				m_ExaminationDate;
	private Date				m_SpecimenDate;
	private Date				m_Downloaded;
	private String				m_Reference;
	private String				m_ExaminationStatus;
	private String				m_ResultStatus;
	private String				m_Comment;
	
	private Set <Contact> 		m_ContactPersons;
	private Set <Analysis>		m_Analyses;
	private Set <Antibiogram>	m_Antibiograms;

	
	private int 				m_State = ImportInterface.IMPORT_SUCCESSFUL;
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

	public static final String c_ResultById		 			 = "getResultById";
	public static final String c_ResultByIncidentEntryId	 = "getResultByIncidentEntryId";
	public static final String c_ResultsForPhysician		 = "getResultsForPhysician";
	public static final String c_ResultsForPhysicianByPeriod = "getResultsForPhysicianByPeriod";
	public static final String c_AlreadyExistingResult		 = "getAlreadyExistingResult";
	
	public static final String c_IdParameter    		 	= "Id";
	public static final String c_IncidentEntryIdParameter   = "IncidentEntryId";
	public static final String c_LaboratoryIdParameter    	= "LaboratoryId";
	public static final String c_PhysicianIdParameter    	= "PhysicianId";
	public static final String c_ResultNumberParameter    	= "ResultNumber";
	public static final String c_BeginOfPeriodParameter  	= "BeginOfPeriod";
	public static final String c_EndOfPeriodParameter    	= "EndOfPeriod";
	
	public static final String c_LaboResultIncident		 	= "labo.result";
	public static final String c_LaboResultMime			 	= "text/plain";
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
/**
 * returns the laboratory that performed the tests contained in this result
 * @return the laboratory that performed the tests
 */
//---------------------------------------------------------------------------

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "laboratory_id")

public Laboratory getLaboratory()
	{
	return m_Laboratory;
	}

//---------------------------------------------------------------------------
/**
 * @param p_laboratory specifies the new performing laboratory to be set for
 * this result.
 */
//---------------------------------------------------------------------------

public void setLaboratory (Laboratory p_laboratory)
	{
    m_Laboratory = p_laboratory;
	}

//---------------------------------------------------------------------------
/**
 * returns the physician who prescribed the laboratory tests stored in this
 * result
 * @return the prescribing physician
 */
//---------------------------------------------------------------------------

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "prescriber_id")

public Physician getPrescriber()
	{
	return m_Prescriber;
	}

//---------------------------------------------------------------------------
/**
 * Sets the prescribing physician for this result to the specified physician
 * @param p_Prescriber specifies the new prescribing physician for this
 * result
 */
//---------------------------------------------------------------------------

public void setPrescriber (Physician p_Prescriber)
	{
	m_Prescriber = p_Prescriber;
	}
	
//---------------------------------------------------------------------------
/**
 * returns the patient for whom the tests stored in this result were done for
 * @return the patient the tests were done for
 */
//---------------------------------------------------------------------------

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "patient_id")

public Patient getPatient()
	{
	return m_Patient;
	}

//---------------------------------------------------------------------------
/**
 * Sets the patient for whom the tests stored in this result were done for.
 * @param p_Patient specifies the new patient
 */
//---------------------------------------------------------------------------

public void setPatient (Patient p_Patient)
	{
	m_Patient = p_Patient;
	}

//---------------------------------------------------------------------------
/**
 * returns the ID of the incident entry associated with this result
 * @return the ID of the associated incident entry
 */
//---------------------------------------------------------------------------

@Column(name = "incident_entry_id")
public Integer getIncidentEntryId()
	{
	return m_IncidentEntryId;
	}

//---------------------------------------------------------------------------
/**
 * Sets the ID of the incident entry associated with this result
 * @param p_IncidentEntryId specifies the ID of the incident entry
 */
//---------------------------------------------------------------------------

public void setIncidentEntryId (Integer p_IncidentEntryId)
	{
	m_IncidentEntryId = p_IncidentEntryId;
	}

//---------------------------------------------------------------------------
/**
 * returns the number of the result which was contained in the downloaded
 * result file name.
 * @return the result number given to this result by the laboratory
 */
//---------------------------------------------------------------------------

@Column(name = "result_number")
public Integer getResultNumber()
	{
	return m_ResultNumber;
	}

//---------------------------------------------------------------------------
/**
 * Sets the number of the result which was contained in the downloaded
 * result file name.
 * @param p_ResultNumber specifies the new result number
 */
//---------------------------------------------------------------------------

public void setResultNumber(Integer p_ResultNumber)
	{
	m_ResultNumber = p_ResultNumber;
	}

//---------------------------------------------------------------------------
/**
 * returns the date the prescribing physician prescribed the tests contained
 * in this result
 * @return the prescription date
 */
//---------------------------------------------------------------------------

@Column(name = "prescription_date")
public Date getPrescriptionDate()
	{
	return m_PrescriptionDate;
	}

//---------------------------------------------------------------------------
/**
 * Sets the date the prescribing physician prescribed the tests contained in
 * this result
 * @param prescriptionDate specifies the new prescription date
 */
//---------------------------------------------------------------------------

public void setPrescriptionDate (Date p_PrescriptionDate)
	{
	m_PrescriptionDate = (p_PrescriptionDate != null) ? new Date (p_PrescriptionDate.getTime()) : null;
	}
	
//---------------------------------------------------------------------------
/**
 * returns the date the specimen or samples required for the tests were taken 
 * from the patient.
 * @return the date the samples were taken.
 */
//---------------------------------------------------------------------------

@Column(name = "specimen_date")
public Date getSpecimenDate()
	{
	return m_SpecimenDate;
	}

//---------------------------------------------------------------------------
/**
 * Sets the date the specimen or samples required for the tests were taken 
 * from the patient.
 * @param p_SpecimenDate specifies the new sampling date
 */
//---------------------------------------------------------------------------

public void setSpecimenDate (Date p_SpecimenDate)
	{
	m_SpecimenDate = (p_SpecimenDate != null) ? new Date (p_SpecimenDate.getTime()) : null;
	}
	
//---------------------------------------------------------------------------
/**
 * returns the date the specimen or samples were analyzed 
 * @return the date the samples were analyzed.
 */
//---------------------------------------------------------------------------

@Column(name = "examination_date")
public Date getExaminationDate()
	{
	return m_ExaminationDate;
	}

//---------------------------------------------------------------------------
/**
 * Sets the date the specimen or samples were analyzed
 * @param p_ExaminationDate specifies the new analyzing date
 */
//---------------------------------------------------------------------------

public void setExaminationDate (Date p_ExaminationDate)
	{
	m_ExaminationDate = (p_ExaminationDate != null) ? new Date (p_ExaminationDate.getTime()) : null;
	}

//---------------------------------------------------------------------------
/**
 * returns the date and time this result was downloaded
 * @return the date and time this result was downloaded
 */
//---------------------------------------------------------------------------

@Column(name = "downloaded")
public Date getDownloaded()
	{
	return m_Downloaded;
	}

//---------------------------------------------------------------------------
/**
 * Sets the date and time this result was downloaded
 * @param p_Downloaded specifies the new download date and time
 */
//---------------------------------------------------------------------------

public void setDownloaded (Date p_Downloaded)
	{
	m_Downloaded = (p_Downloaded != null) ? new Date (p_Downloaded.getTime()) : null;
	}

//---------------------------------------------------------------------------
/**
 * returns the reference defined by the laboratory to clearly identify this
 * result.
 * @return the reference given to this result by the laboratory
 */
//---------------------------------------------------------------------------

@Column(name = "reference")
public String getReference()
	{
	return m_Reference;
	}

//---------------------------------------------------------------------------
/**
 * Sets the reference to clearly identify this result.
 * @param p_Reference specifies the new reference
 */
//---------------------------------------------------------------------------

public void setReference(String p_Reference)
	{
	m_Reference = p_Reference;
	}

//---------------------------------------------------------------------------
/**
 * Returns the status of the examination (or analysis) that generated this
 * result
 * @return the status of the examination
 */
//---------------------------------------------------------------------------

@Column(name = "examination_status")
public String getExaminationStatus()
	{
	return m_ExaminationStatus;
	}

//---------------------------------------------------------------------------
/**
 * Sets the status of the examination that generated this result
 * @param p_ExaminationStatus specifies the new status
 */
//---------------------------------------------------------------------------

public void setExaminationStatus (String p_ExaminationStatus)
	{
	m_ExaminationStatus = p_ExaminationStatus;
	}
	
//---------------------------------------------------------------------------
/**
 * Returns the status of this result
 * @return the status of this result
 */
//---------------------------------------------------------------------------

@Column(name = "result_status")
public String getResultStatus()
	{
	return m_ResultStatus;
	}

//---------------------------------------------------------------------------
/**
 * Sets the status for this result
 * @param p_ResultStatus specifies the new status
 */
//---------------------------------------------------------------------------

public void setResultStatus (String p_ResultStatus)
	{
	m_ResultStatus = p_ResultStatus;
	}
	
//---------------------------------------------------------------------------
/**
 * Returns eventual comment provided by the laboratory for this result
 * @return the comments about this result
 */
//---------------------------------------------------------------------------

@Column(name = "comments")
public String getComment()
	{
	return m_Comment;
	}

//---------------------------------------------------------------------------
/**
 * Sets eventual comments for this result
 * @param p_Comments specifies the new comments
 */
//---------------------------------------------------------------------------

public void setComment (String p_Comment)
	{
	m_Comment = p_Comment;
	}

//---------------------------------------------------------------------------
/**
 * Returns the contact persons for this result. 
 * @return All the contact persons for this result.
 * @
 */
//---------------------------------------------------------------------------

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "rel_result_contact", schema = "labo",
						joinColumns = {@JoinColumn(name = "result_id")},
						inverseJoinColumns = {@JoinColumn(name = "contact_id")})

public Set<Contact> getContactPersons ()
	{
	return m_ContactPersons;
	}

//---------------------------------------------------------------------------
/**
 * Sets the specified set of contact persons as the new contact persons for
 * this result.
 * @param p_ContactPersons specifies the new set of contact persons.
 */
//---------------------------------------------------------------------------

public void setContactPersons (Set<Contact> p_ContactPersons )
	{
	m_ContactPersons = p_ContactPersons;
	}

//---------------------------------------------------------------------------
/**
 * Returns all analyses for this result. Analyses are fetched lazily
 * @return All the analyses for this result.
  */
//---------------------------------------------------------------------------

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn (name = "result_id")
@OrderBy ("id ASC")
public Set<Analysis> getAnalyses ()
	{
	return m_Analyses;
	}

//---------------------------------------------------------------------------
/**
 * Sets the specified set of analyses as the ones for this result
 * @param p_Analyses specifies the new set of analyses.
 */
//---------------------------------------------------------------------------

public void setAnalyses (Set<Analysis> p_Analyses )
	{
	m_Analyses = p_Analyses;
	}

//---------------------------------------------------------------------------
/**
 * Returns all antibiograms for this result. Antibiograms are fetched lazily
 * @return All the antibiograms for this result.
  */
//---------------------------------------------------------------------------

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "result_id")
@OrderBy ("id ASC")
public Set<Antibiogram> getAntibiograms ()
	{
	return m_Antibiograms;
	}

//---------------------------------------------------------------------------
/**
 * Sets the specified set of antibiograms as the ones for this result
 * @param p_Antibiograms specifies the new set of antibiograms.
 */
//---------------------------------------------------------------------------

public void setAntibiograms (Set<Antibiogram> p_Antibiograms )
	{
	m_Antibiograms = p_Antibiograms;
	}

//---------------------------------------------------------------------------

@Transient
public int getState ()
	{
	return m_State;
	}

//---------------------------------------------------------------------------

@Transient
public void setState (int p_State)
	{
	m_State = p_State;
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	}
