PlaceFacade.java 8.68 KB
/*
 * Copyright Codecrew Ry
 * 
 * All rights reserved.
 * 
 * This license applies to any software containing a notice placed by the 
 * copyright holder. Such software is herein referred to as the Software. 
 * This license covers modification, distribution and use of the Software. 
 * 
 * Any distribution and use in source and binary forms, with or without 
 * modification is not permitted without explicit written permission from the 
 * copyright owner. 
 * 
 * A non-exclusive royalty-free right is granted to the copyright owner of the 
 * Software to use, modify and distribute all modifications to the Software in 
 * future versions of the Software. 
 * 
 */
package fi.codecrew.moya.facade;

import java.util.Arrays;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;

import fi.codecrew.moya.beans.EventBean;
import fi.codecrew.moya.model.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fi.codecrew.moya.beans.LoggingBeanLocal;

@Stateless
@LocalBean
public class PlaceFacade extends IntegerPkGenericFacade<Place> {

	private static final Logger logger = LoggerFactory.getLogger(PlaceFacade.class);

	@EJB
	private EventBean eventBean;

	@EJB
	private PlaceSlotFacade placeslotfacade;

	@EJB
	private LoggingBeanLocal logbean;

	public PlaceFacade() {

		super(Place.class);
	}

	public EventMap deletePlaces(EventMap map, String nameLike) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaDelete<Place> del = cb.createCriteriaDelete(Place.class);
		Root<Place> root = del.getRoot();
		del.where(
			cb.equal(root.get(Place_.map), map),
			cb.like(root.get(Place_.name), nameLike)
		);
		int i = getEm().createQuery(del).executeUpdate();

