package com.sap.hana.cloud.samples.benefits.odata; import static com.sap.hana.cloud.samples.benefits.odata.cfg.FunctionImportParameters.BENEFIT_TYPE_ID; import static com.sap.hana.cloud.samples.benefits.odata.cfg.FunctionImportParameters.CAMPAIGN_ID; import static com.sap.hana.cloud.samples.benefits.odata.cfg.FunctionImportParameters.ORDER_ID; import static com.sap.hana.cloud.samples.benefits.odata.cfg.FunctionImportParameters.QUANTITY; import static com.sap.hana.cloud.samples.benefits.odata.cfg.FunctionImportParameters.USER_ID; import static org.apache.olingo.odata2.api.annotation.edm.EdmType.INT64; import static org.apache.olingo.odata2.api.annotation.edm.EdmType.STRING; import java.util.Collection; import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImport; import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImport.HttpMethod; import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImport.ReturnType; import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImport.ReturnType.Type; import org.apache.olingo.odata2.api.annotation.edm.EdmFunctionImportParameter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sap.hana.cloud.samples.benefits.odata.cfg.FunctionImportNames; import com.sap.hana.cloud.samples.benefits.persistence.BenefitTypeDAO; import com.sap.hana.cloud.samples.benefits.persistence.OrderDAO; import com.sap.hana.cloud.samples.benefits.persistence.OrderDetailDAO; import com.sap.hana.cloud.samples.benefits.persistence.UserPointsDAO; import com.sap.hana.cloud.samples.benefits.persistence.model.BenefitType; import com.sap.hana.cloud.samples.benefits.persistence.model.Campaign; import com.sap.hana.cloud.samples.benefits.persistence.model.Order; import com.sap.hana.cloud.samples.benefits.persistence.model.OrderDetails; import com.sap.hana.cloud.samples.benefits.persistence.model.User; import com.sap.hana.cloud.samples.benefits.persistence.model.UserPoints; public class OrderService extends ODataService { private static final String ORDER_DETAIL_NOT_VALID_MESSAGE = "The order value exceedes the available unused points, so is not valid. The order is not persisted"; //$NON-NLS-1$ private final Logger logger = LoggerFactory.getLogger(getClass()); private UserPointsDAO userPointsDAO = new UserPointsDAO(); @EdmFunctionImport(name = FunctionImportNames.ADD_ORDER, returnType = @ReturnType(type = Type.SIMPLE, isCollection = false), httpMethod = HttpMethod.POST) public boolean addOrder(@EdmFunctionImportParameter(name = CAMPAIGN_ID, type = INT64) Long campaignId, @EdmFunctionImportParameter(name = USER_ID, type = STRING) String userId, @EdmFunctionImportParameter(name = QUANTITY, type = INT64) Long quantity, @EdmFunctionImportParameter(name = BENEFIT_TYPE_ID, type = INT64) Long benefitTypeId) throws AppODataException { final User loggedInUser = getLoggedInSfUser(); if (!(loggedInUser.getUserId().equals(userId) || UserManager.getIsUserAdmin())) { throw new AppODataException("Unauthorized"); //$NON-NLS-1$ } final User user = userDAO.getByUserId(userId); final Campaign campaign = campaignDAO.getById(campaignId); if (campaign == null) { throw new AppODataException("Incorrect campaign id"); //$NON-NLS-1$ } if (!campaign.getActive()) { throw new AppODataException("The campaign with id " + campaignId + " is not active"); //$NON-NLS-1$ //$NON-NLS-2$ } final OrderDAO orderDAO = new OrderDAO(); final Order userOrder = getOrCreateUserOrder(user, campaign, orderDAO); final BenefitTypeDAO benefitTypeDAO = new BenefitTypeDAO(); final BenefitType benefitType = benefitTypeDAO.getById(benefitTypeId); if (benefitType == null) { throw new AppODataException("Incorrect benefit type id"); //$NON-NLS-1$ } final OrderDetails orderDetails = createOrderDetails(quantity, benefitType); final UserPoints userPoints = getUserPoints(userOrder); final long orderDetailsTotal = calcPointsToAdd(orderDetails); if (userPoints.getAvailablePoints() < orderDetailsTotal) { throw new AppODataException(ORDER_DETAIL_NOT_VALID_MESSAGE); } userOrder.addOrderDetails(orderDetails); new OrderDetailDAO().saveNew(orderDetails); userPoints.subtractPoints(orderDetailsTotal); userPointsDAO.save(userPoints); return true; } @EdmFunctionImport(name = FunctionImportNames.DELETE_ORDER, returnType = @ReturnType(type = Type.SIMPLE, isCollection = false), httpMethod = HttpMethod.DELETE) public boolean deleteOrderDetail(@EdmFunctionImportParameter(name = ORDER_ID, type = INT64) Long orderId) throws AppODataException { final OrderDetailDAO orderDetailDAO = new OrderDetailDAO(); final Order order = orderDetailDAO.getOrderByOrderDetailsId(orderId); final OrderDetails details = orderDetailDAO.getById(orderId); final UserPoints userPoints = getUserPoints(order); try { order.removeOrderDetails(details); userPoints.addPoints(calcPointsToAdd(details)); userPointsDAO.save(userPoints); orderDetailDAO.delete(orderId); return true; } catch (IllegalArgumentException ex) { logger.error("Error occur while deleting order with id:{}", orderId, ex); //$NON-NLS-1$ throw new AppODataException("Error occur while deleting order", ex); //$NON-NLS-1$ } } private Order getOrCreateUserOrder(final User user, final Campaign campaign, final OrderDAO orderDAO) { Order userOrder = null; final Collection<Order> ordersOfUser = orderDAO.getOrdersForUser(user, campaign); if (ordersOfUser.isEmpty()) { userOrder = orderDAO.createOrderForUser(user, campaign); } else { userOrder = ordersOfUser.iterator().next(); } return userOrder; } private OrderDetails createOrderDetails(Long quantity, BenefitType benefitType) { final OrderDetails orderDetails = new OrderDetails(); orderDetails.setBenefitType(benefitType); orderDetails.setQuantity(quantity); return orderDetails; } private UserPoints getUserPoints(Order order) { return userPointsDAO.getUserPoints(order.getUser(), order.getCampaign()); } private long calcPointsToAdd(OrderDetails orderDetail) { return orderDetail.getQuantity() * orderDetail.getBenefitType().getValue(); } }