Commit 82dfb3fd by Tuomas Riihimäki

Place selection with neomap

1 parent 380c6c51
......@@ -23,6 +23,7 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.annotation.security.DeclareRoles;
......@@ -49,6 +50,7 @@ import fi.codecrew.moya.exceptions.BillExceptionNotEnoughtCredits;
import fi.codecrew.moya.facade.BillFacade;
import fi.codecrew.moya.facade.BillLineFacade;
import fi.codecrew.moya.facade.EventUserFacade;
import fi.codecrew.moya.facade.PlaceSlotFacade;
import fi.codecrew.moya.model.AccountEvent;
import fi.codecrew.moya.model.Bill;
import fi.codecrew.moya.model.BillLine;
......@@ -56,8 +58,10 @@ import fi.codecrew.moya.model.Discount;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.FoodWave;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.PlaceSlot;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.model.ProductFlag;
import fi.codecrew.moya.utilities.jpa.GenericFacade;
import fi.codecrew.moya.utilities.moyamessage.MoyaEventType;
/**
......@@ -102,6 +106,8 @@ public class BillBean implements BillBeanLocal {
private LoggingBeanLocal logbean;
@EJB
private BillPBean billpbean;
@EJB
private PlaceSlotFacade psFacade;
/**
* Default constructor.
......@@ -259,9 +265,37 @@ public class BillBean implements BillBeanLocal {
}
billFacade.create(bill);
generateBillNumber(bill);
createPlaceslots(bill);
return bill;
}
/**
* Create place slots for the bill
*
* @param bill
*/
private void createPlaceslots(Bill bill) {
for (BillLine bl : bill.getBillLines()) {
if (bl == null)
return;
Product prod = bl.getLineProduct();
if (prod == null || prod.getPlaces() == null || prod.getPlaces().isEmpty()) {
// Not a place product.
return;
}
int count = bl.getQuantity().intValue();
Date now = new Date();
for (int i = 0; i < count; ++i)
{
PlaceSlot ps = new PlaceSlot();
ps.setBill(bill);
ps.setCreated(now);
ps.setProduct(prod);
psFacade.create(ps);
}
}
}
@RolesAllowed({ BillPermission.S_WRITE_ALL })
public Bill save(Bill bill) {
return billFacade.merge(bill);
......
......@@ -25,6 +25,7 @@ package fi.codecrew.moya.beans;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
......@@ -230,8 +231,8 @@ public class PlaceBean implements PlaceBeanLocal {
@Override
@RolesAllowed(MapPermission.S_BUY_PLACES)
public boolean reservePlace(Place place, EventUser user) {
place = placeFacade.find(place.getId());
user = eventUserFacade.find(user.getId());
place = placeFacade.reload(place);
user = eventUserFacade.reload(user);
boolean ret = false;
// when admin click's place, he reserves it -> just ignore it
......@@ -239,13 +240,30 @@ public class PlaceBean implements PlaceBeanLocal {
if (place.isBuyable() || permbean.hasPermission(MapPermission.MANAGE_OTHERS)) {
if (place.getProduct().getProductFlags().contains(ProductFlag.PREPAID_CREDIT)) {
// TODO: We should check there is enough credits...
logger.warn("Reserving place {} with Prepaid credit!", place);
BigDecimal balance = user.getAccountBalance();
BigDecimal price = getTotalReservationPrice(user, place);
boolean canReserve = (price.compareTo(balance) <= 0);
logger.debug("Balance {}, price {}", balance, price);
if (!canReserve)
{
logger.debug("Did not have enought credits to reserve place! required {} , got {}", price, balance);
return false;
}
} else {
List<PlaceSlot> slots = placeSlotFacade.findFreePlaceSlots(user, place.getProduct());
logger.info("Found free slots {} for user {}", Arrays.asList(slots.toArray()), user);
if (slots != null && !slots.isEmpty()) {
PlaceSlot slot = slots.get(0);
logger.warn("Reserving place {} with placeslot {}", place, slot);
slot.setPlace(place);
slot.setUsed(new Date());
} else {
logger.warn("Not enough slots to reserve place {}", place);
// Not enough slots to reserve place
return false;
}
}
......
......@@ -12,7 +12,8 @@
<ui:composition template="#{sessionHandler.template}">
<f:metadata>
<f:event type="preRenderView" listener="#{ajaxMapView.initReserveMap()}" />
<f:event type="preRenderView"
listener="#{ajaxMapView.initReserveMap()}" />
</f:metadata>
<ui:define name="content">
<h:form>
......@@ -32,20 +33,29 @@
<h:outputScript target="head" library="seatjs" name="d3-tip.js" />
<h:outputScript target="head" library="seatjs" name="seatmap.js" />
<h:outputStylesheet library="seatjs" name="placemap.css" />
<svg id="seatmap" style="margin: auto; border: 1px solid black; background-image: url()"
width="#{ajaxMapView.map.width}px" height="#{ajaxMapView.map.height}px" />
<script type="text/javascript">
<h:form>
<h:commandButton rendered="#{mapView.canUserBuy()}"
value="#{i18n['mapView.buyPlaces']}"
action="#{placeView.buySelectedPlaces()}" />
</h:form>
<div>
<svg id="seatmap"
style="margin: auto; border: 1px solid black; background-image: url()"
width="#{ajaxMapView.map.width}px"
height="#{ajaxMapView.map.height}px" />
<script type="text/javascript">
px = placemap({
element : document.getElementById("seatmap"),
moyaurl : "#{request.contextPath}",
map_id : #{ajaxMapView.map.id},
onclick : function(d) {
placeClicker([{name: 'placeId', value: d}])
// placeClicker([{name: 'placeId', value: d}])
return false;
}
});
</script>
</div>
</ui:define>
</ui:composition>
</h:body>
......
......@@ -17,11 +17,11 @@
</f:metadata>
<ui:param name="thispage" value="page.place.placemap" />
<ui:define name="content">
<h:form>
<!-- <h:form>
<p:remoteCommand name="placeClicker" update=":fbdiag"
action="#{ajaxMapView.placeClicked()}" />
</h:form>
-->
<p:dialog rendered="#{ajaxMapView.isMgmtPermission()}"
visible="#{!empty ajaxMapView.place}" id="fbdiag">
Clicked place name : #{ajaxMapView.place.name};
......@@ -35,7 +35,13 @@
<h:outputScript target="head" library="seatjs" name="d3-tip.js" />
<h:outputScript target="head" library="seatjs" name="seatmap.js" />
<h:outputStylesheet library="seatjs" name="placemap.css" />
<button onclick="px.update()" >Update</button><br/>
<div style="margin: 5px;">
<h:form id="placeselectform">
<h:commandButton rendered="#{ajaxMapView.canUserBuy()}"
value="#{i18n['mapView.buyPlaces']}"
action="#{ajaxMapView.buySelectedPlaces()}" />
</h:form>
</div>
<svg id="seatmap" style="margin: auto; border: 1px solid black;"
width="#{ajaxMapView.map.width}px"
height="#{ajaxMapView.map.height}px" />
......@@ -57,6 +63,37 @@
// });
//px.enable_edit();
</script>
<h:panelGrid columns="3" cellpadding="10">
<h:panelGrid columns="2">
<div
style="border-color: black; border-style: solid; border-width: 1px; background-color: grey; width: 10px; height: 10px;">&nbsp;</div>
<h:outputText value="#{i18n['placeSelect.legend.grey']}" />
<div
style="border-color: black; border-style: solid; border-width: 1px; background-color: white; width: 10px; height: 10px;">&nbsp;</div>
<h:outputText value="#{i18n['placeSelect.legend.white']}" />
<div
style="border-color: black; border-style: solid; border-width: 1px; background-color: red; width: 10px; height: 10px;">&nbsp;</div>
<h:outputText value="#{i18n['placeSelect.legend.red']}" />
<div
style="border-color: black; border-style: solid; border-width: 1px; background-color: green; width: 10px; height: 10px;">&nbsp;</div>
<h:outputText value="#{i18n['placeSelect.legend.green']}" />
<div
style="border-color: black; border-style: solid; border-width: 1px; background-color: blue; width: 10px; height: 10px;">&nbsp;</div>
<h:outputText value="#{i18n['placeSelect.legend.blue']}" />
</h:panelGrid>
<h:panelGrid columnClasses=",rightalign" columns="2">
<h:outputLabel value="#{i18n['placeSelect.totalPlaces']}:" />
<h:outputText value="#{ajaxMapView.availablePlaces}" />
<h:outputLabel value="#{i18n['placeSelect.placesleft']}:" />
<h:outputText value="#{ajaxMapView.placesLeftToSelect}" />
</h:panelGrid>
</h:panelGrid>
</ui:define>
</ui:composition>
</h:body>
......
......@@ -108,7 +108,7 @@ public class PlacemapRestViewV1 {
@POST
@Path("/place/{place}")
public SimplePlacelistRoot togglePlaceReservation(@PathParam("place") Integer placeId)
public Response togglePlaceReservation(@PathParam("place") Integer placeId)
{
EventUser user = null;
if (userView != null) {
......@@ -116,16 +116,23 @@ public class PlacemapRestViewV1 {
}
Place p = placebean.find(placeId);
boolean success = false;
if (p.isReservedFor(user)) {
placebean.releasePlace(p);
success = placebean.releasePlace(p);
} else if (p.isBuyable() && !p.isTaken()) {
placebean.reservePlace(p, user);
logger.info("Rest Reserving place for place {}", p);
success = placebean.reservePlace(p, user);
}
p = placebean.find(placeId);
List<Place> thisplace = new ArrayList<Place>();
thisplace.add(p);
return SimplePlacelistRoot.wrap(thisplace, user);
logger.info("Returning rest success {}", success);
ResponseBuilder resp = null;
if (success) {
p = placebean.find(placeId);
List<Place> thisplace = new ArrayList<Place>();
thisplace.add(p);
resp = Response.ok(SimplePlacelistRoot.wrap(thisplace, user));
} else {
resp = Response.status(Response.Status.FORBIDDEN);
}
return resp.build();
}
}
......@@ -16,10 +16,13 @@ import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.PermissionBeanLocal;
import fi.codecrew.moya.beans.PlaceBeanLocal;
import fi.codecrew.moya.enums.apps.MapPermission;
import fi.codecrew.moya.exceptions.BortalCatchableException;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.web.cdiview.GenericCDIView;
import fi.codecrew.moya.web.cdiview.user.UserView;
@Named
@ConversationScoped
......@@ -47,6 +50,8 @@ public class AjaxMapView extends GenericCDIView {
private EventMap map;
private Place place;
private Integer mapId;
@Inject
private UserView userview;
public void initReserveMap() {
initMap();
......@@ -57,8 +62,8 @@ public class AjaxMapView extends GenericCDIView {
initMap();
}
private void initMap() {
if (mapId != null) {
private EventMap initMap() {
if (map == null && mapId != null) {
map = placebean.findMap(mapId);
}
if (map == null) {
......@@ -73,30 +78,60 @@ public class AjaxMapView extends GenericCDIView {
}
}
}
return map;
}
public boolean isMgmtPermission()
{
return permbean.hasPermission(MapPermission.MANAGE_OTHERS);
public Long getPlacesLeftToSelect() {
Long ret = placebean.selectablePlaceCount(initMap());
logger.debug("Got {} places left for map {}", ret, initMap());
return ret;
}
public Long getAvailablePlaces() {
Long ret = placebean.availablePlaceCount(initMap());
public void placeClicked()
{
// logger.debug("Got {} availbale places for map {}", ret, initMap());
return ret;
Map<String, String> vmap = context.getExternalContext().getRequestParameterMap();
int placeId = Integer.parseInt(vmap.get("placeId"));
place = placebean.find(placeId);
logger.info("Found place {} with placeid {}", place, placeId);
if (place.isReservedFor(permbean.getCurrentUser()))
{
placebean.releasePlace(place);
}
else if (place.isBuyable() && !place.isTaken())
{
placebean.reservePlace(place, permbean.getCurrentUser());
}
public boolean canUserBuy() {
return permbean.hasPermission(MapPermission.BUY_PLACES);
}
public String buySelectedPlaces() {
try {
EventUser user = userview.getSelectedUser();
placebean.buySelectedPlaces(user);
return "/place/myGroups";
} catch (BortalCatchableException e) {
addFaceMessage("mapView.errorWhileBuyingPlaces");
}
return null;
}
public boolean isMgmtPermission()
{
return permbean.hasPermission(MapPermission.MANAGE_OTHERS);
}
// public void placeClicked()
// {
//
// Map<String, String> vmap = context.getExternalContext().getRequestParameterMap();
// int placeId = Integer.parseInt(vmap.get("placeId"));
// place = placebean.find(placeId);
// logger.info("Found place {} with placeid {}", place, placeId);
// if (place.isReservedFor(permbean.getCurrentUser()))
// {
// placebean.releasePlace(place);
// }
// else if (place.isBuyable() && !place.isTaken())
// {
// placebean.reservePlace(place, permbean.getCurrentUser());
// }
// }
public String getTestVal() {
return testVal;
}
......@@ -123,7 +158,7 @@ public class AjaxMapView extends GenericCDIView {
public FacesContext getContext() {
return context;
}
}
public void setContext(FacesContext context) {
this.context = context;
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!