Commit 40b88c27 by Tuukka Kivilahti

Merge remote-tracking branch 'origin/master' into asm-placegive

2 parents 3bf5ff53 f59d43f5
......@@ -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);
......
......@@ -147,7 +147,7 @@ public class MenuBean implements MenuBeanLocal {
MenuNavigation userPlaces = usermenu.addPage(null, null);
userPlaces.setKey("topnavi.userplaces");
userPlaces.addPage(menuitemfacade.findOrCreate("/place/placemap"), MapPermission.VIEW);
userPlaces.addPage(menuitemfacade.findOrCreate("/neomap/view"), MapPermission.VIEW);
userPlaces.addPage(menuitemfacade.findOrCreate("/place/myGroups"), MapPermission.BUY_PLACES);
userPlaces.addPage(menuitemfacade.findOrCreate("/place/edit"), MapPermission.MANAGE_OTHERS).setVisible(false);
......
......@@ -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;
}
}
......
......@@ -108,9 +108,9 @@ public class ProductPBean {
List<Discount> discounts = new ArrayList<>();
if (overriddenUnitPrice != null && BigDecimal.ZERO.compareTo(overriddenUnitPrice) < 0) {
if (overriddenUnitPrice != null && BigDecimal.ZERO.compareTo(overriddenUnitPrice) <= 0) {
unitPrice = overriddenUnitPrice;
unitPrice = overriddenUnitPrice.negate();
lbean.sendMessage(MoyaEventType.ACCOUNTEVENT_INFO, permbean.getCurrentUser(), "User creating accountevent with discount");
// lbean.logMessage(SecurityLogType.accountEvent, permbean.getCurrentUser(), "User creating accountevent with discount");
} else {
......
......@@ -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;
......
......@@ -365,7 +365,11 @@ public class ProductShopView extends GenericCDIView {
for (ProductShopItem shopitem : shoppingcart) {
if (shopitem.getCount().compareTo(BigDecimal.ZERO) > 0) {
retuser = productBean.createAccountEvent(shopitem.getProduct(), shopitem.getCount(), shopitem.getOverriddenUnitPrice(), userView.getSelectedUser()).getUser();
// retuser = productBean.createAccountEvent(shopitem.getProduct(), shopitem.getCount(), shopitem.getOverriddenUnitPrice(), userView.getSelectedUser()).getUser();
BigDecimal overriddenPrice = (shopitem.isOverrideUnitPrice()) ? shopitem.getOverriddenUnitPrice() : null;
retuser = productBean.createAccountEvent(shopitem.getProduct(), shopitem.getCount(), overriddenPrice, userView.getSelectedUser()).getUser();
}
}
......
......@@ -46,7 +46,7 @@ public class ProductShopItemHelper extends GenericCDIView {
public void updateProductShopItemCount(ProductShopItem item) {
// Discounts or overridden price, you cannot get both
if(item.isPriceOverridden()) {
if(item.isOverrideUnitPrice()) {
item.setInternalPrice(item.getOverriddenUnitPrice().multiply(item.getCount()));
} else {
item.setInternalPrice(item.getProduct().getPrice().abs().multiply(item.getCount()));
......
......@@ -46,6 +46,7 @@ public class ProductShopItem {
private BigDecimal overriddenUnitPrice = BigDecimal.ZERO;
private boolean overrideUnitPrice = false;
......@@ -78,12 +79,10 @@ public class ProductShopItem {
/**
* Return products that
*
* @param findForStaffshop
* @return
*
*/
public static List<ProductShopItem> productGTList(List<Product> products, EventUser user) {
List<ProductShopItem> ret = new ArrayList<ProductShopItem>();
List<ProductShopItem> ret = new ArrayList<>();
for (Product prod : products) {
if (prod.getPrice().compareTo(BigDecimal.ZERO) >= 0) {
ret.add(new ProductShopItem(prod, user));
......@@ -94,7 +93,7 @@ public class ProductShopItem {
}
public static List<ProductShopItem> productList(List<Product> products, EventUser user) {
List<ProductShopItem> ret = new ArrayList<ProductShopItem>();
List<ProductShopItem> ret = new ArrayList<>();
for (Product prod : products) {
ret.add(new ProductShopItem(prod, user));
}
......@@ -124,7 +123,6 @@ public class ProductShopItem {
/**
* Price and discounts are only stored so we can show them to user, changing there does not change end price of card
* @param discounts
*/
public void setInternalPrice(BigDecimal price) {
this.price = price;
......@@ -195,8 +193,13 @@ public class ProductShopItem {
public BigDecimal getOverriddenUnitPrice() {
if(overriddenUnitPrice == null)
overriddenUnitPrice = BigDecimal.ZERO;
if(!isOverrideUnitPrice())
return getPrice().divide(getCount());
// isOverrideUnitPrice shout also check this, but just in case..
if(overriddenUnitPrice == null || overriddenUnitPrice.compareTo(BigDecimal.ZERO) < 0)
overriddenUnitPrice = getPrice().divide(getCount());
return overriddenUnitPrice;
}
......@@ -209,16 +212,35 @@ public class ProductShopItem {
* @param overrideUnitPrice
*/
public void setOverriddenUnitPrice(BigDecimal overrideUnitPrice) {
this.overriddenUnitPrice = overrideUnitPrice;
}
public boolean isPriceOverridden() {
return (getOverriddenUnitPrice() != null && getOverriddenUnitPrice().compareTo(BigDecimal.ZERO) > 0);
if(overrideUnitPrice != getPrice().divide(getCount())) {
setOverrideUnitPrice(true);
this.overriddenUnitPrice = overrideUnitPrice;
} else {
setOverrideUnitPrice(false);
this.overriddenUnitPrice = null;
}
}
public BigDecimal getUnitDiscount() {
return getPrice().divide(getCount()).subtract(getProduct().getPrice());
}
public boolean isOverrideUnitPrice() {
if(overrideUnitPrice && (overriddenUnitPrice == null || overriddenUnitPrice.compareTo(BigDecimal.ZERO) < 0)) {
return false;
}
return overrideUnitPrice;
}
public void setOverrideUnitPrice(boolean overrideUnitPrice) {
this.overrideUnitPrice = overrideUnitPrice;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!