// Generated by: hibernate/SpringHibernateDaoImpl.vsl in andromda-spring-cartridge.
// license-header java merge-point
/**
 * This is only generated once! It will never be overwritten.
 * You can (and have to!) safely modify it by hand.
 */
package org.phoenixctms.ctsms.domain;

import java.sql.Timestamp;
import java.util.Collection;

import org.hibernate.Criteria;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.phoenixctms.ctsms.query.CategoryCriterion;
import org.phoenixctms.ctsms.query.CategoryCriterion.EmptyPrefixModes;
import org.phoenixctms.ctsms.query.CriteriaUtil;
import org.phoenixctms.ctsms.query.SubCriteriaMap;
import org.phoenixctms.ctsms.util.DefaultSettings;
import org.phoenixctms.ctsms.util.SettingCodes;
import org.phoenixctms.ctsms.util.Settings;
import org.phoenixctms.ctsms.util.Settings.Bundle;
import org.phoenixctms.ctsms.util.date.BookingDuration;
import org.phoenixctms.ctsms.vo.CourseOutVO;
import org.phoenixctms.ctsms.vo.InventoryBookingInVO;
import org.phoenixctms.ctsms.vo.InventoryBookingOutVO;
import org.phoenixctms.ctsms.vo.InventoryOutVO;
import org.phoenixctms.ctsms.vo.PSFVO;
import org.phoenixctms.ctsms.vo.ProbandOutVO;
import org.phoenixctms.ctsms.vo.StaffOutVO;
import org.phoenixctms.ctsms.vo.TrialOutVO;
import org.phoenixctms.ctsms.vo.UserOutVO;

/**
 * @see InventoryBooking
 */