		logger.info("Deleted {} places from {} with string '{}'", i, map, nameLike);
		getEm().getEntityManagerFactory().getCache().evict(EventMap.class, map.getId());
		getEm().refresh(map);
		return map;
	}

	public List<Place> findUsersReservations(LanEvent event, EventUser user) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Place> cq = cb.createQuery(Place.class);
		Root<Place> root = cq.from(Place.class);

		cq.select(root);
		cq.where(
			cb.and(
				cb.equal(root.get(Place_.map).get(EventMap_.event), event),
				cb.equal(root.get(Place_.currentUser), user)
			));
		TypedQuery<Place> q = getEm().createQuery(cq);

		return q.getResultList();
	}

	public List<Place> findUsersUnlocketSelected(EventUser user) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Place> cq = cb.createQuery(Place.class);

		Root<Place> root = cq.from(Place.class);

		cq.select(root);
		cq.where(
			cb.and(
				cb.equal(root.get(Place_.map).get(EventMap_.event), user.getEvent()),
				cb.equal(root.get(Place_.currentUser), user),
				cb.isNull(root.get(Place_.group))
			));
		TypedQuery<Place> q = getEm().createQuery(cq);

		return q.getResultList();
	}

	public int setBuyable(EventMap map, String like, boolean b) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Place> cq = cb.createQuery(Place.class);
		Root<Place> root = cq.from(Place.class);
		cq.where(
			cb.like(root.get(Place_.name), like),
			cb.equal(root.get(Place_.map), map)
		);

		List<Place> list = getEm().createQuery(cq).getResultList();
		for (Place p : list) {
			p.setBuyable(b);
		}

		// Query q =
		// em.createQuery("UPDATE Place p set p.buyable = :b where p.name like :like");
		// q.setParameter("b", b);
		// q.setParameter("like", like);
		return list.size();

	}

	// public boolean isCoordinateInPlace(int x, int y) {
	// if (x > mapX
	// && x < (mapX + width)
	// && y > mapY
	// && y < (mapY + height)) {
	// return true;
	// }
	//
	// return false;
	// }
	public Place find(EventMap map, int x, int y) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Place> cq = cb.createQuery(Place.class);
		Root<Place> root = cq.from(Place.class);
		Path<Integer> xObj = root.get(Place_.mapX);
		Path<Integer> yObj = root.get(Place_.mapY);

		cq.where(cb.equal(root.get(Place_.map), map),
			cb.lessThan(xObj, x),
			cb.greaterThan(cb.sum(xObj, root.get(Place_.width)), x),
			cb.lessThan(yObj, y),
			cb.greaterThan(cb.sum(yObj, root.get(Place_.height)), y),
			cb.isFalse(root.get(Place_.disabled))
		);
		return getSingleNullableResult(getEm().createQuery(cq));
	}

	public List<Place> findAll(LanEvent event) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Place> cq = cb.createQuery(Place.class);
		Root<Place> root = cq.from(Place.class);

		Path<EventMap> map = root.get(Place_.map);
		cq.where(
			cb.isTrue(map.get(EventMap_.active)),
			cb.equal(map.get(EventMap_.event), event)
		);
		cq.orderBy(cb.asc(root.get(Place_.name)));
		return getEm().createQuery(cq).getResultList();
	}

	public Long countSelectable(Product product) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
		Root<Place> root = cq.from(Place.class);
		cq.select(cb.count(root));

		cq.where(
			cb.equal(root.get(Place_.product), product),
			cb.isNull(root.get(Place_.reserveTime)),
			cb.isNull(root.get(Place_.group)),
			cb.isFalse(root.get(Place_.disabled)),
			cb.isTrue(root.get(Place_.buyable)),
			cb.isTrue(root.get(Place_.map).get(EventMap_.active))
		);
		return super.getSingleNullableResult(getEm().createQuery(cq));
	}

	public Long findCountForProduct(Product product) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Long> cq = cb.createQuery(Long.class);
		Root<Place> root = cq.from(Place.class);
		cq.select(cb.count(root));

		cq.where(
			cb.equal(root.get(Place_.product), product),
			cb.isFalse(root.get(Place_.disabled)),
			cb.isTrue(root.get(Place_.map).get(EventMap_.active))
		);
		return super.getSingleNullableResult(getEm().createQuery(cq));
	}

	public Long countAvailable(EventMap map) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Long> cq = cb.createQuery(Long.class);

		Root<Place> root = cq.from(Place.class);

		cq.select(cb.count(root));

		cq.where(
			cb.equal(root.get(Place_.map), map),
			cb.isFalse(root.get(Place_.disabled)),

			// TKwtf lisäsi:
			cb.isTrue(root.get(Place_.buyable))
		);

		return getSingleNullableResult(getEm().createQuery(cq));

	}

	public Long countSelectable(EventMap map) {

		if (map == null) {
			return null;
		}

		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Long> cq = cb.createQuery(Long.class);

		Root<Place> root = cq.from(Place.class);

		cq.select(cb.count(root));

		cq.where(
			cb.equal(root.get(Place_.map), map),
			cb.isNull(root.get(Place_.reserveTime)),
			cb.isNull(root.get(Place_.group)),
			cb.isFalse(root.get(Place_.disabled)),
			// TKwtf lisäsi:
			cb.isTrue(root.get(Place_.buyable))

		);

		return getSingleNullableResult(getEm().createQuery(cq));
	}

	public List<Product> getMapProducts(EventMap map) {

		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Product> cq = cb.createQuery(Product.class);

		Root<Product> root = cq.from(Product.class);
		Subquery<Integer> subq = cq.subquery(Integer.class);
		Root<Place> subroot = subq.from(Place.class);
		subq.select(subroot.get(Place_.product).get(Product_.id));
		subq.distinct(true);
		subq.where(cb.equal(subroot.get(Place_.map), map));

		cq.where(root.get(Product_.id).in(subq));

		return getEm().createQuery(cq).getResultList();
	}

	public List<Product> getPlaceProducts() {

		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Product> cq = cb.createQuery(Product.class);
		Root<Product> root = cq.from(Product.class);

		Subquery<Integer> subq = cq.subquery(Integer.class);

		Root<Product> subroot = subq.from(Product.class);
		subq.select(subroot.get(Product_.id));
		subq.distinct(true);

		Join<Product, Place> placeJoin = subroot.join(Product_.places);

		subq.where(
			placeJoin.get(Place_.id).isNotNull(),
			cb.equal(placeJoin.get(Place_.map).get(EventMap_.event), eventBean.getCurrentEvent())
		);

		ProductFlag[] flags = {ProductFlag.CREATE_NEW_PLACE_WHEN_BOUGHT};

		cq.where(
			cb.or(
				root.get(Product_.id).in(subq),
				root.get(Product_.productFlags).in(Arrays.asList(flags))
			),
			cb.equal(root.get(Product_.event), eventBean.getCurrentEvent())
		);

		cq.orderBy(cb.asc(root.get(Product_.name)));

		return getEm().createQuery(cq).getResultList();
	}

	public Place findByCode(String code, LanEvent event) {
		CriteriaBuilder cb = getEm().getCriteriaBuilder();
		CriteriaQuery<Place> cq = cb.createQuery(Place.class);
		Root<Place> root = cq.from(Place.class);

		cq.where(
			cb.equal(root.get(Place_.product).get(Product_.event), event),
			cb.equal(root.get(Place_.code), code)
		);
		return super.getSingleNullableResult(getEm().createQuery(cq));
	}


}