package catering.order; import catering.staff.Employee; import jakarta.persistence.*; import org.javamoney.moneta.Money; import org.salespointframework.order.Order; import org.salespointframework.payment.Cash; import org.salespointframework.useraccount.UserAccount; import org.springframework.data.annotation.Id; import javax.money.MonetaryAmount; import java.time.Duration; import java.time.LocalDateTime; import java.time.YearMonth; import java.time.format.DateTimeFormatter; import java.util.HashSet; import java.util.Set; @Entity public class CustomOrder extends Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToMany private Set staff; private OrderType orderType = OrderType.EVENT_CATERING; private LocalDateTime start; private LocalDateTime finish; private boolean invoiceAvailable = false; private String formatterPattern = "dd.MM.yyyy, HH:mm 'Uhr'"; // Constructor public CustomOrder(UserAccount.UserAccountIdentifier identifier, CustomCart cart) { super(identifier, Cash.CASH); this.staff = new HashSet<>(); this.orderType = cart.getOrderType(); this.start = cart.getStart(); this.finish = cart.getFinish(); this.formatterPattern = cart.getFormatterPattern(); } public CustomOrder() { } private long getDurationInSeconds(LocalDateTime start, LocalDateTime finish) { if (start.compareTo(finish) > 0) { return 0; } return Duration.between(start, finish).getSeconds(); } /** * Helper function to get the amount of hours in between start and finish (analogous to CustomCart) * @return hours between start and finish */ private long getDurationInHours(LocalDateTime start, LocalDateTime finish) { return getDurationInSeconds(start, finish) / 3600; } public long getDurationInHours() { return getDurationInHours(start, finish); } private static LocalDateTime min(LocalDateTime a, LocalDateTime b) { return (a.compareTo(b)) < 0 ? a : b; } private static LocalDateTime max(LocalDateTime a, LocalDateTime b) { return (a.compareTo(b)) > 0 ? a : b; } public long getDurationInSecondsDuringMonth(YearMonth month) { LocalDateTime startInMonth = max(this.start, month.atDay(1).atStartOfDay()); LocalDateTime finishInMonth = min(this.finish, month.plusMonths(1).atDay(1).atStartOfDay()); return getDurationInSeconds(startInMonth, finishInMonth); } /** * Adds an employee to the order and adds a new {@Link ChangeLine} containing the costs */ public boolean addEmployee(Employee employee) { MonetaryAmount cost = Money.of(employee.getWage(), "EUR") .multiply(getDurationInHours()); if (this.staff.add(employee)) { super.addChargeLine(cost, employee.getId().toString()); return true; } return false; } public Set getStaff() { return staff; } public OrderType getOrderType() { return orderType; } public LocalDateTime getStart() { return start; } /** * @return start DateTime in a formatted manner */ public String getFormattedStart() { return start.format(DateTimeFormatter.ofPattern(formatterPattern)); } public LocalDateTime getFinish() { return finish; } /** * @return finish DateTime in a formatted manner */ public String getFormattedFinish() { return finish.format(DateTimeFormatter.ofPattern(formatterPattern)); } public boolean isInvoiceAvailable() { return invoiceAvailable; } public void setInvoiceAvailable(boolean available) { this.invoiceAvailable = available; } }