public class InventoryBookingDaoImpl
extends InventoryBookingDaoBase
{

	private static void applyIncludeAppointmentsCriterion(Criteria bookingCriteria,Boolean isAppointment,String idProperty,Boolean isRelevantForAppointments,String relevantForAppointmentsProperty) {
		if (isAppointment != null) {
			if (isAppointment) {
				bookingCriteria.add(Restrictions.isNotNull(idProperty));
			} else {
				bookingCriteria.add(Restrictions.isNull(idProperty));
			}
		}
		if (isRelevantForAppointments != null) {
			bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN).createCriteria("category", CriteriaSpecification.INNER_JOIN)
			.add(Restrictions.eq(relevantForAppointmentsProperty, isRelevantForAppointments.booleanValue()));
		}
	}

	private void applyCourseIntervalCriterion(Criteria bookingCriteria, Long courseId, Timestamp from, Timestamp to, Boolean isRelevantForCourseAppointments) {
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);
		if (courseId != null) {
			bookingCriteria.add(Restrictions.eq("course.id", courseId.longValue()));
		}
		if (isRelevantForCourseAppointments != null) {
			bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN).createCriteria("category", CriteriaSpecification.INNER_JOIN)
			.add(Restrictions.eq("relevantForCourseAppointments", isRelevantForCourseAppointments.booleanValue()));
		}
	}

	private org.hibernate.Criteria createBookingCriteria() {
		org.hibernate.Criteria bookingCriteria = this.getSession().createCriteria(InventoryBooking.class);
		return bookingCriteria;
	}

	@Override
	protected Collection<InventoryBooking> handleFindByAppointmentDepartmentsCalendarInterval(Long probandDepartmentId, Long courseDepartmentId, Long trialDepartmentId,
			String calendar, Timestamp from, Timestamp to,
			Boolean isProbandAppointment, Boolean isRelevantForProbandAppointments,
			Boolean isCourseAppointment, Boolean isRelevantForCourseAppointments,
			Boolean isTrialAppointment, Boolean isRelevantForTrialAppointments) throws Exception
			{
		Criteria bookingCriteria = createBookingCriteria();
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);

		if (probandDepartmentId != null) {
			bookingCriteria.createCriteria("proband", CriteriaSpecification.LEFT_JOIN).add(
					Restrictions.or(Restrictions.isNull("department.id"), Restrictions.eq("department.id", probandDepartmentId.longValue())));
		}
		if (courseDepartmentId != null) {
			bookingCriteria.createCriteria("course", CriteriaSpecification.LEFT_JOIN).add(
					Restrictions.or(Restrictions.isNull("department.id"), Restrictions.eq("department.id", courseDepartmentId.longValue())));
		}
		if (trialDepartmentId != null) {
			bookingCriteria.createCriteria("trial", CriteriaSpecification.LEFT_JOIN).add(
					Restrictions.or(Restrictions.isNull("department.id"), Restrictions.eq("department.id", trialDepartmentId.longValue())));
		}
		applyIncludeAppointmentsCriterion(bookingCriteria,isProbandAppointment,"proband.id",isRelevantForProbandAppointments,"relevantForProbandAppointments");
		applyIncludeAppointmentsCriterion(bookingCriteria,isCourseAppointment,"course.id",isRelevantForCourseAppointments,"relevantForCourseAppointments");
		applyIncludeAppointmentsCriterion(bookingCriteria,isTrialAppointment,"trial.id",isRelevantForTrialAppointments,"relevantForTrialAppointments");

		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendar, "calendar", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		bookingCriteria.addOrder(Order.asc("start"));
		return bookingCriteria.list();
			}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByCourse(Long courseId, PSFVO psf) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		SubCriteriaMap criteriaMap = new SubCriteriaMap(InventoryBooking.class, bookingCriteria);
		if (courseId != null) {
			bookingCriteria.add(Restrictions.eq("course.id", courseId.longValue()));
		}
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return bookingCriteria.list();
	}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByCourseCalendarInterval(Long courseId, String calendar, Timestamp from, Timestamp to, Boolean isRelevantForCourseAppointments)
			throws Exception
			{
		Criteria bookingCriteria = createBookingCriteria();
		applyCourseIntervalCriterion(bookingCriteria, courseId, from, to, isRelevantForCourseAppointments);
		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendar, "calendar", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		return bookingCriteria.list();
			}

	@Override
	protected Collection<InventoryBooking> handleFindByCourseParticipantDepartmentCategoryInterval(
			Long staffId, Long courseDepartmentId, Long courseCategoryId, Timestamp from, Timestamp to, Boolean isRelevantForCourseAppointments)
					throws Exception {
		Criteria bookingCriteria = createBookingCriteria();
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);
		boolean distinctRoot = false;
		Criteria courseCriteria = null;
		if (courseCategoryId != null || courseDepartmentId != null || staffId != null) {
			courseCriteria = bookingCriteria.createCriteria("course", CriteriaSpecification.INNER_JOIN);
			if (courseDepartmentId != null) {
				courseCriteria.add(Restrictions.eq("department.id", courseDepartmentId.longValue()));
			}
			if (courseCategoryId != null) {
				courseCriteria.add(Restrictions.eq("category.id", courseCategoryId.longValue()));
			}
			if (staffId != null) {
				Criteria participationCriteria = courseCriteria.createCriteria("participations", CriteriaSpecification.LEFT_JOIN);
				participationCriteria.add(Restrictions.eq("staff.id", staffId.longValue()));
				// bookingCriteria.setResultTransformer(org.hibernate.Criteria.DISTINCT_ROOT_ENTITY);
				distinctRoot = true;
			}
		} else {
			bookingCriteria.add(Restrictions.isNotNull("course"));
		}
		if (isRelevantForCourseAppointments != null) {
			bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN).createCriteria("category", CriteriaSpecification.INNER_JOIN)
			.add(Restrictions.eq("relevantForCourseAppointments", isRelevantForCourseAppointments.booleanValue()));
		}
		if (distinctRoot) {
			return CriteriaUtil.listDistinctRoot(bookingCriteria, this);
		} else {
			return bookingCriteria.list();
		}
	}

	@Override
	protected Collection<InventoryBooking> handleFindByCourseSorted(Long courseId, Boolean isRelevantForCourseAppointments, boolean sort) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		if (courseId != null) {
			bookingCriteria.add(Restrictions.eq("course.id", courseId.longValue()));
		}
		if (isRelevantForCourseAppointments != null) {
			bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN).createCriteria("category", CriteriaSpecification.INNER_JOIN)
			.add(Restrictions.eq("relevantForCourseAppointments", isRelevantForCourseAppointments.booleanValue()));
		}
		if (sort) {
			bookingCriteria.addOrder(Order.asc("start"));
		}
		return bookingCriteria.list();
	}

	@Override
	protected Collection<InventoryBooking> handleFindByDepartmentCategoryInventoryOnBehalfOfProbandCourseTrialCalendarInterval(
			Long departmentId, Long inventoryCategoryId, Long inventoryId, Long onBehalfOfId, Long probandId, Long courseId, Long trialId, String calendar, Timestamp from,
			Timestamp to)
					throws Exception {
		Criteria bookingCriteria = createBookingCriteria();
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);
		if (departmentId != null || inventoryCategoryId != null) {
			Criteria inventoryCriteria = bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN);
			if (departmentId != null) {
				inventoryCriteria.add(Restrictions.eq("department.id", departmentId.longValue()));
			}
			if (inventoryCategoryId != null) {
				inventoryCriteria.add(Restrictions.eq("category.id", inventoryCategoryId.longValue()));
			}
		}
		if (inventoryId != null) {
			bookingCriteria.add(Restrictions.eq("inventory.id", inventoryId.longValue()));
		}
		if (onBehalfOfId != null) {
			bookingCriteria.add(Restrictions.eq("onBehalfOf.id", onBehalfOfId.longValue()));
		}
		if (probandId != null) {
			bookingCriteria.add(Restrictions.eq("proband.id", probandId.longValue()));
		}
		if (courseId != null) {
			bookingCriteria.add(Restrictions.eq("course.id", courseId.longValue()));
		}
		if (trialId != null) {
			bookingCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		}
		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendar, "calendar", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		return bookingCriteria.list();
	}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByInventory(Long inventoryId, PSFVO psf) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		SubCriteriaMap criteriaMap = new SubCriteriaMap(InventoryBooking.class, bookingCriteria);
		if (inventoryId != null) {
			bookingCriteria.add(Restrictions.eq("inventory.id", inventoryId.longValue()));
		}
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return bookingCriteria.list();
	}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByInventoryCalendarInterval(Long inventoryId, String calendar, Timestamp from, Timestamp to) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);
		if (inventoryId != null) {
			bookingCriteria.add(Restrictions.eq("inventory.id", inventoryId.longValue()));
		}
		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendar, "calendar", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		return bookingCriteria.list();
	}

	@Override
	protected Collection<InventoryBooking> handleFindByOnBehalfOf(
			Long staffId, PSFVO psf) throws Exception {
		Criteria bookingCriteria = createBookingCriteria();
		SubCriteriaMap criteriaMap = new SubCriteriaMap(InventoryBooking.class, bookingCriteria);
		if (staffId != null) {
			bookingCriteria.add(Restrictions.eq("onBehalfOf.id", staffId.longValue()));
		}
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return bookingCriteria.list();
	}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByProband(Long probandId, PSFVO psf) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		SubCriteriaMap criteriaMap = new SubCriteriaMap(InventoryBooking.class, bookingCriteria);
		if (probandId != null) {
			bookingCriteria.add(Restrictions.eq("proband.id", probandId.longValue()));
		}
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return bookingCriteria.list();
	}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByProbandCalendarInterval(Long probandId, String calendar, Timestamp from, Timestamp to,
			Boolean isRelevantForProbandAppointments) throws Exception
			{
		Criteria bookingCriteria = createBookingCriteria();
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);
		if (probandId != null) {
			bookingCriteria.add(Restrictions.eq("proband.id", probandId.longValue()));
		}
		if (isRelevantForProbandAppointments != null) {
			bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN).createCriteria("category", CriteriaSpecification.INNER_JOIN)
			.add(Restrictions.eq("relevantForProbandAppointments", isRelevantForProbandAppointments.booleanValue()));
		}
		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendar, "calendar", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		return bookingCriteria.list();
			}

	/**
	 * @inheritDoc
	 */
	@Override
	protected Collection<InventoryBooking> handleFindByTrial(Long trialId, PSFVO psf) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		SubCriteriaMap criteriaMap = new SubCriteriaMap(InventoryBooking.class, bookingCriteria);
		if (trialId != null) {
			bookingCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		}
		CriteriaUtil.applyPSFVO(criteriaMap, psf);
		return bookingCriteria.list();
	}

	@Override
	protected Collection<InventoryBooking> handleFindByTrialCalendarInterval(
			Long trialId, String calendar, Timestamp from, Timestamp to,
			Boolean isRelevantForTrialAppointments) throws Exception {
		Criteria bookingCriteria = createBookingCriteria();
		CriteriaUtil.applyClosedIntervalCriterion(bookingCriteria, from, to, null);
		if (trialId != null) {
			bookingCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		}
		if (isRelevantForTrialAppointments != null) {
			bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN).createCriteria("category", CriteriaSpecification.INNER_JOIN)
			.add(Restrictions.eq("relevantForTrialAppointments", isRelevantForTrialAppointments.booleanValue()));
		}
		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendar, "calendar", MatchMode.EXACT, EmptyPrefixModes.ALL_ROWS));
		return bookingCriteria.list();
	}

	@Override
	protected Collection<String> handleFindCalendars(
			Long inventoryDepartmentId, Long inventoryId, Long probandId, Long courseId,
			Long trialId, String calendarPrefix, Integer limit)
					throws Exception {
		Criteria bookingCriteria = createBookingCriteria();
		if (inventoryId != null) {
			bookingCriteria.add(Restrictions.eq("inventory.id", inventoryId.longValue()));
		}
		if (inventoryDepartmentId != null) {
			Criteria inventoryCriteria = bookingCriteria.createCriteria("inventory", CriteriaSpecification.INNER_JOIN);
			inventoryCriteria.add(Restrictions.eq("department.id", inventoryDepartmentId.longValue()));
		}
		if (probandId != null) {
			bookingCriteria.add(Restrictions.eq("proband.id", probandId.longValue()));
		}
		if (courseId != null) {
			bookingCriteria.add(Restrictions.eq("course.id", courseId.longValue()));
		}
		if (trialId != null) {
			bookingCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		}
		CategoryCriterion.apply(bookingCriteria, new CategoryCriterion(calendarPrefix, "calendar", MatchMode.START));
		bookingCriteria.addOrder(Order.asc("calendar"));
		bookingCriteria.setProjection(Projections.distinct(Projections.property("calendar")));
		CriteriaUtil.applyLimit(limit, Settings.getIntNullable(SettingCodes.INVENTORY_BOOKING_CALENDAR_AUTOCOMPLETE_DEFAULT_RESULT_LIMIT, Bundle.SETTINGS,
				DefaultSettings.INVENTORY_BOOKING_CALENDAR_AUTOCOMPLETE_DEFAULT_RESULT_LIMIT), bookingCriteria);
		return bookingCriteria.list();
	}

	@Override
	protected long handleGetCount(Long inventoryId, Long probandId, Long trialId,
			Long courseId, Long onBehalfOfId) throws Exception {
		Criteria bookingCriteria = createBookingCriteria();
		if (inventoryId != null) {
			bookingCriteria.add(Restrictions.eq("inventory.id", inventoryId.longValue()));
		}
		if (probandId != null) {
			bookingCriteria.add(Restrictions.eq("proband.id", probandId.longValue()));
		}
		if (trialId != null) {
			bookingCriteria.add(Restrictions.eq("trial.id", trialId.longValue()));
		}
		if (courseId != null) {
			bookingCriteria.add(Restrictions.eq("course.id", courseId.longValue()));
		}
		if (onBehalfOfId != null) {
			bookingCriteria.add(Restrictions.eq("onBehalfOf.id", onBehalfOfId.longValue()));
		}
		return (Long) bookingCriteria.setProjection(Projections.rowCount()).uniqueResult();
	}

	@Override
	protected long handleGetCourseIntervalCount(Long courseId, Timestamp from, Timestamp to, Boolean isRelevantForCourseAppointments) throws Exception
	{
		Criteria bookingCriteria = createBookingCriteria();
		applyCourseIntervalCriterion(bookingCriteria, courseId, from, to, isRelevantForCourseAppointments);
		return (Long) bookingCriteria.setProjection(Projections.rowCount()).uniqueResult();
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public InventoryBooking inventoryBookingInVOToEntity(InventoryBookingInVO inventoryBookingInVO)
	{
		InventoryBooking entity = this.loadInventoryBookingFromInventoryBookingInVO(inventoryBookingInVO);
		this.inventoryBookingInVOToEntity(inventoryBookingInVO, entity, true);
		return entity;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void inventoryBookingInVOToEntity(
			InventoryBookingInVO source,
			InventoryBooking target,
			boolean copyIfNull)
	{
		super.inventoryBookingInVOToEntity(source, target, copyIfNull);
		Long inventoryId = source.getInventoryId();
		Long onBehalfOfId = source.getOnBehalfOfId();
		Long courseId = source.getCourseId();
		Long probandId = source.getProbandId();
		Long trialId = source.getTrialId();
		if (inventoryId != null) {
			Inventory inventory = this.getInventoryDao().load(inventoryId);
			target.setInventory(inventory);
			inventory.addBookings(target);
		} else if (copyIfNull) {
			Inventory inventory = target.getInventory();
			target.setInventory(null);
			if (inventory != null) {
				inventory.removeBookings(target);
			}
		}
		if (onBehalfOfId != null) {
			Staff onBehalfOf = this.getStaffDao().load(onBehalfOfId);
			target.setOnBehalfOf(onBehalfOf);
			onBehalfOf.addInventoryBookings(target);
		} else if (copyIfNull) {
			Staff onBehalfOf = target.getOnBehalfOf();
			target.setOnBehalfOf(null);
			if (onBehalfOf != null) {
				onBehalfOf.removeInventoryBookings(target);
			}
		}
		if (courseId != null) {
			Course course = this.getCourseDao().load(courseId);
			target.setCourse(course);
			course.addInventoryBookings(target);
		} else if (copyIfNull) {
			Course course = target.getCourse();
			target.setCourse(null);
			if (course != null) {
				course.removeInventoryBookings(target);
			}
		}
		if (probandId != null) {
			Proband proband = this.getProbandDao().load(probandId);
			target.setProband(proband);
			proband.addInventoryBookings(target);
		} else if (copyIfNull) {
			Proband proband = target.getProband();
			target.setProband(null);
			if (proband != null) {
				proband.removeInventoryBookings(target);
			}
		}
		if (trialId != null) {
			Trial trial = this.getTrialDao().load(trialId);
			target.setTrial(trial);
			trial.addInventoryBookings(target);
		} else if (copyIfNull) {
			Trial trial = target.getTrial();
			target.setTrial(null);
			if (trial != null) {
				trial.removeInventoryBookings(target);
			}
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public InventoryBooking inventoryBookingOutVOToEntity(InventoryBookingOutVO inventoryBookingOutVO)
	{
		InventoryBooking entity = this.loadInventoryBookingFromInventoryBookingOutVO(inventoryBookingOutVO);
		this.inventoryBookingOutVOToEntity(inventoryBookingOutVO, entity, true);
		return entity;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void inventoryBookingOutVOToEntity(
			InventoryBookingOutVO source,
			InventoryBooking target,
			boolean copyIfNull)
	{
		super.inventoryBookingOutVOToEntity(source, target, copyIfNull);
		InventoryOutVO inventoryVO = source.getInventory();
		StaffOutVO onBehalfOfVO = source.getOnBehalfOf();
		CourseOutVO courseVO = source.getCourse();
		ProbandOutVO probandVO = source.getProband();
		TrialOutVO trialVO = source.getTrial();
		UserOutVO modifiedUserVO = source.getModifiedUser();
		if (inventoryVO != null) {
			Inventory inventory = this.getInventoryDao().inventoryOutVOToEntity(inventoryVO);
			target.setInventory(inventory);
			inventory.addBookings(target);
		} else if (copyIfNull) {
			Inventory inventory = target.getInventory();
			target.setInventory(null);
			if (inventory != null) {
				inventory.removeBookings(target);
			}
		}
		if (onBehalfOfVO != null) {
			Staff onBehalfOf = this.getStaffDao().staffOutVOToEntity(onBehalfOfVO);
			target.setOnBehalfOf(onBehalfOf);
			onBehalfOf.addInventoryBookings(target);
		} else if (copyIfNull) {
			Staff onBehalfOf = target.getOnBehalfOf();
			target.setOnBehalfOf(null);
			if (onBehalfOf != null) {
				onBehalfOf.removeInventoryBookings(target);
			}
		}
		if (courseVO != null) {
			Course course = this.getCourseDao().courseOutVOToEntity(courseVO);
			target.setCourse(course);
			course.addInventoryBookings(target);
		} else if (copyIfNull) {
			Course course = target.getCourse();
			target.setCourse(null);
			if (course != null) {
				course.removeInventoryBookings(target);
			}
		}
		if (probandVO != null) {
			Proband proband = this.getProbandDao().probandOutVOToEntity(probandVO);
			target.setProband(proband);
			proband.addInventoryBookings(target);
		} else if (copyIfNull) {
			Proband proband = target.getProband();
			target.setProband(null);
			if (proband != null) {
				proband.removeInventoryBookings(target);
			}
		}
		if (trialVO != null) {
			Trial trial = this.getTrialDao().trialOutVOToEntity(trialVO);
			target.setTrial(trial);
			trial.addInventoryBookings(target);
		} else if (copyIfNull) {
			Trial trial = target.getTrial();
			target.setTrial(null);
			if (trial != null) {
				trial.removeInventoryBookings(target);
			}
		}
		if (modifiedUserVO != null) {
			target.setModifiedUser(this.getUserDao().userOutVOToEntity(modifiedUserVO));
		} else if (copyIfNull) {
			target.setModifiedUser(null);
		}
	}

	/**
	 * Retrieves the entity object that is associated with the specified value object
	 * from the object store. If no such entity object exists in the object store,
	 * a new, blank entity is created
	 */
	private InventoryBooking loadInventoryBookingFromInventoryBookingInVO(InventoryBookingInVO inventoryBookingInVO)
	{
		InventoryBooking inventoryBooking = null;
		Long id = inventoryBookingInVO.getId();
		if (id != null) {
			inventoryBooking = this.load(id);
		}
		if (inventoryBooking == null)
		{
			inventoryBooking = InventoryBooking.Factory.newInstance();
		}
		return inventoryBooking;
	}

	/**
	 * Retrieves the entity object that is associated with the specified value object
	 * from the object store. If no such entity object exists in the object store,
	 * a new, blank entity is created
	 */
	private InventoryBooking loadInventoryBookingFromInventoryBookingOutVO(InventoryBookingOutVO inventoryBookingOutVO)
	{
		InventoryBooking inventoryBooking = this.load(inventoryBookingOutVO.getId());
		if (inventoryBooking == null)
		{
			inventoryBooking = InventoryBooking.Factory.newInstance();
		}
		return inventoryBooking;
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public InventoryBookingInVO toInventoryBookingInVO(final InventoryBooking entity)
	{
		return super.toInventoryBookingInVO(entity);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void toInventoryBookingInVO(
			InventoryBooking source,
			InventoryBookingInVO target)
	{
		super.toInventoryBookingInVO(source, target);
		Inventory inventory = source.getInventory();
		Staff onBehalfOf = source.getOnBehalfOf();
		Course course = source.getCourse();
		Proband proband = source.getProband();
		Trial trial = source.getTrial();
		if (inventory != null) {
			target.setInventoryId(inventory.getId());
		}
		if (onBehalfOf != null) {
			target.setOnBehalfOfId(onBehalfOf.getId());
		}
		if (course != null) {
			target.setCourseId(course.getId());
		}
		if (proband != null) {
			target.setProbandId(proband.getId());
		}
		if (trial != null) {
			target.setTrialId(trial.getId());
		}
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public InventoryBookingOutVO toInventoryBookingOutVO(final InventoryBooking entity)
	{
		return super.toInventoryBookingOutVO(entity);
	}

	/**
	 * @inheritDoc
	 */
	@Override
	public void toInventoryBookingOutVO(
			InventoryBooking source,
			InventoryBookingOutVO target)
	{
		super.toInventoryBookingOutVO(source, target);
		// WARNING! No conversion for target.user (can't convert source.getUser():org.phoenixctms.ctsms.domain.User to org.phoenixctms.ctsms.vo.UserOutVO
		// WARNING! No conversion for target.inventory (can't convert source.getInventory():org.phoenixctms.ctsms.domain.Inventory to org.phoenixctms.ctsms.vo.InventoryOutVO
		// WARNING! No conversion for target.course (can't convert source.getCourse():org.phoenixctms.ctsms.domain.Course to org.phoenixctms.ctsms.vo.CourseOutVO
		// WARNING! No conversion for target.trial (can't convert source.getTrial():org.phoenixctms.ctsms.domain.Trial to org.phoenixctms.ctsms.vo.TrialOutVO
		// WARNING! No conversion for target.proband (can't convert source.getProband():org.phoenixctms.ctsms.domain.Proband to org.phoenixctms.ctsms.vo.ProbandOutVO
		Inventory inventory = source.getInventory();
		Staff onBehalfOf = source.getOnBehalfOf();
		Course course = source.getCourse();
		Proband proband = source.getProband();
		Trial trial = source.getTrial();
		User modifiedUser = source.getModifiedUser();
		if (inventory != null) {
			target.setInventory(this.getInventoryDao().toInventoryOutVO(inventory));
		}
		if (onBehalfOf != null) {
			target.setOnBehalfOf(this.getStaffDao().toStaffOutVO(onBehalfOf));
		}
		if (course != null) {
			target.setCourse(this.getCourseDao().toCourseOutVO(course));
		}
		if (proband != null) {
			target.setProband(this.getProbandDao().toProbandOutVO(proband));
		}
		if (trial != null) {
			target.setTrial(this.getTrialDao().toTrialOutVO(trial));
		}
		if (modifiedUser != null) {
			target.setModifiedUser(this.getUserDao().toUserOutVO(modifiedUser));
		}
		BookingDuration bookingDuration = new BookingDuration();
		try {
			bookingDuration.add(target.getStart(), target.getStop(), null);
			bookingDuration.updateInventoryBooking(target);
		} catch (Exception e) {
		}
	}
}