Add additional functionality to order package

This adds improved product removal from cart, changeable order time and
nice colors to order list.

Works on #38
This commit is contained in:
Mathis Kral 2023-11-20 22:08:08 +01:00 committed by Simon Bruder
parent ea24c27d6e
commit 27fdc3ef02
Signed by: simon
GPG key ID: 8D3C82F9F309F8EC
3 changed files with 84 additions and 21 deletions

View file

@ -1,17 +1,17 @@
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.Cart;
import org.salespointframework.order.Order;
import org.salespointframework.order.OrderManagement;
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;
@ -19,8 +19,10 @@ 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;
@ -48,6 +50,8 @@ public class OrderController {
model.addAttribute("orders", myOrders);
model.addAttribute("total", myOrders.size());
model.addAttribute("cancelled", OrderStatus.CANCELED);
model.addAttribute("completed", OrderStatus.COMPLETED);
return "orders";
}
@ -58,6 +62,8 @@ public class OrderController {
model.addAttribute("orders", myOrders);
model.addAttribute("total", myOrders.size());
model.addAttribute("cancelled", OrderStatus.CANCELED);
model.addAttribute("completed", OrderStatus.COMPLETED);
return "orders";
}
@ -81,7 +87,7 @@ public class OrderController {
@ModelAttribute("event")
CustomCart initializeCart() {
return new CustomCart(OrderType.SOMETHING_ELSE, LocalDateTime.now(), LocalDateTime.now());
return new CustomCart(OrderType.SOMETHING_ELSE, LocalDateTime.now().plusDays(7), LocalDateTime.now().plusDays(7));
}
@GetMapping("/event")
@ -110,15 +116,13 @@ public class OrderController {
@PreAuthorize("hasRole('CUSTOMER')")
public String addProduct(@RequestParam("pid") Product product, @RequestParam("number") int number, @ModelAttribute("event") CustomCart cart) {
Quantity amount = Quantity.of(number);
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 if (amount.add(cartQuantity).isLessThan(Quantity.of(0))) {
cart.addOrUpdateItem(product, cartQuantity.negate());
} else {
cart.addOrUpdateItem(product, amount);
}
@ -126,9 +130,37 @@ public class OrderController {
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<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";
}
@PostMapping("/event/checkout")
@PreAuthorize("hasRole('CUSTOMER')")
public String checkout(@ModelAttribute("event") CustomCart cart, @LoggedIn Optional<UserAccount> userAccount, Model model) {
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);
@ -137,8 +169,6 @@ public class OrderController {
orderManagement.completeOrder(myOrder);
cart.clear();
List<CustomOrder> myOrders = orderManagement.findBy(account).stream().collect(Collectors.toList());
return "redirect:/myOrders";
}).orElse("redirect:/event");
}

View file

@ -6,11 +6,9 @@
<body>
<div layout:fragment="content">
<span th:text="'Typ: ' + ${event.getOrderType()}"/>
<form th:action="@{/event/changeOrderType}" method="post">
<select class="form-select w-auto d-inline-block" name="type">
<option disabled="disabled" selected value="NULL" th:text="' -- Wählen Sie eine Option -- '"/>
<option disabled="disabled" selected value="NULL" th:text="${event.getOrderType()}"/>
<option th:value="'SE'" th:text="'Something else'"/>
<option th:value="'RaK'" th:text="Rent-a-Cook"/>
<option th:value="'EK'" th:text="Eventcatering"/>
@ -20,16 +18,44 @@
<button class="btn btn-primary" type="submit">Eventtypen ändern</button>
</form>
<!-- I NEED SPACE -->
<br>
<form th:action="@{/event/changeDate}" method="post">
<label th:text="'Wählen sie ihren gewünschten Zeitraum aus (min. 7 Tage im voraus):'"/><br>
<input type="date" th:value="${event.getStart().toLocalDate()}" th:min="${event.getStart().toLocalDate()}" name="startDate"/>
<select class="i do not know" name="startHour">
<option disabled="disabled" selected value="NULL" th:text="${event.getStart().getHour()} + ' Uhr'"/>
<option th:each="i : ${#numbers.sequence(0, 23)}" th:value="${i}" th:text="${i} + ' Uhr'"></option>
</select>
<input type="date" th:value="${event.getFinish().toLocalDate()}" th:min="${event.getFinish().toLocalDate()}" name="finishDate"/>
<select class="i do not know" name="finishHour">
<option disabled="disabled" selected value="NULL" th:text="${event.getFinish().getHour() + ' Uhr'}"/>
<option th:each="i : ${#numbers.sequence(0, 23)}" th:value="${i}" th:text="${i} + ' Uhr'"></option>
</select>
<button class="btn btn-primary" type="submit">Wunschdatum überprüfen</button>
</form>
<!-- I NEED SPACE -->
<br>
<table class="table">
<tr>
<th>Produkt</th>
<th>Anzahl</th>
<th>Preis</th>
<th></th>
</tr>
<tr th:each="item : ${items}">
<td th:text="${item.getProductName()}">Sake Nigiri</td>
<td th:text="${item.getQuantity()}">200</td>
<td th:text="${item.getPrice()} +'€'">10€</td>
<td>
<form method="post" th:action="@{/event/removeProduct}">
<input type="hidden" th:value="${item.getId()}" name="itemId"/>
<button class="btn btn-danger" type="submit" >Produkt entfernen</button>
</form>
</td>
</tr>
</table>
@ -58,7 +84,7 @@
<td th:text="${item.getQuantity()}">Verfügbar</td>
<td>
<form th:action="@{/event/addProduct}" method="post">
<input id="number" type="number" name="number" th:min="${item.getQuantity().negate()}" th:max="${item.getQuantity()}" value="1"/>
<input id="number" type="number" name="number" min="1" th:max="${item.getQuantity()}" value="1"/>
<input type="hidden" name="pid" th:value="${item.getProduct().getId()}"/>
<input class="btn btn-primary" type="submit" th:value="Hinzufügen"/>
</form>

View file

@ -20,12 +20,16 @@
<tr th:each="order : ${orders}">
<td th:text="${order.getFormattedStart()}">
<td th:text="${order.getFormattedFinish()}">
<td th:text="BeispielKunde"/>
<td th:text="${order.getUserAccountIdentifier()}"/>
<td>
<div>
<a href="#productDetails" th:text="${order.getOrderType()}"/>
<ul th:each="chargeLine : ${order.getChargeLines()}">
<li th:text="${chargeLine}"/>
<ul th:each="orderLine : ${order.getOrderLines()}">
<li>
<b th:text="${orderLine.getProductName()}"/><br>
<th:block th:text="'Menge: ' + ${orderLine.getQuantity()}"/><br>
<th:block th:text="'Preis: ' + ${orderLine.getPrice().getNumber().doubleValue() + ' €'}"/>
</li>
</ul>
</div>
</td>
@ -37,15 +41,18 @@
<span>Keine Rechnung verfügbar</span>
</div>
</td>
<td th:text="${order.getOrderStatus()}"></td> <!--von Admin bearbeitbar-->
<td>
<th:block th:text="${order.getTotal()}"/>
<p style="color: red" th:if="${order.getOrderStatus()} == ${cancelled}" th:text="STORNIERT"/>
<p style="color: green" th:if="${order.getOrderStatus()} == ${completed}" th:text="ABGESCHLOSSEN"/>
</td> <!--von Admin bearbeitbar-->
<td>
<th:block th:text="${order.getTotal().getNumber().doubleValue()}"/>
<th:block th:text="€"/>
</td>
<td sec:authorize="hasRole('ADMIN')">
<td sec:authorize="hasRole('ADMIN')" th:if="${order.getOrderStatus()} != ${cancelled}">
<form method="post" th:action="@{/allOrders/remove}">
<input type="hidden" name="orderID" value="0" th:value="${order.getId()}"/> <!-- FIXME BROKEN -->
<input class="btn btn-danger" type="submit" value="remove" th:value="Entfernen"/>
<input class="btn btn-danger" type="submit" value="remove" th:value="Stornieren"/>
</form>
</td>
</tr>