feature/basic_functions #7

Merged
Seil0 merged 30 commits from feature/basic_functions into master 2020-05-10 17:48:31 +02:00
24 changed files with 526 additions and 53 deletions
Showing only changes of commit b2f927e48d - Show all commits

View File

@ -1,9 +1,9 @@
/* password is 123 */
INSERT INTO users ("created", "email", "password_hash", "gets_ads", "is_active", "is_employee", "isb2b")
VALUES (datetime('now','localtime') ||'.0', "emp@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "0", "1", "1", "0");
INSERT INTO users ("created", "email", "password_hash", "is_active", "is_employee")
VALUES (datetime('now','localtime') ||'.0', "emp@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "1");
INSERT INTO users ("created", "email", "password_hash", "gets_ads", "is_active", "is_employee", "isb2b")
VALUES (datetime('now','localtime') ||'.0', "user@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "1", "0", "0");
INSERT INTO users ("created", "email", "password_hash", "is_active", "is_employee")
VALUES (datetime('now','localtime') ||'.0', "user@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "0");
INSERT INTO users ("created", "email", "password_hash", "gets_ads", "is_active", "is_employee", "isb2b")
VALUES (datetime('now','localtime') ||'.0', "blocked@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "1", "0", "0", "0");
INSERT INTO users ("created", "email", "password_hash", "is_active", "is_employee")
VALUES (datetime('now','localtime') ||'.0', "blocked@ecom", "$2a$10$zFiqcePBmXHErD86vkI.vO1dnX20ezoVSM8xjGi59nktXYQv0o.fK", "0", "0");

View File

@ -0,0 +1,30 @@
package org.hso.ecommerce.action.booking;
import org.hso.ecommerce.entities.booking.Booking;
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
import org.hso.ecommerce.entities.booking.BookingReason;
public class CreateBookingAction {
private Booking booking;
public CreateBookingAction(BookingAccountEntry source, BookingAccountEntry destination, BookingReason reason, int amountCent) {
booking = new Booking();
booking.reason = reason;
booking.amountCent = amountCent;
assert source != null || destination != null;
if (source != null) {
booking.source = source.copyAddAmount(-amountCent);
}
if (destination != null) {
booking.destination = destination.copyAddAmount(amountCent);
}
}
public Booking finish() {
return booking;
}
}

View File

@ -0,0 +1,177 @@
package org.hso.ecommerce.action.shop;
import org.hso.ecommerce.action.booking.CreateBookingAction;
import org.hso.ecommerce.entities.booking.*;
import org.hso.ecommerce.entities.shop.Address;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.shop.CustomerOrder;
import org.hso.ecommerce.entities.shop.CustomerOrderPosition;
import org.hso.ecommerce.entities.user.User;
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPosition;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class CreateOrderAction {
private User user;
Address destination;
private int expectedTotalGrossCent;
private int totalNetCent;
private int totalVatCent;
private PaymentMethod method;
private BookingAccountEntry latestUserBooking;
private BookingAccountEntry latestVatBooking;
private BookingAccountEntry latestMainBooking;
private List<OrderItem> orderItems = new ArrayList<>();
public CreateOrderAction(
User user,
int expectedTotalGrossCent,
Address destination,
PaymentMethod method,
BookingAccountEntry latestUserBooking,
BookingAccountEntry latestVatBooking,
BookingAccountEntry latestMainBooking
) {
this.user = user;
this.expectedTotalGrossCent = expectedTotalGrossCent;
this.destination = destination;
this.method = method;
this.latestUserBooking = latestUserBooking;
assert latestUserBooking.userAccount.id == user.id;
this.latestVatBooking = latestVatBooking;
assert latestVatBooking.isVATAccount;
this.latestMainBooking = latestMainBooking;
assert latestMainBooking.isMainAccount;
}
public void addArticle(Article article, int quantity, List<WarehouseBookingPositionSlotEntry> availableSlots) {
for (WarehouseBookingPositionSlotEntry slot : availableSlots) {
assert slot.article.id == article.id;
}
orderItems.add(new OrderItem(article, availableSlots, quantity));
totalNetCent += article.shopPricePerUnitNetCent * quantity;
totalVatCent += article.getVat() * quantity;
}
public Result finish() {
CustomerOrder order = createOrder();
CustomerPayment payment = createPayment();
List<Booking> bookingList = new ArrayList<>();
bookingList.add(new CreateBookingAction(latestUserBooking, latestMainBooking, new BookingReason(order), order.totalGrossCent).finish());
bookingList.add(new CreateBookingAction(null, latestUserBooking, new BookingReason(payment), order.totalGrossCent).finish());
bookingList.add(new CreateBookingAction(latestMainBooking, latestVatBooking, new BookingReason(order), order.totalVatCent).finish());
WarehouseBooking warehouseBooking = createWarehouseBooking(order);
return new Result(
order,
warehouseBooking,
bookingList
);
}
private WarehouseBooking createWarehouseBooking(CustomerOrder order) {
WarehouseBooking booking = new WarehouseBooking();
booking.created = new Timestamp(new Date().getTime());
booking.reason = new BookingReason(order);
for (OrderItem item : orderItems) {
int needed = item.quantity;
for (WarehouseBookingPositionSlotEntry slot : item.availableSlots) {
int remove = Math.min(slot.newSumSlot, needed);
needed -= remove;
WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition();
bookingPosition.article = item.article;
bookingPosition.amount = -remove;
bookingPosition.slotEntry = slot.copyAddAmount(-remove);
bookingPosition.booking = booking;
booking.positions.add(bookingPosition);
if (needed == 0) {
break;
}
}
}
return booking;
}
private CustomerPayment createPayment() {
CustomerPayment payment = new CustomerPayment();
payment.amountCent = totalNetCent + totalVatCent;
payment.payment = method;
return payment;
}
private CustomerOrder createOrder() {
assert totalNetCent + totalVatCent == expectedTotalGrossCent;
CustomerOrder customerOrder = new CustomerOrder();
customerOrder.customer = user;
customerOrder.destination = destination;
for (OrderItem item : orderItems) {
CustomerOrderPosition position = new CustomerOrderPosition();
position.article = item.article;
position.pricePerUnit = item.article.shopPricePerUnitNetCent;
position.quantity = item.quantity;
position.order = customerOrder;
customerOrder.positions.add(position);
}
customerOrder.created = new Timestamp(new Date().getTime());
customerOrder.totalNetCent = totalNetCent;
customerOrder.totalVatCent = totalVatCent;
customerOrder.totalGrossCent = totalNetCent + totalVatCent;
return customerOrder;
}
public static class Result {
public final CustomerOrder customerOrder;
public final WarehouseBooking warehouseBooking;
public final List<Booking> bookings;
Result(CustomerOrder customerOrder, WarehouseBooking warehouseBooking, List<Booking> bookings) {
this.customerOrder = customerOrder;
this.warehouseBooking = warehouseBooking;
this.bookings = bookings;
}
}
private static class OrderItem {
List<WarehouseBookingPositionSlotEntry> availableSlots;
int quantity;
Article article;
public OrderItem(Article article, List<WarehouseBookingPositionSlotEntry> availableSlots, int quantity) {
this.article = article;
this.availableSlots = availableSlots;
this.quantity = quantity;
}
}
}

View File

@ -0,0 +1,11 @@
package org.hso.ecommerce.action.shop;
import org.hso.ecommerce.entities.shop.CustomerOrder;
public class EnableTrackingAction {
public static void addTrackingInfo(CustomerOrder customerOrder) {
// TODO:
customerOrder.trackingId = "555-NASE";
}
}

View File

@ -1,7 +0,0 @@
package org.hso.ecommerce.action.somepackage;
public class DemoAction {
// TODO: remove me.
// mksubpackage
}

View File

@ -1,14 +1,23 @@
package org.hso.ecommerce.controller.shop;
import org.hso.ecommerce.action.shop.CreateOrderAction;
import org.hso.ecommerce.action.shop.EnableTrackingAction;
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
import org.hso.ecommerce.entities.booking.PaymentMethod;
import org.hso.ecommerce.entities.shop.Address;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.shop.ShoppingCart;
import org.hso.ecommerce.entities.user.User;
import org.hso.ecommerce.repos.booking.BookingAccountEntryRepository;
import org.hso.ecommerce.repos.booking.BookingRepository;
import org.hso.ecommerce.repos.shop.ArticleRepository;
import org.hso.ecommerce.repos.shop.CustomerOderRepository;
import org.hso.ecommerce.repos.user.UserRepository;
import org.hso.ecommerce.repos.warehouse.WarehouseBookingPositionSlotEntryRepository;
import org.hso.ecommerce.repos.warehouse.WarehouseBookingRepository;
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 org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@ -19,9 +28,27 @@ import java.util.TreeMap;
@RequestMapping("/shop/")
public class ShopCheckoutController {
@Autowired
private final UserRepository userRepository = null;
@Autowired
private final ArticleRepository articleRepository = null;
@Autowired
private final BookingAccountEntryRepository bookingEntryRepository = null;
@Autowired
private final BookingRepository bookingRepository = null;
@Autowired
private final WarehouseBookingRepository warehouseBookingRepository = null;
@Autowired
private final CustomerOderRepository customerOderRepository = null;
@Autowired
private final WarehouseBookingPositionSlotEntryRepository wbeseRepo = null;
@GetMapping("/checkout")
public String shopCheckout(HttpSession session,
HttpServletRequest request,
@ -69,7 +96,43 @@ public class ShopCheckoutController {
}
@PostMapping("/checkoutFinish")
public String shopCheckoutFinish() {
public String shopCheckoutFinish(
@RequestAttribute(value = "user") User user,
@RequestAttribute(value = "shoppingCart") ShoppingCart shoppingCart,
@RequestParam("address") String address,
@RequestParam("cardnumber") String cardnumber,
@RequestParam("shopping_cart_revision") Integer cartRevision,
@RequestParam("expected_total") Integer expectedPrice
) {
// Must be refetched for persitence.
user = userRepository.findById(user.id).get();
CreateOrderAction action = new CreateOrderAction(
user,
expectedPrice,
Address.fromString(address),
PaymentMethod.fromCreditCarNumber(cardnumber),
bookingEntryRepository.getByUser(user).orElse(BookingAccountEntry.newUser(user)),
bookingEntryRepository.getByVat().orElse(BookingAccountEntry.newVat()),
bookingEntryRepository.getByMain().orElse(BookingAccountEntry.newMain())
);
for (ShoppingCart.ShoppingCartItem item : shoppingCart.getItems()) {
Article article = articleRepository.findById(item.getArticleId()).get();
action.addArticle(article, item.getAmount(), wbeseRepo.getByArticle(article));
}
CreateOrderAction.Result result = action.finish();
EnableTrackingAction.addTrackingInfo(result.customerOrder);
customerOderRepository.save(result.customerOrder);
bookingRepository.saveAll(result.bookings);
warehouseBookingRepository.save(result.warehouseBooking);
shoppingCart.clear();
return "shop/checkoutFinish";
}

View File

@ -14,12 +14,12 @@ public class Booking {
// always >= 0
public int amountCent;
@ManyToOne(optional = true)
@ManyToOne(optional = true, cascade = CascadeType.ALL)
public BookingAccountEntry source;
@ManyToOne(optional = true)
@ManyToOne(optional = true, cascade = CascadeType.ALL)
public BookingAccountEntry destination;
@OneToOne(optional = false)
@OneToOne(optional = false, cascade = CascadeType.ALL)
public BookingReason reason;
}

View File

@ -16,13 +16,49 @@ public class BookingAccountEntry {
public int newSumCent;
@ManyToOne(optional = true)
@ManyToOne(optional = true, cascade = CascadeType.ALL)
public User userAccount;
@ManyToOne(optional = true)
@ManyToOne(optional = true, cascade = CascadeType.ALL)
public Supplier supplierAccount;
public boolean isMainAccount;
public boolean isVATAccount;
public BookingAccountEntry copyAddAmount(int amountCent) {
BookingAccountEntry e = new BookingAccountEntry();
e.userAccount = userAccount;
e.supplierAccount = supplierAccount;
e.isMainAccount = isMainAccount;
e.isVATAccount = isVATAccount;
e.newSumCent = newSumCent + amountCent;
return e;
}
public static BookingAccountEntry newUser(User user) {
BookingAccountEntry e = new BookingAccountEntry();
e.userAccount = user;
e.newSumCent = 0;
return e;
}
public static BookingAccountEntry newMain() {
BookingAccountEntry e = new BookingAccountEntry();
e.isMainAccount = true;
e.newSumCent = 0;
return e;
}
public static BookingAccountEntry newVat() {
BookingAccountEntry e = new BookingAccountEntry();
e.isVATAccount = true;
e.newSumCent = 0;
return e;
}
}

View File

@ -22,9 +22,22 @@ public class BookingReason {
@ManyToOne(optional = true)
public CustomerOrder customerOrder;
@ManyToOne(optional = true)
@OneToOne(optional = true, cascade = CascadeType.ALL)
public CustomerPayment customerPayment;
@ManyToOne(optional = true)
public SupplierOrder supplierOrder;
public BookingReason() {
}
;
Review

Das kann auch weg.

Das kann auch weg.
Review

Nope, ORM braucht nen leeren Konstruktor. Ich mach ein Kommentar drüber. 713c8ebe86

Nope, ORM braucht nen leeren Konstruktor. Ich mach ein Kommentar drüber. 713c8ebe86faffcde94f076956bdc5d02fe3ddaa
Review

Ich meinte auch das Semikolon.

Ich meinte auch das Semikolon.
public BookingReason(CustomerOrder order) {
this.customerOrder = order;
}
public BookingReason(CustomerPayment customerPayment) {
this.customerPayment = customerPayment;
}
}

View File

@ -7,4 +7,11 @@ import javax.validation.constraints.NotNull;
public class PaymentMethod {
@NotNull
public String creditCardNumber;
public static PaymentMethod fromCreditCarNumber(String cardnumber) {
PaymentMethod m = new PaymentMethod();
m.creditCardNumber = cardnumber;
return m;
}
}

View File

@ -4,7 +4,24 @@ import javax.persistence.Embeddable;
@Embeddable
public class Address {
public String name;
public String addressString;
public String name = "";
public String addressString = "";
public String country = "DE";
@Override
public String toString() {
return name + "\n" + addressString;
}
public static Address fromString(String addr) {
Address a = new Address();
String[] arr = addr.split("\n", 2);
a.name = arr[0];
if (arr.length > 1) {
a.addressString = arr[1];
}
return a;
}
}

View File

@ -24,7 +24,7 @@ public class CustomerOrder {
@OneToMany(
targetEntity = CustomerOrderPosition.class,
mappedBy = "order"
mappedBy = "order", cascade = CascadeType.ALL
)
public List<CustomerOrderPosition> positions = new ArrayList<>();

View File

@ -6,12 +6,18 @@ import java.util.List;
// Not a db entity. Just for session storage
public class ShoppingCart {
private final static int MAX_ITEMS = 10;
private int revision;
private ArrayList<ShoppingCartItem> items;
public ShoppingCart() {
revision = (int) Math.round(Math.random() * 0xFFFF);
clear();
}
public void clear() {
items = new ArrayList<>();
revision = (int) Math.round(Math.random() * 0xFFFF);
}
public List<ShoppingCartItem> getItems() {
@ -60,7 +66,7 @@ public class ShoppingCart {
items.add(new ShoppingCartItem(quantity, article));
}
items.removeIf(i -> i.getAmount() == 0);
items.removeIf(i -> i.getAmount() <= 0);
}
public static class ShoppingCartItem {
@ -78,6 +84,9 @@ public class ShoppingCart {
public void addAmount(int amount) {
this.amount += amount;
if (this.amount > MAX_ITEMS) {
this.amount = MAX_ITEMS;
}
}
public long getArticleId() {
@ -86,6 +95,9 @@ public class ShoppingCart {
public void setAmount(Integer amount) {
this.amount = amount;
if (this.amount > MAX_ITEMS) {
this.amount = MAX_ITEMS;
}
}
}
}

View File

@ -30,10 +30,10 @@ public class User {
public boolean isEmployee;
@Embedded
private Address defaultDeliveryAddress;
public Address defaultDeliveryAddress;
@Embedded
private PaymentMethod defaultPayment;
public PaymentMethod defaultPayment;
public long getId() {
return id;

View File

@ -1,5 +1,7 @@
package org.hso.ecommerce.entities.warehouse;
import org.hso.ecommerce.entities.booking.BookingReason;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
@ -21,7 +23,10 @@ public class WarehouseBooking {
public boolean isDone;
@OneToMany(
mappedBy = "booking"
mappedBy = "booking", cascade = CascadeType.ALL
)
public List<WarehouseBookingPosition> positions = new ArrayList<>();
@OneToOne(optional = false, cascade = CascadeType.ALL)
public BookingReason reason;
}

View File

@ -23,10 +23,6 @@ public class WarehouseBookingPosition {
public int amount; // positive or negative
@ManyToOne(optional = true)
public WarehouseBookingPositionSlotEntry source;
@ManyToOne(optional = true)
public WarehouseBookingPositionSlotEntry destination;
@ManyToOne(optional = true, cascade = CascadeType.ALL)
public WarehouseBookingPositionSlotEntry slotEntry;
}

View File

@ -16,8 +16,23 @@ public class WarehouseBookingPositionSlotEntry {
@ManyToOne
public Article article;
public int newSumArticles;
public int newSumWarehousePosition;
// Can;t do, does not work when created in action.
//public int newSumArticles;
public int newSumSlot;
Review

removed bd2aeb63f6

removed bd2aeb63f6ea5a3c0d2f78cde2ff8f5691061f30
public int slot;
public WarehouseBookingPositionSlotEntry copyAddAmount(int amount) {
WarehouseBookingPositionSlotEntry e = new WarehouseBookingPositionSlotEntry();
e.article = article;
e.slot = slot;
e.newSumSlot = newSumSlot + amount;
assert e.article.warehouseUnitsPerSlot >= e.newSumSlot;
assert e.newSumSlot >= 0;
return e;
}
}

View File

@ -23,4 +23,11 @@ public class WarehouseBookingReason {
public CustomerOrder customerOrder;
public boolean isManuel;
public WarehouseBookingReason() {
}
public WarehouseBookingReason(CustomerOrder order) {
this.customerOrder = order;
}
}

View File

@ -0,0 +1,26 @@
package org.hso.ecommerce.repos.booking;
import org.hso.ecommerce.entities.booking.BookingAccountEntry;
import org.hso.ecommerce.entities.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface BookingAccountEntryRepository extends JpaRepository<BookingAccountEntry, Long> {
@Query("SELECT e FROM BookingAccountEntry e WHERE e.userAccount = :user ORDER BY e.id DESC")
Optional<BookingAccountEntry> getByUser(User user);
@Query("SELECT e FROM BookingAccountEntry e WHERE e.isMainAccount = 1 ORDER BY e.id DESC")
Optional<BookingAccountEntry> getByMain();
@Query("SELECT e FROM BookingAccountEntry e WHERE e.isVATAccount = 1 ORDER BY e.id DESC")
Optional<BookingAccountEntry> getByVat();
}

View File

@ -0,0 +1,12 @@
package org.hso.ecommerce.repos.booking;
import org.hso.ecommerce.entities.booking.Booking;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface BookingRepository extends JpaRepository<Booking, Long> {
}

View File

@ -0,0 +1,11 @@
package org.hso.ecommerce.repos.shop;
import org.hso.ecommerce.entities.shop.CustomerOrder;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CustomerOderRepository extends JpaRepository<CustomerOrder, Long> {
}

View File

@ -0,0 +1,18 @@
package org.hso.ecommerce.repos.warehouse;
import org.hso.ecommerce.entities.shop.Article;
import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface WarehouseBookingPositionSlotEntryRepository extends JpaRepository<WarehouseBookingPositionSlotEntry, Long> {
// TODO this is wrong. revisit.
@Query("SELECT e FROM WarehouseBookingPositionSlotEntry e WHERE e.article = :article ORDER BY e.id DESC")
List<WarehouseBookingPositionSlotEntry> getByArticle(Article article);
}

View File

@ -0,0 +1,11 @@
package org.hso.ecommerce.repos.warehouse;
import org.hso.ecommerce.entities.warehouse.WarehouseBooking;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface WarehouseBookingRepository extends JpaRepository<WarehouseBooking, Long> {
}

View File

@ -21,7 +21,17 @@
</div>
<nav></nav>
</div>
<main class="content-width sidebar-layout" style="min-height: 100vh;">
<main th:if="${checkoutItems.size() == 0}">
<div class="detailflex m">
<h2> Noch keine Artikel im Warenkorb. </h2>
<p>
<img th:src="@{/img/undraw_successful_purchase_secondary.svg}"/>
</p>
<a class="button" th:href="@{/}"> Weiter shoppen </a>
</div>
</main>
<main th:if="${checkoutItems.size() > 0}" class="content-width sidebar-layout" style="min-height: 100vh;">
<div style="max-width: 45em; width: 100%;">
<table>
<tr>
@ -37,7 +47,9 @@
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><span
th:text="${#numbers.formatDecimal(item.article.getPriceGross(), 1, 'POINT', 2, 'COMMA')}"></span>
EUR <b>x</b></td>
<td>
<form method="POST" th:action="@{/shop/articles/{id}(id = ${item.article.id})}">
<input type="hidden" name="fastcheckout" value="true"/>
@ -45,11 +57,9 @@
<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>
<option th:each="quantity : ${#numbers.sequence(1,10)}"
th:value="${quantity}"
th:text="${quantity}"></option>
</select>
<button class="small">Ändern</button>
</form>
@ -64,11 +74,16 @@
<h1>Checkout</h1>
</div>
<div th:if="${user}">
<input type="hidden" name="shopping_cart_revision" th:value="${shoppingCart.getRevision()}"/>
<input type="hidden" name="expected_total" th:value="${checkoutTotals.total}"/>
<h2>Lieferadresse:</h2>
<textarea rows="5" class="full-width" type="text" name="address"
placeholder="Optional: Zusatz&#10;Optional: Unternehmen&#10;Straße Hausnummer&#10;Postleitzeit Ort&#10;Land">
placeholder="Name&#10;Optional: Zusatz&#10;Optional: Unternehmen&#10;Straße Hausnummer&#10;Postleitzeit Ort&#10;Land"
th:text="${user.defaultDeliveryAddress != null ? user.defaultDeliveryAddress.toString() : ''}"
required>
Max Mustermann
Musterstraße 42
Musterstraße 4
42424 Mustertal
</textarea>
</div>
@ -78,12 +93,10 @@ Musterstraße 42
<input type="radio" name="type" value="priv" id="payment-card" required checked>
<label for="payment-card">Kartenzahlung</label> <br/>
<input class="full-width" type="text" id="cardnumber" name="cardnumber" placeholder="Kartennummer"
th:value="${user.defaultPayment != null ? user.defaultPayment.creditCardNumber : ''}"
pattern="[0-9]{6,16}"
required/>
</fieldset>
<fieldset>
<input class="" type="checkbox" id="bonus" name="bonus" checked/>
<label for="bonus"><h3>10 gesammelte Bonuspunkte verwenden</h3></label>
</fieldset>
</div>
<div>
<h2>Bestellübersicht</h2>