package catering.order; import org.salespointframework.catalog.Product; import org.salespointframework.inventory.UniqueInventory; import org.salespointframework.inventory.UniqueInventoryItem; import org.salespointframework.order.Cart; import org.salespointframework.order.Order; import org.salespointframework.order.OrderManagement; 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.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.temporal.ChronoUnit; import java.time.format.DateTimeFormatter; 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()); 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()); 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(), LocalDateTime.now()); } @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") 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); 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 if (amount.add(cartQuantity).isLessThan(Quantity.of(0))) { cart.addOrUpdateItem(product, cartQuantity.negate()); } else { cart.addOrUpdateItem(product, amount); } return "redirect:/event"; } @PostMapping("/event/checkout") @PreAuthorize("hasRole('CUSTOMER')") public String checkout(@ModelAttribute("event") CustomCart cart, @LoggedIn Optional userAccount, Model model) { 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(); List myOrders = orderManagement.findBy(account).stream().collect(Collectors.toList()); 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"; } @PostMapping("/event/changeOrderTime") @PreAuthorize("hasRole('CUSTOMER')") public String changeOrderTime(@RequestParam(name = "start") Optional startTime, @RequestParam(name = "finish") Optional finishTime, @ModelAttribute("event") CustomCart cart) { LocalDateTime start = LocalDateTime.parse(startTime.orElse("2024-12-03T10:15:30")); LocalDateTime finish = LocalDateTime.parse(finishTime.orElse("2024-12-03T10:19:30")); cart.setStart(start); cart.setFinish(finish); return "redirect:/event"; } }