swt23w23/src/main/java/catering/order/OrderController.java

263 lines
10 KiB
Java
Raw Normal View History

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;
2023-11-21 22:59:04 +01:00
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.util.Streamable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
2023-11-07 22:23:48 +01:00
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;
2023-11-21 22:59:04 +01:00
import java.util.*;
import java.util.stream.Collectors;
@Controller
@PreAuthorize("isAuthenticated()")
@SessionAttributes("event")
public class OrderController {
private final OrderManagement<CustomOrder> orderManagement;
private final UniqueInventory<UniqueInventoryItem> inventory;
public OrderController(OrderManagement<CustomOrder> orderManagement, UniqueInventory<UniqueInventoryItem> inventory) {
this.orderManagement = orderManagement;
this.inventory = inventory;
}
@GetMapping("/myOrders")
@PreAuthorize("hasRole('CUSTOMER')")
public String orders(Model model, @LoggedIn Optional<UserAccount> userAccount) {
List<CustomOrder> 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<CustomOrder> 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";
}
2023-11-05 16:41:22 +01:00
2023-11-14 20:31:12 +01:00
// For Theo: filters orders by day
@GetMapping("/allOrders/{day}")
@PreAuthorize("hasRole('ADMIN')")
2023-11-14 20:31:12 +01:00
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<CustomOrder> 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());
2023-11-14 20:31:12 +01:00
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> 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:/");
2023-11-05 16:41:22 +01:00
}
@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";
}
2023-11-07 22:23:48 +01:00
@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<Integer> startHour, @RequestParam("finishDate") LocalDate finish, @RequestParam("finishHour") Optional<Integer> 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";
}
2023-11-07 22:23:48 +01:00
@PostMapping("/event/checkout")
@PreAuthorize("hasRole('CUSTOMER')")
public String checkout(@ModelAttribute("event") CustomCart cart, @LoggedIn Optional<UserAccount> 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");
2023-11-07 22:23:48 +01:00
}
@PostMapping("/event/changeOrderType")
@PreAuthorize("hasRole('CUSTOMER')")
public String changeOrderType(@RequestParam(name = "type") Optional<String> optionalOrderType, @ModelAttribute("event") CustomCart cart) {
2023-11-09 22:17:47 +01:00
String orderType = optionalOrderType.orElse("FOO");
2023-11-07 22:23:48 +01:00
switch (orderType) {
case "RaK":
cart.setOrderType(OrderType.RENT_A_COOK);
2023-11-07 22:23:48 +01:00
break;
case "EK":
cart.setOrderType(OrderType.EVENT_CATERING);
2023-11-07 22:23:48 +01:00
break;
case "SN":
cart.setOrderType(OrderType.SUSHI_NIGHT);
break;
case "MB":
cart.setOrderType(OrderType.MOBILE_BREAKFAST);
2023-11-07 22:23:48 +01:00
break;
default:
cart.setOrderType(OrderType.SOMETHING_ELSE);
2023-11-07 22:23:48 +01:00
}
return "redirect:/event";
}
2023-11-21 22:59:04 +01:00
@GetMapping("/orders/calender")
public String calender(Model model) {
ArrayList<ArrayList<String>> datesOfMonth = new ArrayList<ArrayList<String>>(28);
LocalDateTime startDateTime = LocalDateTime.now();
LocalDateTime endDateTime = startDateTime.plusDays(27).withHour(23).withMinute(59).withSecond(59); // FIXME: set me to end of day
LocalDate startDate = startDateTime.toLocalDate();
LocalDate endDate = endDateTime.toLocalDate();
// create all dates of the calender
for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
ArrayList<String> x = new ArrayList<String>(2);
x.add(Integer.toString(date.getDayOfMonth()));
x.add(date.toString());
datesOfMonth.add(x);
}
/*
* FIXME: Do not load all orders into java,
* instead query orderManagement better to only return orders overlapping with interval [startDate,endDate]
* by using "query creation" of the jpa
* e.g. this.orderManagement.findByFinishDateIsNotBeforeAndStartDateIsNotAfter(LocalDateTime startDateTime, LocalDateTime endDateTime)
*/
Streamable<CustomOrder> x = this.orderManagement.findAll(Pageable.unpaged()).filter(e ->
!e.getFinish().toLocalDate().isBefore(startDate) && // end is not before today
!e.getStart().toLocalDate().isAfter(endDate)
);
// add each order overlapping with the calendar to the days it overlaps with
for (CustomOrder order : x) {
2023-11-21 22:59:04 +01:00
int start_index_inclusive = Math.max((int) startDate.until(order.getStart().toLocalDate(), ChronoUnit.DAYS),0);
int end_index_exclusive = Math.min((int) startDate.until(order.getFinish().toLocalDate(), ChronoUnit.DAYS), 27) + 1;
String order_id = Objects.requireNonNull(order.getId()).toString();
for (int i = start_index_inclusive; i < end_index_exclusive; i++) {
// FIXME: exchange order ids for a short name or a color
2023-11-21 22:59:04 +01:00
datesOfMonth.get(i).add(order_id);
}
}
// get names of weekdays for table header starting with the current day
LocalDate endOfWeekDate = startDate.plusDays(6);
ArrayList<String> dayNames = new ArrayList<String>(7);
for (LocalDate date = startDate; !date.isAfter(endOfWeekDate); date = date.plusDays(1)) {
dayNames.add(date.getDayOfWeek().toString());
}
// FIXME: Get rid of the following paragraph of code by change of order_calender.html
// put data of datesOfMonth inside current structure used in order_calender.html
2023-11-21 22:59:04 +01:00
ArrayList<ArrayList<ArrayList<String>>> weeksOfMonth = new ArrayList<ArrayList<ArrayList<String>>>();
for (int i = 0; i < 4; i++) {
weeksOfMonth.add(new ArrayList<ArrayList<String>>(7));
for (int j = 0; j < 7; j++) {
weeksOfMonth.get(i).add(new ArrayList<String>());
weeksOfMonth.get(i).get(j).addAll(datesOfMonth.get(
i*7+j
2023-11-21 22:59:04 +01:00
)
);
}
}
model.addAttribute("weeksOfMonth", weeksOfMonth);
model.addAttribute("dayNames", dayNames);
return "orders_calender";
}
}