WIP feature/listedArticles #15
|
@ -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");
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package org.hso.ecommerce.action.somepackage;
|
||||
|
||||
public class DemoAction {
|
||||
// TODO: remove me.
|
||||
// mksubpackage
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public BookingReason(CustomerOrder order) {
|
||||
this.customerOrder = order;
|
||||
}
|
||||
|
||||
public BookingReason(CustomerPayment customerPayment) {
|
||||
this.customerPayment = customerPayment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ public class CustomerOrder {
|
|||
|
||||
@OneToMany(
|
||||
targetEntity = CustomerOrderPosition.class,
|
||||
mappedBy = "order"
|
||||
mappedBy = "order", cascade = CascadeType.ALL
|
||||
)
|
||||
public List<CustomerOrderPosition> positions = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,4 +23,11 @@ public class WarehouseBookingReason {
|
|||
public CustomerOrder customerOrder;
|
||||
|
||||
public boolean isManuel;
|
||||
|
||||
public WarehouseBookingReason() {
|
||||
}
|
||||
|
||||
public WarehouseBookingReason(CustomerOrder order) {
|
||||
this.customerOrder = order;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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> {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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> {
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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> {
|
||||
|
||||
}
|
||||
|
|
@ -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 Optional: Unternehmen Straße Hausnummer Postleitzeit Ort Land">
|
||||
placeholder="Name Optional: Zusatz Optional: Unternehmen Straße Hausnummer Postleitzeit Ort 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>
|
||||
|
|
Reference in New Issue