ReaderBean.java 7.74 KB
package fi.codecrew.moya.beans;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.ejb.EJB;
import javax.ejb.EJBAccessException;
import javax.ejb.Stateless;

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

import fi.codecrew.moya.facade.CardCodeFacade;
import fi.codecrew.moya.facade.PrintedCardFacade;
import fi.codecrew.moya.facade.ReaderEventFacade;
import fi.codecrew.moya.facade.ReaderFacade;
import fi.codecrew.moya.model.AccountEvent;
import fi.codecrew.moya.model.CardCode;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.PrintedCard;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.model.Reader;
import fi.codecrew.moya.model.ReaderEvent;
import fi.codecrew.moya.model.ReaderEventType;
import fi.codecrew.moya.model.ReaderType;
import fi.codecrew.moya.model.User;

/**
 * Session Bean implementation class ReaderBean
 */
@Stateless
public class ReaderBean implements ReaderBeanLocal {

	@EJB
	private ReaderFacade readerfacade;

	@EJB
	private PrintedCardFacade cardfacade;

	@EJB
	private CardTemplateBeanLocal cardtemplatebean;
	@EJB
	private ReaderEventFacade readerEventFacade;
	@EJB
	private EventBeanLocal eventbean;
	@EJB
	private UserBeanLocal userbean;
	@EJB
	private CardTemplateBean cardTemplateBean;
	@EJB
	private ProductPBean productPBean;

	@EJB
	private CardCodeFacade cardCodeFacade;

	@EJB
	private BarcodeBeanLocal barcodeBean;

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

	@Override
	public ReaderEvent checkCode(String readerIdent, String code) {
		Reader reader = readerfacade.findOrCreateByIdent(readerIdent);
		return checkCode(reader, code);
	}

	@Override
	/** 
	 * check reader code, and add it to the database
	 */
	public ReaderEvent checkCode(Reader reader, String code) {

		if (reader == null || code == null || code.isEmpty()) {
			return null;
		}
		logger.info("got code from reader {}", code);

		code = code.replace("\"\b", "");

		if (ReaderType.RFID.equals(reader.getType())) {

			if (Pattern.matches("^.*000000$", code))
			{
				code = code.replace("000000", "");
			}
			StringBuilder sb = new StringBuilder(code);
			while (sb.length() < 16)
			{
				sb.insert(0, "0");
			}
			code = sb.toString();
		}

		ReaderEvent event = new ReaderEvent(new Date(), reader, code);

		// first, check if dublicate, there is 30s timeout for dublicates,
		// afther that it's ok to create dublicate
		// that's bcause accident dublicates are bad, but otherwise it's
		// probably bcause user want's to read it again
		List<ReaderEvent> lastevents = readerEventFacade.findLastEvents(reader, 1);

		if (!lastevents.isEmpty() && !reader.isAutoproduct())
		{
			ReaderEvent lastevent = lastevents.get(0);

			if (lastevent.getValue().equals(event.getValue()) && (lastevent.getUpdatetime().getTime() + 60000l) > event.getTime().getTime()) {

				lastevent = readerEventFacade.reload(lastevent);
				lastevent = readerEventFacade.merge(lastevent);

				return lastevent; // todo: update lastevent bfore return
			}
		}

		// find stuff with barcode and set type
		// IF we find 2 stuff with same barcode, it's just bad luck and things
		// may be little random.
		EventUser user = barcodeBean.getUser(code);

		if (user != null) {
			event.setType(ReaderEventType.USER);
			event.setUser(user);
		}

		PrintedCard card = barcodeBean.getPrintedCard(code);

		if (card != null) {
			event.setType(ReaderEventType.CARD);
			event.setPrintedCard(card);

			if (card.getUser() != null) {
				event.setUser(card.getUser());
			}
		}

		Product product = barcodeBean.getProduct(code);

		if (product != null) {
			event.setType(ReaderEventType.PRODUCT);
			event.setProduct(product);
		}

		Place place = barcodeBean.getPlaceFromBarcode(code);

		if (place != null) {
			event.setType(ReaderEventType.PLACE);
			event.setPlace(place);
		}

		event.setUpdatetime(new Date());

		// reader is in autoproduct-mode, create dat product
		if (reader.isAutoproduct()) {
			EventUser eu = userbean.getEventUser(card.getUser().getUser(), false);
			if (eu != null) {
				AccountEvent createAc = productPBean.createAccountEvent(reader.getAutomaticProduct(), reader.getAutomaticProductCount(), eu, Calendar.getInstance());
				readerfacade.flush();
				logger.info("Creating new accountevent from autoproduct {}", createAc);
				event.setNotes("Created automatic account event from reader. " + createAc);
			}
		}

		readerEventFacade.create(event);

		return event;

	}

