//#############################################################################
//#                                                                           #
//#  Copyright (C) <2015>  <IMS MAXIMS>                                       #
//#                                                                           #
//#  This program is free software: you can redistribute it and/or modify     #
//#  it under the terms of the GNU Affero General Public License as           #
//#  published by the Free Software Foundation, either version 3 of the       #
//#  License, or (at your option) any later version.                          # 
//#                                                                           #
//#  This program 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 Affero General Public License for more details.                      #
//#                                                                           #
//#  You should have received a copy of the GNU Affero General Public License #
//#  along with this program.  If not, see <http://www.gnu.org/licenses/>.    #
//#                                                                           #
//#  IMS MAXIMS provides absolutely NO GUARANTEE OF THE CLINICAL SAFTEY of    #
//#  this program.  Users of this software do so entirely at their own risk.  #
//#  IMS MAXIMS only ensures the Clinical Safety of unaltered run-time        #
//#  software that it builds, deploys and maintains.                          #
//#                                                                           #
//#############################################################################
//#EOH
// This code was generated by Peter Martin using IMS Development Environment (version 1.66 build 3261.22124)
// Copyright (C) 1995-2008 IMS MAXIMS plc. All rights reserved.

package ims.core.domain.impl;

import ims.admin.domain.HcpAdmin;
import ims.admin.domain.OrganisationAndLocation;
import ims.admin.domain.impl.HcpAdminImpl;
import ims.admin.domain.impl.OrganisationAndLocationImpl;
import ims.configuration.gen.ConfigFlag;
import ims.core.admin.pas.domain.objects.InpatientEpisode;
import ims.core.admin.pas.domain.objects.PendingTransfers;
import ims.core.admin.pas.vo.InpatientEpisodeRefVo;
import ims.core.admin.pas.vo.PASEventRefVo;
import ims.core.admin.pas.vo.PendingTransfersRefVo;
import ims.core.domain.Demographics;
import ims.core.domain.WardView;
import ims.core.domain.base.impl.BaseTransfersImpl;
import ims.core.patient.vo.PatientRefVo;
import ims.core.resource.place.domain.objects.Location;
import ims.core.resource.place.vo.LocationRefVo;
import ims.core.vo.CareContextShortVo;
import ims.core.vo.HcpFilter;
import ims.core.vo.HcpLiteVo;
import ims.core.vo.HcpLiteVoCollection;
import ims.core.vo.InpatientEpisodeForTransfersVo;
import ims.core.vo.InpatientEpisodeVo;
import ims.core.vo.InpatientEpisodeVoCollection;
import ims.core.vo.LocMostVo;
import ims.core.vo.LocationLiteVo;
import ims.core.vo.LocationLiteVoCollection;
import ims.core.vo.Patient;
import ims.core.vo.PatientShort;
import ims.core.vo.PendingTransfersFilterVo;
import ims.core.vo.PendingTransfersVo;
import ims.core.vo.PendingTransfersVoCollection;
import ims.core.vo.WardStayVo;
import ims.core.vo.domain.InpatientEpisodeForTransfersVoAssembler;
import ims.core.vo.domain.InpatientEpisodeVoAssembler;
import ims.core.vo.domain.LocMostVoAssembler;
import ims.core.vo.domain.LocationLiteVoAssembler;
import ims.core.vo.domain.PendingTransfersVoAssembler;
import ims.core.vo.lookups.PatIdType;
import ims.domain.DomainFactory;
import ims.domain.exceptions.DomainInterfaceException;
import ims.domain.exceptions.StaleObjectException;
import ims.domain.lookups.LookupInstance;
import ims.framework.exceptions.CodingRuntimeException;
import ims.framework.interfaces.ILocation;
import ims.framework.utils.Date;
import ims.framework.utils.DateTime;
import ims.framework.utils.Time;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class TransfersImpl extends BaseTransfersImpl
{

	private static final long serialVersionUID = 1L;

	public PendingTransfersVoCollection listPendingTransfers(PendingTransfersFilterVo filter) 
	{
		if (filter == null)
			throw new CodingRuntimeException("Invalid voFilter");

		ArrayList<String> markers = new ArrayList<String>();
		ArrayList<Serializable> values = new ArrayList<Serializable>();

		StringBuffer sb = new StringBuffer();
		String andStr = "";
		boolean isCaseSensitivePatIdSearch = ConfigFlag.DOM.CASE_SENSITIVE_PATID.getValue(); //WDEV-18817

		String hql = ConfigFlag.UI.BED_INFO_UI_TYPE.getValue().equals("MAXIMS") ?  "select trans, (select wcfg.wardStatus from WardBayConfig wcfg WHERE wcfg.ward.id = trans.inpatientEpisode.pasEvent.location.id) from PendingTransfers as trans" : "select trans from PendingTransfers as trans "; 

		String strSearchSurname = "";
		String strSearchForename = "";

		
		if (filter.getPatientHospNumberIsNotNull())
		{
			hql += " join trans.inpatientEpisode.pasEvent.patient.identifiers as ids ";
			
			String idVal = filter.getPatientHospNumber().trim();			
			if (filter.getIDType().equals(PatIdType.NHSN))
				idVal = filter.getPatientHospNumber().replace(" ", "");//wdev-7305
			if (!isCaseSensitivePatIdSearch)
			{	
				idVal = idVal.toUpperCase(); //WDEV-18817
			}
			if (filter.getIDType().equals(PatIdType.NHSN))
			{
				sb.append(andStr + (!isCaseSensitivePatIdSearch ? " UPPER(ids.value)" : " ids.value") + " like :idnum "); //WDEV-18817 
				idVal += "%";
			}
			else
				sb.append(andStr + (!isCaseSensitivePatIdSearch ? " UPPER(ids.value)" : " ids.value") + " = :idnum");//WDEV-18817

			markers.add("idnum");
			andStr = " and ";
			sb.append(andStr + " ids.type = :idtype");
			markers.add("idtype");

			values.add(idVal);
			values.add(getDomLookup(filter.getIDType()));
		}
		else
		{
			if(filter.getPatientForenameIsNotNull())
			{
				sb.append(andStr + " trans.inpatientEpisode.pasEvent.patient.name.upperForename like :patFore");
				markers.add("patFore");
				andStr = " and ";
	
				strSearchForename = filter.getPatientForename().toUpperCase().trim();
				strSearchForename = strSearchForename.replaceAll("[^a-zA-Z]", "");
					
				if(strSearchForename.length() >= 40)
				{
					strSearchForename = strSearchForename.substring(0,40);
					strSearchForename += '%';
				}
				else
				{
					strSearchForename += '%';
				}
				values.add(strSearchForename);
	
			}
	
			if(filter.getPatientSurnameIsNotNull())
			{
				sb.append(andStr + " trans.inpatientEpisode.pasEvent.patient.name.upperSurname like :patSur");
				markers.add("patSur");
				andStr = " and ";
	
				strSearchSurname = filter.getPatientSurname().toUpperCase().trim();
				strSearchSurname = strSearchSurname.replaceAll("[^a-zA-Z]", "");
					
				if(strSearchSurname.length() >= 40)
				{
					strSearchSurname = strSearchSurname.substring(0,40);
					strSearchSurname += '%';
				}
				else
				{
					strSearchSurname += '%';
				}
				values.add(strSearchSurname);
	
			}
		}//WDEV-13065
		
		if (filter.getConsultantIsNotNull())
		{
			sb.append(andStr + " trans.inpatientEpisode.pasEvent.consultant.id = :cons");
			markers.add("cons");
			values.add(filter.getConsultant().getID_Hcp());
			andStr = " and ";
		}
		
		//WDEV-20258
		if (filter.getCurrentWardIsNotNull())
		{
			sb.append(andStr + " trans.inpatientEpisode.pasEvent.location.id = :ward");
			markers.add("ward");
			values.add(filter.getCurrentWard().getID_Location());
			andStr = " and ";
		}
		else if (filter.getCurrentHospitalIsNotNull())
		{
			LocationLiteVoCollection wards = listWards(filter.getCurrentHospital().getID_Location(), null);
			if (wards != null && wards.size() > 0)
			{	
					sb.append(andStr + " (trans.inpatientEpisode.pasEvent.location.id in " + getWardIds(wards));
					sb.append(" OR ");
				}
						
			sb.append((wards != null && wards.size() > 0 ? "" : andStr) + " trans.inpatientEpisode.pasEvent.location.parentLocation.id = :hosp" + (wards != null && wards.size() > 0 ? ")" : ""));
			markers.add("hosp");
			values.add(filter.getCurrentHospital().getID_Location());			
			andStr = " and ";
		}

		if (filter.getDestinationWardIsNotNull())
		{
			sb.append(andStr + " trans.destinationWard.id = :destward");
			markers.add("destward");
			values.add(filter.getDestinationWard().getID_Location());
			andStr = " and ";
		}
		
		else if (filter.getDestHospitalIsNotNull())
		{
			LocationLiteVoCollection dwards = listWards(filter.getDestHospital().getID_Location(), null);
			if (dwards != null && dwards.size() > 0)
			{	
				sb.append(andStr + " (trans.destinationWard.id in " + getWardIds(dwards));
				sb.append(" OR ");
			}
			
			sb.append((dwards != null && dwards.size() > 0 ? "" : andStr)  + " trans.destinationWard.parentLocation.id = :dhosp" + (dwards != null && dwards.size() > 0 ? ")" : ""));
			markers.add("dhosp");
			values.add(filter.getDestHospital().getID_Location());			
			andStr = " and ";
		}		
		//WDEV-20258 --- end of
		if (filter.getAlertIsNotNull())
		{
			hql += " join trans.inpatientEpisode.pasEvent.patient.patientAlerts as patAlerts ";

			sb.append(andStr + " patAlerts.alertType = :alertID");
			markers.add("alertID");
			values.add(getDomLookup(filter.getAlert()));
			andStr = " and ";
		}
		
		if(sb.length()!=0){
			hql += " where ";
			hql += sb.toString();
		}
		if (ConfigFlag.UI.BED_INFO_UI_TYPE.getValue().equals("MAXIMS")) //WDEV-20328
		{
			List<?> results = getDomainFactory().find(hql.toString(), markers, values);
			
			if (results == null || results.isEmpty())
				return null;
			PendingTransfersVoCollection collResults = new PendingTransfersVoCollection();

			for (int i = 0; i<results.size();i++)
			{
				if (results.get(i) instanceof Object[])
				{
					Object[] ret = (Object[]) results.get(i);
					PendingTransfersVo vo = new PendingTransfersVo();
					if (ret[0] instanceof PendingTransfers)
					{	
						//WDEV-22567
						PendingTransfers doPendingTransf = (PendingTransfers) ret[0];
						if (doPendingTransf != null && doPendingTransf.getInpatientEpisode() != null && doPendingTransf.getInpatientEpisode().getPasEvent() != null && doPendingTransf.getInpatientEpisode().getPasEvent().getPatient() != null && doPendingTransf.getInpatientEpisode().getPasEvent().getPatient().getAssociatedPatient() != null)
						{
							ims.core.patient.domain.objects.Patient mergedToPatient = doPendingTransf.getInpatientEpisode().getPasEvent().getPatient().getAssociatedPatient();
							doPendingTransf.getInpatientEpisode().getPasEvent().setPatient(mergedToPatient);
						}
						vo = PendingTransfersVoAssembler.create(doPendingTransf);
					}
					if (ret[1] instanceof LookupInstance)
					{	
						vo.setWardStatus(ims.core.vo.lookups.LookupHelper.getWardBayStatusInstance(getLookupService(), ((LookupInstance) ret[1]).getId()));
					}
					collResults.add(vo);					
				}					
			}
			return collResults;
		}
		//WDEV-20328 -- ends here
		return PendingTransfersVoAssembler.createPendingTransfersVoCollectionFromPendingTransfers(getDomainFactory().find(hql.toString(), markers, values));
	}
	
	//WDEV-20258
	private String getWardIds(LocationLiteVoCollection wards)
	{
		if (wards == null || wards.size() == 0)
			return "";
		
		StringBuilder idList = new StringBuilder();
		idList.append("(");
		
		for (int i=0; i<wards.size();i++)
		{
			if (wards.get(i) == null)
				continue;
			idList.append(wards.get(i).getID_Location().toString()).append(i == wards.size() - 1 ? ")": ", ");			
		}
		
		return idList.toString();
	}
	public InpatientEpisodeVoCollection listRecentTransfers(PendingTransfersFilterVo filter)
	{
		if (filter == null)
			throw new CodingRuntimeException("Invalid voFilter");

		ArrayList<String> markers = new ArrayList<String>();
		ArrayList<Serializable> values = new ArrayList<Serializable>();
		boolean isCaseSensitivePatIdSearch = ConfigFlag.DOM.CASE_SENSITIVE_PATID.getValue(); //WDEV-18817

		StringBuffer sb = new StringBuffer();
		String andStr = "";

		String hql = ConfigFlag.UI.BED_INFO_UI_TYPE.getValue().equals("MAXIMS") ?  "select inpat, (select wcfg.wardStatus from WardBayConfig wcfg WHERE wcfg.ward.id = inpat.pasEvent.location.id), ws.transferReason, ws.transferComment from InpatientEpisode as inpat left join inpat.wardStays as ws" : "select inpat from InpatientEpisode as inpat"; 

		String strSearchSurname = "";
		String strSearchForename = "";

		sb.append(andStr + " inpat.wardStays.transferDateTime between :fromDate and :toDate and inpat.wardStays.transferDateTime <> inpat.admissionDateTime");
		markers.add("fromDate");
		values.add(new DateTime(new Date().addDay(-1), new Time()).getJavaDate() );
		markers.add("toDate");
		values.add(new DateTime(new Date(), new Time()).getJavaDate() );
		andStr = " and ";

		if (filter.getPatientHospNumberIsNotNull())
		{
			hql += " join inpat.pasEvent.patient.identifiers as ids ";
			
			String idVal = filter.getPatientHospNumber().trim();			
			if (filter.getIDType().equals(PatIdType.NHSN))
				idVal = filter.getPatientHospNumber().replace(" ", "");//wdev-7305
			
			if (!isCaseSensitivePatIdSearch) //WDEV-18817
			{	
				idVal = idVal.toUpperCase();
			}
			if (filter.getIDType().equals(PatIdType.NHSN))
			{
				sb.append(andStr + (!isCaseSensitivePatIdSearch ? " UPPER(ids.value)" : " ids.value") + " like :idnum");//WDEV-18817
				idVal += "%";
			}
			else
				sb.append(andStr + (!isCaseSensitivePatIdSearch ? " UPPER(ids.value)" : " ids.value") + " = :idnum");//WDEV-18817

			markers.add("idnum");
			andStr = " and ";
			sb.append(andStr + " ids.type = :idtype");
			markers.add("idtype");

			values.add(idVal);
			values.add(getDomLookup(filter.getIDType()));
		}
		else
		{
			if(filter.getPatientForenameIsNotNull())
			{
				sb.append(andStr + " inpat.pasEvent.patient.name.upperForename like :patFore");
				markers.add("patFore");
				andStr = " and ";
	
				strSearchForename = filter.getPatientForename().toUpperCase().trim();
				strSearchForename = strSearchForename.replaceAll("[^a-zA-Z]", "");
					
				if(strSearchForename.length() >= 40)
				{
					strSearchForename = strSearchForename.substring(0,40);
					strSearchForename += '%';
				}
				else
				{
					strSearchForename += '%';
				}
				values.add(strSearchForename);
	
			}
	
			if(filter.getPatientSurnameIsNotNull())
			{
				sb.append(andStr + " inpat.pasEvent.patient.name.upperSurname like :patSur");
				markers.add("patSur");
				andStr = " and ";
	
				strSearchSurname = filter.getPatientSurname().toUpperCase().trim();
				strSearchSurname = strSearchSurname.replaceAll("[^a-zA-Z]", "");
					
				if(strSearchSurname.length() >= 40)
				{
					strSearchSurname = strSearchSurname.substring(0,40);
					strSearchSurname += '%';
				}
				else
				{
					strSearchSurname += '%';
				}
				values.add(strSearchSurname);
	
			}
		}//WDEV-13065
		
		if (filter.getConsultantIsNotNull())
		{
			sb.append(andStr + " inpat.pasEvent.consultant.id = :cons");
			markers.add("cons");
			values.add(filter.getConsultant().getID_Hcp());
			andStr = " and ";
		}
		//WDEV-20258
		if (filter.getCurrentWardIsNotNull())
		{
			sb.append(andStr + " inpat.pasEvent.location.id = :currward");
			markers.add("currward");
			values.add(filter.getCurrentWard().getID_Location());
			andStr = " and ";
		}
		else if (filter.getCurrentHospitalIsNotNull())
		{
			LocationLiteVoCollection wards = listWards(filter.getCurrentHospital().getID_Location(), null);
			if (wards != null && wards.size() > 0)
			{	
				sb.append(andStr + " (inpat.pasEvent.location.id in " + getWardIds(wards));
				sb.append(" OR ");
			}
			
			sb.append((wards != null && wards.size() > 0 ? "" : andStr) + " inpat.pasEvent.location.parentLocation.id = :dhosp" + (wards != null && wards.size() > 0 ? ")" : ""));
			markers.add("dhosp");
			values.add(filter.getCurrentHospital().getID_Location());
			andStr = " and ";
		}
		//WDEV-20258   --- end of
		//WDEV-20328
	
		if (filter.getDestinationWardIsNotNull() 
			|| filter.getDestHospitalIsNotNull())
			hql += " join inpat.wardStays as stays ";
		//WDEV-20258 
		if (filter.getDestinationWardIsNotNull())
		{
			sb.append(andStr + " stays.ward.id = :ward");
			markers.add("ward");
			values.add(filter.getDestinationWard().getID_Location());
			andStr = " and ";
		}
		else if (filter.getDestHospitalIsNotNull())
		{
			LocationLiteVoCollection dwards = listWards(filter.getDestHospital().getID_Location(), null);
			if (dwards != null && dwards.size() > 0)
			{	
				sb.append(andStr + " (stays.ward.id in " + getWardIds(dwards));
				sb.append(" OR ");
			}
			
			sb.append((dwards != null && dwards.size() > 0 ? "" : andStr)  + " stays.ward.parentLocation.id = :dhosp" + (dwards != null && dwards.size() > 0 ? ")" : ""));
			markers.add("dhosp");
			values.add(filter.getDestHospital().getID_Location());
			andStr = " and ";
		}
		//WDEV-20258 -- ends here
		hql += " where ";
		hql += sb.toString();
		
		if (ConfigFlag.UI.BED_INFO_UI_TYPE.getValue().equals("MAXIMS")) //WDEV-20328
		{
			List<?> results = getDomainFactory().find(hql.toString(), markers, values);

			if (results == null || results.isEmpty())
				return null;
			InpatientEpisodeVoCollection collResults = new InpatientEpisodeVoCollection();

			for (int i = 0; i<results.size();i++)
			{
				if (results.get(i) instanceof Object[])
				{
					Object[] ret = (Object[]) results.get(i);
					InpatientEpisodeVo vo = new InpatientEpisodeVo();
					if (ret[0] instanceof InpatientEpisode)
					{	
						//WDEV-22567
						InpatientEpisode doInpat = (InpatientEpisode) ret[0];
						if (doInpat != null && doInpat.getPasEvent() != null && doInpat.getPasEvent().getPatient() != null && doInpat.getPasEvent().getPatient().getAssociatedPatient() != null)
						{
							ims.core.patient.domain.objects.Patient mergedToPatient = doInpat.getPasEvent().getPatient().getAssociatedPatient();
							doInpat.getPasEvent().setPatient(mergedToPatient);
						}
						vo = InpatientEpisodeVoAssembler.create(doInpat);
					}
					if (ret[1] instanceof LookupInstance)
					{	
						vo.setWardStatus(ims.core.vo.lookups.LookupHelper.getWardBayStatusInstance(getLookupService(), ((LookupInstance) ret[1]).getId()));
					}
					if (ret[2] instanceof LookupInstance)
					{	
						vo.setTransferReason(ims.core.vo.lookups.LookupHelper.getTransferReasonInstance(getLookupService(), ((LookupInstance) ret[2]).getId()));
					}
					if (ret[3] instanceof String)
					{	
						vo.setTransferComment((String)ret[3]);
					}
					
					collResults.add(vo);					
				}					
			}
			
			if (filter.getDestinationWardIsNotNull())
			{
				InpatientEpisodeVoCollection voReturnColl = new InpatientEpisodeVoCollection();
				if (collResults.size() > 0)
				{
					for (int i = 0 ; i < collResults.size() ; i++)
					{
						if (collResults.get(i).getWardStaysIsNotNull()
							&& collResults.get(i).getWardStays().size() > 1)
						{
							collResults.get(i).getWardStays().sort(WardStayVo.getWardStayVoIdComparator());
							
							WardStayVo voPreviousWardStay = collResults.get(i).getWardStays().get(1);
							if (voPreviousWardStay.getWardIsNotNull()
								&& voPreviousWardStay.getWard().equals(filter.getDestinationWard()))
							{
								collResults.get(i).setTransferReason(voPreviousWardStay.getTransferReason());
								collResults.get(i).setTransferComment(voPreviousWardStay.getTransferComment());
								voReturnColl.add(collResults.get(i));
							}
						}
					}
					return voReturnColl;
				}
			}
			else
			{	
				return collResults;
			}	
		}
		//WDEV-20328 -- ends here
		
		if (filter.getDestinationWardIsNotNull())
		{
			InpatientEpisodeVoCollection voReturnColl = new InpatientEpisodeVoCollection();
			InpatientEpisodeVoCollection voColl = InpatientEpisodeVoAssembler.createInpatientEpisodeVoCollectionFromInpatientEpisode(getDomainFactory().find(hql.toString(), markers, values));
			if (voColl.size() > 0)
			{
				for (int i = 0 ; i < voColl.size() ; i++)
				{
					if (voColl.get(i).getWardStaysIsNotNull()
						&& voColl.get(i).getWardStays().size() > 1)
					{
						voColl.get(i).getWardStays().sort(WardStayVo.getWardStayVoIdComparator());
						
						WardStayVo voPreviousWardStay = voColl.get(i).getWardStays().get(1);
						if (voPreviousWardStay.getWardIsNotNull()
							&& voPreviousWardStay.getWard().equals(filter.getDestinationWard()))
							voReturnColl.add(voColl.get(i));
					}
				}
				return voReturnColl;
			}
		}
		else
			return InpatientEpisodeVoAssembler.createInpatientEpisodeVoCollectionFromInpatientEpisode(getDomainFactory().find(hql.toString(), markers, values));
	
		return null;
	}

	public LocationLiteVoCollection listActiveHospitalsLite()
	{
		OrganisationAndLocation impl = (OrganisationAndLocation) getDomainImpl(OrganisationAndLocationImpl.class);
		return impl.listActiveHospitalsLite();		
	}

	public LocationLiteVoCollection listWards(Integer hospitalID, String searchName)
	{
		OrganisationAndLocation implLoc = (OrganisationAndLocation)getDomainImpl(OrganisationAndLocationImpl.class);
		LocationRefVo voRef = new LocationRefVo();
		voRef.setID_Location(hospitalID);
		return implLoc.listActiveWardsForHospitalByNameLite(voRef, searchName);
	}

	public HcpLiteVo getHCP(Integer idHCP) 
	{
		HcpAdmin implHcpAdmin = (HcpAdmin)getDomainImpl(HcpAdminImpl.class);
		HcpFilter voFilter = new HcpFilter();
		voFilter.setID_Hcp(idHCP);
		return implHcpAdmin.getHcpLite(voFilter);
	}

	public LocationLiteVo getWard(LocationRefVo voWardRef) 
	{
		OrganisationAndLocation implLoc = (OrganisationAndLocation)getDomainImpl(OrganisationAndLocationImpl.class);
		return implLoc.getLocation(voWardRef.getID_Location());
	}

	public LocationLiteVo getHospital(LocationRefVo locationRefvo) 
	{
		DomainFactory factory = getDomainFactory();
		return LocationLiteVoAssembler.create((Location) factory.getDomainObject(Location.class, locationRefvo.getID_Location()));
	}

	public HcpLiteVoCollection listHCPs(HcpFilter hcpFilter)
	{
		HcpAdmin implHcpAdmin = (HcpAdmin)getDomainImpl(HcpAdminImpl.class);
		return implHcpAdmin.listHcpLite(hcpFilter);
	}

	public PatientShort getPatientShort(PatientRefVo patientRefVo) 
	{
		Demographics impl = (Demographics) getDomainImpl(DemographicsImpl.class);
		Patient voPat = impl.getPatient(patientRefVo);		

		if (voPat != null)
			return (PatientShort)voPat;
		else
			return null;
	}

	public PendingTransfersVo getCurrentTransferRecord(PendingTransfersRefVo transferRefVo) 
	{
		DomainFactory factory = getDomainFactory();
		return PendingTransfersVoAssembler.create((PendingTransfers) factory.getDomainObject(PendingTransfers.class, transferRefVo.getID_PendingTransfers()));
	}

	public PendingTransfersVo saveTransfer(PendingTransfersVo voTransfer) throws DomainInterfaceException, StaleObjectException 
	{
		if(voTransfer == null)
			throw new CodingRuntimeException("Cannot save null PendingTransfersVo");
		if (!voTransfer.isValidated())
			throw new CodingRuntimeException("Transfer Record has not been validated");
				
		DomainFactory factory = getDomainFactory();
		
		PendingTransfers doTrans = PendingTransfersVoAssembler.extractPendingTransfers(factory, voTransfer);
			
		factory.save(doTrans);
		return (PendingTransfersVoAssembler.create(doTrans));		
	}

	public LocMostVo getLocation(LocationRefVo voLocRef)
	{
		DomainFactory factory = getDomainFactory();
		return LocMostVoAssembler.create((Location) factory.getDomainObject(Location.class, voLocRef.getID_Location()));
	}

	public InpatientEpisodeForTransfersVo getCurrentTransferRecord(InpatientEpisodeRefVo ipRefVo)
	{
		DomainFactory factory = getDomainFactory();
		return InpatientEpisodeForTransfersVoAssembler.create((InpatientEpisode) factory.getDomainObject(InpatientEpisode.class, ipRefVo.getID_InpatientEpisode()));
	}

	public InpatientEpisodeForTransfersVo saveTransfer(InpatientEpisodeForTransfersVo voTransfer) throws DomainInterfaceException, StaleObjectException 
	{
		if(voTransfer == null)
			throw new CodingRuntimeException("Cannot save null InpatientEpisodeForTransfersVo");
		if (!voTransfer.isValidated())
			throw new CodingRuntimeException("Transfer Record has not been validated");
		
		DomainFactory factory = getDomainFactory();
		
		InpatientEpisode doTrans = InpatientEpisodeForTransfersVoAssembler.extractInpatientEpisode(factory, voTransfer);
			
		factory.save(doTrans);
		return InpatientEpisodeForTransfersVoAssembler.create(doTrans);		
	}

	public void saveInpatientEpisode(InpatientEpisodeVo inpatEpis) throws StaleObjectException
	{
		if (inpatEpis == null)
			throw new CodingRuntimeException("inpatEpis is null in method saveInpatientEpisode");
		if (!inpatEpis.isValidated())
			throw new CodingRuntimeException("inpatEpis has not been validated in method saveInpatientEpisode");

		DomainFactory factory = getDomainFactory();
		factory.save(InpatientEpisodeVoAssembler.extractInpatientEpisode(factory, inpatEpis));
	}
	
	//WDEV-20707
	public LocationLiteVo getCurrentHospital(ILocation location) 
	{
		WardView impl = (WardView)getDomainImpl(WardViewImpl.class);
		return impl.getCurrentHospital(location);
	}

	public CareContextShortVo getCurrentCareContext(PASEventRefVo pasEventRef)
	{
		WardView impl = (WardView) getDomainImpl(WardViewImpl.class);
		return impl.getCareContextForPasEvent(pasEventRef);
	}
}
