package catering.order; import jakarta.persistence.PostPersist; import org.salespointframework.catalog.Product; import org.salespointframework.inventory.UniqueInventory; import org.salespointframework.inventory.UniqueInventoryItem; import org.salespointframework.order.*; import org.salespointframework.quantity.Quantity; import org.salespointframework.time.Interval; import org.salespointframework.useraccount.Role; import org.salespointframework.useraccount.UserAccount; import org.salespointframework.useraccount.web.LoggedIn; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.query.Procedure; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.LocalDate; import java.time.LocalTime; import java.time.temporal.ChronoUnit; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @Controller @PreAuthorize("isAuthenticated()") @SessionAttributes("event") public class OrderController { private final OrderManagement orderManagement; private final UniqueInventory inventory; public OrderController(OrderManagement orderManagement, UniqueInventory inventory) { this.orderManagement = orderManagement; this.inventory = inventory; } @GetMapping("/myOrders") @PreAuthorize("hasRole('CUSTOMER')") public String orders(Model model, @LoggedIn Optional userAccount) { List myOrders = orderManagement.findBy(userAccount.get()).stream().collect(Collectors.toList()); // to be changed model.addAttribute("orders", myOrders); model.addAttribute("total", myOrders.size()); model.addAttribute("cancelled", OrderStatus.CANCELED); model.addAttribute("completed", OrderStatus.COMPLETED); return "orders"; } @GetMapping("/allOrders") @PreAuthorize("hasRole('ADMIN')") public String orders(Model model) { List myOrders = orderManagement.findAll(Pageable.unpaged()).stream().collect(Collectors.toList()); model.addAttribute("orders", myOrders); model.addAttribute("total", myOrders.size()); model.addAttribute("cancelled", OrderStatus.CANCELED); model.addAttribute("completed", OrderStatus.COMPLETED); return "orders"; } // For Theo: filters orders by day @GetMapping("/allOrders/{day}") @PreAuthorize("hasRole('ADMIN')") public String orders(@PathVariable String day, Model model) { // Obtains an instance of LocalDate from a text string such as 2007-12-03. (https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html) LocalDate date = LocalDate.parse(day); List myOrders = orderManagement.findAll(Pageable.unpaged()).stream().filter( order -> (order.getStart().toLocalDate().isBefore(date) || order.getStart().toLocalDate().isEqual(date)) && (order.getFinish().toLocalDate().isAfter(date) || order.getFinish().toLocalDate().isEqual(date)) ).collect(Collectors.toList()); model.addAttribute("orders", myOrders); model.addAttribute("total", myOrders.size()); return "orders"; } @ModelAttribute("event") CustomCart initializeCart() { return new CustomCart(OrderType.SOMETHING_ELSE, LocalDateTime.now().plusDays(7), LocalDateTime.now().plusDays(7)); } @GetMapping("/event") @PreAuthorize("hasRole('CUSTOMER')") public String event(Model model, @ModelAttribute("event") CustomCart cart) { model.addAttribute("items", cart.stream().collect(Collectors.toList())); model.addAttribute("totalPrice", cart.getPrice()); model.addAttribute("invItems", inventory.findAll().stream().collect(Collectors.toList())); return "event"; } @PostMapping("/allOrders/remove") @PreAuthorize("hasRole('ADMIN')") public String removeOrder(@RequestParam Order.OrderIdentifier orderID, @LoggedIn Optional userAccount) { return userAccount.map(account -> { if (account.hasRole(Role.of("ADMIN"))) { CustomOrder myOrder = orderManagement.get(orderID).get(); // FIXME orderManagement.cancelOrder(myOrder, "I have my own reasons."); return "redirect:/allOrders"; } return "redirect:/"; }).orElse("redirect:/"); } @PostMapping("/event/addProduct") @PreAuthorize("hasRole('CUSTOMER')") public String addProduct(@RequestParam("pid") Product product, @RequestParam("number") int number, @ModelAttribute("event") CustomCart cart) { Quantity amount = Quantity.of(number > 0 ? number : 1); Quantity invAmount = inventory.findByProduct(product).get().getQuantity(); // TODO ERROR HANDLING Quantity cartQuantity = cart.getQuantity(product); // check for possible miss-inputs if (amount.add(cartQuantity).isGreaterThan(invAmount)) { cart.addOrUpdateItem(product, cartQuantity.negate().add(invAmount)); } else { cart.addOrUpdateItem(product, amount); } return "redirect:/event"; } @PostMapping("/event/removeProduct") @PreAuthorize("hasRole('CUSTOMER')") public String removeProduct(@RequestParam("itemId") String itemId, @ModelAttribute("event") CustomCart cart) { cart.removeItem(itemId); return "redirect:/event"; } @PostMapping("/event/changeDate") @PreAuthorize("hasRole('CUSTOMER')") public String changeDate(@RequestParam("startDate") LocalDate start, @RequestParam("startHour") Optional startHour, @RequestParam("finishDate") LocalDate finish, @RequestParam("finishHour") Optional finishHour, @ModelAttribute("event") CustomCart cart) { int unwrappedStartHour = startHour.orElse(cart.getStart().getHour()); int unwrappedFinishHour = finishHour.orElse(cart.getFinish().getHour()); finish = finish.isBefore(start) ? start : finish; LocalDateTime startTime = LocalDateTime.of(start, LocalTime.of(unwrappedStartHour, 0)); // TODO LocalDateTime finishTime = LocalDateTime.of(finish, LocalTime.of(unwrappedFinishHour <= unwrappedStartHour ? unwrappedStartHour+1 : unwrappedFinishHour, 0)); // TODO cart.setStart(startTime); cart.setFinish(finishTime); return "redirect:/event"; } @PostMapping("/event/checkout") @PreAuthorize("hasRole('CUSTOMER')") public String checkout(@ModelAttribute("event") CustomCart cart, @LoggedIn Optional userAccount) { if (cart.isEmpty()) { return "redirect:/event"; } return userAccount.map(account -> { CustomOrder myOrder = new CustomOrder(account.getId(), cart); cart.addItemsTo(myOrder); orderManagement.payOrder(myOrder); // TODO: change this later orderManagement.completeOrder(myOrder); cart.clear(); return "redirect:/myOrders"; }).orElse("redirect:/event"); } @PostMapping("/event/changeOrderType") @PreAuthorize("hasRole('CUSTOMER')") public String changeOrderType(@RequestParam(name = "type") Optional optionalOrderType, @ModelAttribute("event") CustomCart cart) { String orderType = optionalOrderType.orElse("FOO"); switch (orderType) { case "RaK": cart.setOrderType(OrderType.RENT_A_COOK); break; case "EK": cart.setOrderType(OrderType.EVENT_CATERING); break; case "SN": cart.setOrderType(OrderType.SUSHI_NIGHT); break; case "MB": cart.setOrderType(OrderType.MOBILE_BREAKFAST); break; default: cart.setOrderType(OrderType.SOMETHING_ELSE); } return "redirect:/event"; } }