PlaceBean.java 5.8 KB
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.insomnia.bortal.beans;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import fi.insomnia.bortal.enums.Permission;
import fi.insomnia.bortal.enums.RolePermission;
import fi.insomnia.bortal.exceptions.BortalCatchableException;
import fi.insomnia.bortal.exceptions.PermissionDeniedException;
import fi.insomnia.bortal.facade.PlaceFacade;
import fi.insomnia.bortal.model.EventMap;
import fi.insomnia.bortal.model.Place;
import fi.insomnia.bortal.model.PlaceGroup;
import fi.insomnia.bortal.model.Product;
import fi.insomnia.bortal.model.User;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.persistence.RollbackException;

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


/**
 * 
 * @author tuukka
 */
@Stateless
public class PlaceBean implements PlaceBeanLocal {
    private static final String PLACE_RESERVE_TIMEOUTER = "Map reserve timeouter";
    private static final Logger logger = LoggerFactory.getLogger(PlaceBean.class);

    @Resource
    private TimerService ts;

    @EJB
    private PlaceFacade placeFacade;

    @EJB
    private UserBeanLocal userbean;

    @EJB
    private ProductBeanLocal productBean;

    @EJB
    private EventBeanLocal eventBean;

    @EJB
    private PlaceGroupBeanLocal pgbean;

    @EJB
    private SecurityBeanLocal secubean;
    @EJB
    private EventMapBeanLocal mapfacade;

    @Override
    public Place mergeChanges(Place place) {
        userbean.fatalPermission(Permission.TICKET_SALES, RolePermission.EXECUTE, "User tried to modify place ", place);
        return placeFacade.merge(place);
    }

    @Override
    public BigDecimal totalReservationPrice(EventMap e, Place newPlace) {

        Set<Place> places = new HashSet<Place>();
        places.addAll(placeFacade.findUsersReservations(e, userbean.getCurrentUser()));

        if (newPlace != null) {
            places.add(newPlace);
        }

        Map<Product, Integer> mockmap = getPlaceProductcount(places);

        BigDecimal total = BigDecimal.ZERO;

        for (Entry<Product, Integer> entry : mockmap.entrySet()) {
            logger.debug("Adding to price {} of {}", entry.getValue(), entry.getKey().getName());
            if (entry.getKey() != null) {
                total = total.add(productBean.calculateTotal(entry.getKey(), new BigDecimal(entry.getValue())));
            }
        }
        return total;
    }

    private static Map<Product, Integer> getPlaceProductcount(Collection<Place> places) {
        HashMap<Product, Integer> mockmap = new HashMap<Product, Integer>();

        for (Place p : places) {
            if (p != null) {
                Product prod = p.getProduct();
                Integer val = mockmap.get(prod);
                if (val == null) {
                    val = 0;
                }
                mockmap.put(prod, ++val);
            }
        }

        return mockmap;

    }

    //
    // @Override
    // public List<Place> findPlaces(List<Integer> placeIds) {
    //
    // return placeFacade.find(eventBean.getCurrentEvent(), placeIds);
    // }

    // TODO: Kantakysely tähän!
    @Override
    public Place findPlace(EventMap e, int x, int y) {
        for (Place place : e.getPlaces()) {
            if (place.isCoordinateInPlace(x, y)) {
                return place;
            }
        }

        return null;

    }

    @Override
    public boolean reservePlace(Place p, User user) {
        boolean ret = placeFacade.reservePlace(p, user);

        boolean foundTimeout = false;
        for (Timer t : ts.getTimers()) {
            if (t.getInfo().equals(PLACE_RESERVE_TIMEOUTER)) {
                foundTimeout = true;
            }
        }
        if (!foundTimeout) {
            logger.info("Place timeout calculator not started. Starting new.");
            ts.createTimer(new Date(), 1000 * 60, PLACE_RESERVE_TIMEOUTER);
        }
        return ret;
    }

    @Timeout
    public void checkTimedOutPlaces(Timer timer) {
        // logger.debug("Checking Timed out places at {}", new Date());
        placeFacade.timeoutPlaces();
    }

    @Override
    public void releaseUsersPlaces() {
        logger.debug("timeouting places");
        placeFacade.releasePlaces(userbean.getCurrentUser());
    }

    @Override
    public boolean releasePlace(Place place, User user) {
        return placeFacade.releasePlace(user, place);

    }

    @Override
    public boolean buySelectedPlaces(EventMap e) throws BortalCatchableException {
        User user = userbean.getCurrentUser();

        List<Place> places = placeFacade.findUsersReservations(e, user);
        if (places.size() <= 0) {
            return false;
        }
        PlaceGroup pg = pgbean.createPlaceGroup(user);
        BigDecimal totalprice = totalReservationPrice(e, null);
        BigDecimal balance = userbean.getCurrentUser().getAccountBalance();
        if (balance.compareTo(totalprice) < 0) {
            logger.debug("User {} Could not buy things because account balance is too low!", user);
            return false;
        }

        for (Place p : places) {
            if (!p.buy(pg)) {
                throw new BortalCatchableException("Error while buying places");
            }
            placeFacade.merge(p);
            pgbean.createGroupMembership(pg, p);
        }

        for (Entry<Product, Integer> line : getPlaceProductcount(places).entrySet()) {
            productBean.createAccountEvent(line.getKey(), new BigDecimal(line.getValue()), user);
        }
        return true;
    }

 

}