package catering.order; import catering.catalog.Rentable; import catering.staff.Employee; import org.javamoney.moneta.Money; import org.salespointframework.inventory.UniqueInventory; import org.salespointframework.inventory.UniqueInventoryItem; import org.salespointframework.order.Cart; import org.salespointframework.order.CartItem; import org.salespointframework.order.OrderLine; import javax.money.MonetaryAmount; import java.time.Duration; import java.time.LocalDateTime; import java.util.HashSet; import java.util.Set; public class CustomCart extends Cart { private Set staff; private OrderType orderType; private LocalDateTime start; private LocalDateTime finish; private final String formatterPattern; // Constructor public CustomCart(OrderType orderType, LocalDateTime start, LocalDateTime finish) { super(); this.staff = new HashSet<>(); this.orderType = orderType; this.start = start; this.finish = finish; this.formatterPattern = "dd.MM.yyyy, HH:mm 'Uhr'"; } /** * Adds an employee to the cart */ public boolean addEmployee(Employee employee) { for (Employee myEmployee : staff) { if (myEmployee.equals(employee)) { return false; } } return staff.add(employee); } public Set getStaff() { return staff; } public boolean removeEmployee(Employee employee) { for (Employee myEmployee : staff) { if (myEmployee.equals(employee)) { return staff.remove(myEmployee); } } return false; } /** * Add staff to order (analogous to cart.addItemsTo(order)) */ public CustomOrder addStaffTo(CustomOrder order) { for (Employee employee : staff) { order.addEmployee(employee); } return order; } /** * Add ChargeLines for rental costs of each Rentable to {@param order} */ public CustomOrder addRentablesToOrder(CustomOrder order, UniqueInventory inventory) { for (CartItem item : this) { if (item.getProduct() instanceof Rentable rentable) { OrderLine orderLine = order.getOrderLines(rentable).stream().findFirst().get(); order.addChargeLine( rentable.getPrice() .multiply(getDurationInHours()) .multiply(item.getQuantity().getAmount()), "rental costs", orderLine ); // neutralises automatic reduction of rentables in inventory inventory.save(inventory.findByProduct(rentable).get().increaseQuantity(orderLine.getQuantity())); } } return order; } public OrderType getOrderType() { return orderType; } public void setOrderType(OrderType orderType) { this.orderType = orderType; } public LocalDateTime getStart() { return start; } public void setStart(LocalDateTime start) { this.start = start; } /** * @return hours between start and finish */ public int getDurationInHours() { return (int) (Duration.between(start, finish).getSeconds() / 3600); } public LocalDateTime getFinish() { return finish; } public void setFinish(LocalDateTime finish) { this.finish = finish; } public String getFormatterPattern() { return formatterPattern; } @Override public MonetaryAmount getPrice() { MonetaryAmount total = Money.of(0, "EUR"); for (CartItem item : this) { if (item.getProduct() instanceof Rentable rentable) { // final_price = (price + price * time) * quantity total = total.add(rentable.getPriceForTime(getDurationInHours()).multiply(item.getQuantity().getAmount())); } else { total = total.add(item.getProduct().getPrice().multiply(item.getQuantity().getAmount())); } } for (Employee employee : staff) { total = total.add(Money.of(getDurationInHours() * employee.getWage(), "EUR")); } return total; } @Override public void clear() { super.clear(); staff = new HashSet<>(); } }