package cz.coffei.foodo.data.rest; import cz.coffei.foodo.data.dao.OrderDao; import cz.coffei.foodo.data.dao.PriceConstantDao; import cz.coffei.foodo.data.entities.Order; import cz.coffei.foodo.data.entities.PriceConstant; import cz.coffei.foodo.data.enums.OrderStatus; import cz.coffei.foodo.data.exceptions.EntityInvalidException; import cz.coffei.foodo.data.mail.MailSender; import cz.coffei.foodo.data.rest.utils.ErrorHelper; import javax.ejb.EJBException; import javax.ejb.EJBTransactionRolledbackException; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.mail.MessagingException; import javax.persistence.NoResultException; import javax.ws.rs.*; import javax.ws.rs.core.Response; import java.time.Duration; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.Collections; import java.util.List; import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Created by jtrantin on 26.7.15. */ @Path("/orders") @Produces("application/json;charset=UTF-8") @Consumes("application/json;charset=UTF-8") @RequestScoped public class OrderRESTService { private int MAX_MIN_CANCEL = 15; @Inject private Logger log; @Inject private OrderDao dao; @Inject private PriceConstantDao priceConstantDao; @Inject private MailSender mailSender; @GET @Path("/status/{statuses}") public Response getOrdersByStatus(@PathParam("statuses") String statuses) { List<OrderStatus> allowedStatuses = Collections.emptyList(); try { Stream<OrderStatus> orderStatusStream = Stream.of(statuses.split(",")).map(OrderStatus::valueOf); allowedStatuses = orderStatusStream.collect(Collectors.toList()); } catch (IllegalArgumentException e) { return Response.status(Response.Status.BAD_REQUEST).entity("Invalid order status").build(); } List<Order> orders = dao.getOrdersByStatuses(allowedStatuses); return Response.ok(orders).build(); } @GET @Path("/{id}") public Response findOrderById(@PathParam("id") Long id) { try { Order order = dao.getOrderById(id); return Response.ok(order).build(); } catch (EJBException e) { NoResultException nre = ErrorHelper.findExceptionByClass(e, NoResultException.class); if (nre != null) { return Response.noContent().build(); } return Response.serverError().entity(e.getMessage()).build(); } } @POST public Response createOrder(Order order) { log.info("Creating order:"); log.info(order.toString()); try { order = dao.createOrder(order); PriceConstant takeaway = priceConstantDao.getPriceConstant("takeaway", 0); try { mailSender.sendNewOrderEmail(order, takeaway); } catch (MessagingException e) { log.warning("Cannot send email for new order " + order.getId()); } log.info("Created!"); return Response.created(null).entity(order.getId()).build(); } catch (EntityInvalidException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (EJBTransactionRolledbackException e) { return ErrorHelper.processEJBTransactionFailure(e); } } @PUT @Path("/{id}") public Response updateOrder(Order order, @PathParam("id") Long id) { Order currentOrder = dao.getOrderById(id); boolean statusChanged = !currentOrder.getStatus().equals(order.getStatus()); if (order.getCustomeremail() != null) currentOrder.setCustomeremail(order.getCustomeremail()); if (order.getCustomerName() != null) currentOrder.setCustomerName(order.getCustomerName()); if (order.getStatus() != null) currentOrder.setStatus(order.getStatus()); log.info("Updating order:"); log.info(currentOrder.toString()); try { dao.updateOrder(currentOrder); PriceConstant takeaway = priceConstantDao.getPriceConstant("takeaway", 0); try { mailSender.sendStatusChangedEmail(currentOrder, takeaway, false); } catch (MessagingException e) { log.warning("Cannot send email for order status change: " + currentOrder.getId()); log.warning(e.toString()); } log.info("Updated!"); return Response.ok().build(); } catch (EntityInvalidException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (EJBTransactionRolledbackException e) { return ErrorHelper.processEJBTransactionFailure(e); } } /** * Method used for cancelling the order by customer * @param id identificator of the order to cancel * @return */ @POST @Path(("/{id}/cancel")) public Response cancelOrder(@PathParam("id") Long id) { Order currentOrder = dao.getOrderById(id); Duration duration = Duration.between(currentOrder.getCreated().toLocalDateTime().atZone(ZoneId.of("UTC")), ZonedDateTime.now(ZoneId.of("UTC"))); log.info(currentOrder.getCreated().toString()); log.info(duration.toString()); if (duration.compareTo(Duration.ofMinutes(MAX_MIN_CANCEL)) > 0) { // it is more than 15 minutes from creation return Response.status(Response.Status.BAD_REQUEST).build(); } currentOrder.setStatus(OrderStatus.CANCELLED); try { dao.updateOrder(currentOrder); PriceConstant takeaway = priceConstantDao.getPriceConstant("takeaway", 0); try { mailSender.sendStatusChangedEmail(currentOrder, takeaway, true); } catch (MessagingException e) { log.warning("Cannot send email for order cancellation: " + currentOrder.getId()); log.warning(e.toString()); } log.info("Order cancelled: " + currentOrder.getId()); return Response.ok().build(); } catch (EntityInvalidException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (EJBTransactionRolledbackException e) { return ErrorHelper.processEJBTransactionFailure(e); } } @DELETE @Path("/{id}") public Response deleteOrder(@PathParam("id") Long id) { Order order = null; try { order = dao.getOrderById(id); } catch (EJBException e) { return Response.status(Response.Status.NOT_FOUND).build(); } log.info("Deleting order:"); log.info(order.toString()); try { dao.deleteOrder(order); log.info("Deleted!"); return Response.ok().build(); } catch (EntityInvalidException e) { return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (EJBTransactionRolledbackException e) { return ErrorHelper.processEJBTransactionFailure(e); } } }