implement checkout for non logged in users.

This commit is contained in:
CodeSteak 2020-05-05 18:59:15 +02:00 committed by localhorst
parent 7d83d723c1
commit d2bf6e8c52
6 changed files with 136 additions and 110 deletions

View File

@ -63,6 +63,7 @@ public class ShopArticleController {
@RequestAttribute(value = "shoppingCart") ShoppingCart shoppingCart,
@PathVariable("id") Long id,
@RequestParam("quantity") Integer quantity,
@RequestParam(value = "set_amount", required = false) Boolean setAmount,
@RequestParam("fastcheckout") Boolean fastcheckout
) {
@ -71,12 +72,16 @@ public class ShopArticleController {
throw new RuntimeException("Article not found!");
}
shoppingCart.addArticle(article.get(), quantity);
if (setAmount != null && setAmount) {
shoppingCart.setArticleCount(article.get(), quantity);
} else {
shoppingCart.addArticle(article.get(), quantity);
}
if (!fastcheckout) {
return "shop/articles/post_add";
} else {
return "shop/checkout";
return "redirect:/shop/checkout";
}
}
}

View File

@ -1,23 +1,73 @@
package org.hso.ecommerce.controller.shop;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.shop.ShoppingCart;
import org.hso.ecommerce.repos.shop.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.TreeMap;
@Controller
@RequestMapping("/shop/")
public class ShopCheckoutController {
@Autowired
private final ArticleRepository articleRepository = null;
@GetMapping("/checkout")
public String shopCheckout(HttpSession session, HttpServletRequest request) {
public String shopCheckout(HttpSession session,
HttpServletRequest request,
@RequestAttribute(value = "shoppingCart") ShoppingCart shoppingCart) {
session.setAttribute("afterLogin", request.getRequestURI());
CheckoutListTotals totals = new CheckoutListTotals();
ArrayList<CheckoutListItem> items = new ArrayList<>();
for (ShoppingCart.ShoppingCartItem item : shoppingCart.getItems()) {
Article article = articleRepository.findById(item.getArticleId()).get();
totals.addItem(article, item.getAmount());
items.add(new CheckoutListItem(item.getAmount(), article));
}
request.setAttribute("checkoutItems", items);
request.setAttribute("checkoutTotals", totals);
return "shop/checkout";
}
public static class CheckoutListTotals {
public int net;
public TreeMap<Integer, Integer> vatAmounts = new TreeMap<>();
public int total;
void addItem(Article article, int amount) {
net += article.shopPricePerUnitNetCent * amount;
Integer vatPos = vatAmounts.getOrDefault(article.related.vatPercent, 0) + article.getVat() * amount;
vatAmounts.put(article.related.vatPercent, vatPos);
total += article.getPriceGross() * amount;
}
}
public static class CheckoutListItem {
public int amount;
public Article article;
public int total;
public CheckoutListItem(int amount, Article article) {
this.amount = amount;
this.article = article;
this.total = amount * article.getPriceGross();
}
}
@PostMapping("/checkoutFinish")
public String shopCheckoutFinish() {
return "shop/checkoutFinish";

View File

@ -37,4 +37,12 @@ public class Article {
@ManyToMany
@JoinTable(name = "article_categories_bindings")
public Set<Category> categories = new HashSet<>();
public int getVat() {
return (shopPricePerUnitNetCent * related.vatPercent) / 100;
}
public int getPriceGross() {
return shopPricePerUnitNetCent + getVat();
}
}

View File

@ -1,6 +1,7 @@
package org.hso.ecommerce.entities.shop;
import java.util.ArrayList;
import java.util.List;
// Not a db entity. Just for session storage
public class ShoppingCart {
@ -13,6 +14,10 @@ public class ShoppingCart {
items = new ArrayList<>();
}
public List<ShoppingCartItem> getItems() {
return items;
}
public int getItemCount() {
int count = 0;
@ -40,7 +45,25 @@ public class ShoppingCart {
items.add(new ShoppingCartItem(quantity, article));
}
private static class ShoppingCartItem {
public void setArticleCount(Article article, Integer quantity) {
this.revision++;
boolean found = false;
for (ShoppingCartItem i : items) {
if (i.getArticleId() == article.id) {
i.setAmount(quantity);
found = true;
break;
}
}
if (!found) {
items.add(new ShoppingCartItem(quantity, article));
}
items.removeIf(i -> i.getAmount() == 0);
}
public static class ShoppingCartItem {
private int amount;
private final long articleId;
@ -60,5 +83,9 @@ public class ShoppingCart {
public long getArticleId() {
return articleId;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
}
}

View File

@ -1,7 +0,0 @@
CREATE TABLE "customers" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"lastname" TEXT,
"firstname" TEXT,
"username" TEXT,
"password" TEXT
);

View File

@ -31,91 +31,31 @@
<th>Menge</th>
<th></th>
</tr>
<tr>
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-1.jpg}" class="s"/><a/></td>
<td><a th:href="@{/shop/articles/4151}">Kamera<a/></td>
<td>100,50&nbsp;EUR</td>
<td>
<select size="1">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</td>
<td>
<button class="small">Entfernen</button>
</td>
</tr>
<tr>
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-2.jpg}" class="s"/><a/></td>
<td><a th:href="@{/shop/articles/4151}">Earbuds<a/></td>
<td>63,95&nbsp;EUR</td>
<td>
<select size="1">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</td>
<td>
<button>Entfernen</button>
</td>
</tr>
<tr>
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-3.jpg}" class="s"/><a/></td>
<td><a th:href="@{/shop/articles/4151}">USB-Magic Light<a/></td>
<td>11,90&nbsp;EUR</td>
<td>
<select size="1">
<option value="1">1</option>
<option value="2" selected>2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</td>
<td>
<button>Entfernen</button>
</td>
</tr>
<tr>
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-4.jpg}" class="s"/><a/></td>
<td><a th:href="@{/shop/articles/4151}">3D Magic Stativ<a/></td>
<td>15,99&nbsp;EUR</td>
<td>
<select size="1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5" selected>5</option>
</select>
</td>
<td>
<button>Entfernen</button>
</td>
</tr>
<tr>
<td><a th:href="@{/shop/articles/4151}"><img th:src="@{/img/product-5.jpg}" class="s"/><a/></td>
<td><a th:href="@{/shop/articles/4151}">Ersatzfernbedinung<a/></td>
<td>7,95&nbsp;EUR</td>
<td>
<select size="1">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</td>
<td>
<button>Entfernen</button>
</td>
</tr>
<th:block th:each="item : ${checkoutItems}">
<tr>
<td><a th:href="@{/shop/articles/{id}(id = ${item.article.id})}"><img
th:src="@{/shop/articles/${item.article.id}/image.jpg}" class="s"/></a></td>
<td><a th:href="@{/shop/articles/{id}(id = ${item.article.id})}"
th:text="${item.article.title}"></a></td>
<td><span th:text="${#numbers.formatDecimal(item.total, 1, 'POINT', 2, 'COMMA')}"></span> EUR</td>
<td>
<form method="POST" th:action="@{/shop/articles/{id}(id = ${item.article.id})}">
<input type="hidden" name="fastcheckout" value="true"/>
<input type="hidden" name="set_amount" value="true"/>
<select name="quantity" size="1">
<option th:value="${item.amount}" th:text="${item.amount}" selected></option>
<option value="0">Entfernen</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<button class="small">Ändern</button>
</form>
</td>
</tr>
<th:block>
</table>
</div>
<form method="POST" th:action="@{/shop/checkoutFinish}" style="min-width: 30em; max-width: 45em;">
@ -151,23 +91,26 @@ Musterstraße 42
<table>
<tr>
<th>Artikel (Netto)</th>
<th>200,29&nbsp;EUR</th>
</tr>
<tr th:if="${user}">
<th>Bonuspunkte</th>
<th>-5,00&nbsp;EUR</th>
</tr>
<tr>
<th>Umsatzsteuer (19%)</th>
<th>35,00&nbsp;EUR</th>
</tr>
<tr>
<th>Umsatzsteuer (7%)</th>
<th>2,50&nbsp;EUR</th>
<th><span
th:text="${#numbers.formatDecimal(checkoutTotals.net, 1, 'POINT', 2, 'COMMA')}"></span>
EUR
</th>
</tr>
<th:block th:each="item : ${checkoutTotals.vatAmounts.entrySet()}">
<tr>
<th>Umsatzsteuer (<span th:text="${item.getKey()}"></span>%)</th>
<th><span
th:text="${#numbers.formatDecimal(item.getValue(), 1, 'POINT', 2, 'COMMA')}"></span>
EUR
</th>
</tr>
</th:block>
<tr class="secondary">
<th>Gesamt:</th>
<th>240,79&nbsp;EUR</th>
<th><span
th:text="${#numbers.formatDecimal(checkoutTotals.total, 1, 'POINT', 2, 'COMMA')}"></span>
EUR
</th>
</tr>
<tr th:if="${user}" class="secondary">
<th colspan="2" class=" no-padding"></th>