	@Override
	public ReaderEvent assocCodeToCard(ReaderEvent readerEvent, PrintedCard card) {
		
		// you can select between this and flushCache.
		card = cardfacade.reload(card);


		CardCode code = new CardCode(card, readerEvent.getReader().getType(), readerEvent.getValue(), eventbean.getCurrentEvent());


		cardCodeFacade.create(code);
		

		card.getCardCodes().add(code);

		return readerEvent;
	}

	@Override
	public List<Reader> getReaders() {
		return readerfacade.findAllForEvent();
	}

	@Override
	public List<ReaderEvent> getReaderEvents(Integer readerId) {
		return getReaderEvents(readerId, 20);
	}

	@Override
	public List<ReaderEvent> getReaderEvents(Integer readerId, Integer count) {

		logger.info("Getting events for reader {}", readerId);
		Reader reader = readerfacade.find(readerId);
		return readerEventFacade.findLastEvents(reader, count);
	}

	@Override
	public ReaderEvent getLastReaderEvent(Integer readerId) {
		Reader reader = readerfacade.find(readerId);

		List<ReaderEvent> list = readerEventFacade.findLastEvents(reader, 1);

		if (list.size() > 0)
			return list.get(0);

		return null;
	}

	@Override
	public ReaderEvent getEvent(Integer eventid) {
		ReaderEvent ret = readerEventFacade.find(eventid);
		if (!ret.getReader().getEvent().equals(eventbean.getCurrentEvent()))
		{
			ret = null;
		}
		return ret;
	}

	@Override
	public User findTagFromAnyEvent(String value) {
		PrintedCard card = cardfacade.findLatestByCodeFromAny(value);
		User ret = null;
		if (card != null && card.getUser() != null) {
			ret = card.getUser().getUser();
		}

		return ret;
	}

	// ok, let's comment this out, so I can see where this is used
	/*
	 * @Override public ReaderEvent createCard(ReaderEvent event, EventUser
	 * user) { ReaderEvent ret = null;
	 * logger.info("Trying to create card for event {} with printed card {}",
	 * event, event.getPrintedCard());
	 * 
	 * if (event.getPrintedCard() == null) { CardTemplate ct =
	 * cardTemplateBean.getUsersCardtype(user); logger.info("Card template {}",
	 * ct); if (ct == null) { return null; } PrintedCard card = new
	 * PrintedCard(user, ct, null, true); card.setRfidUid(event.getValue());
	 * cardfacade.create(card);
	 * 
	 * ret = new ReaderEvent(Calendar.getInstance(), card, event.getReader());
	 * card.getReaderEvents().add(event);
	 * ret.setNotes("User associated to a card");
	 * 
	 * } return ret; }
	 */

	@Override
	public Reader getReader(Integer readerid) {
		return readerfacade.findReader(readerid);
	}

	@Override
	public Reader saveReader(Reader reader) {
		if (!eventbean.getCurrentEvent().equals(reader.getEvent())) {
			throw new EJBAccessException("Trying to save reader from wrong event");
		}
		return readerfacade.merge(reader);
	}

	@Override
	public void createReader(Reader reader) {
		reader.setEvent(eventbean.getCurrentEvent());
		readerfacade.create(reader);

	}

	@Override
	public List<ReaderEvent> getLastReaderEvents() {
		List<ReaderEvent> ret = new ArrayList<>();
		for (Reader r : readerfacade.findAllForEvent())
		{
			ret.addAll(readerEventFacade.findLastEvents(r, 1));
		}
		return ret;
	}

	@Override
	public List<ReaderEvent> getReaderEventsAfterEvent(Integer readerId, Integer eventId) {
		Reader reader = getReader(readerId);
		return readerEventFacade.findEventsAfterEvent(reader, eventId);
	}
}