2023-11-05 10:39:39 +01:00
package catering.order ;
2023-11-20 22:08:08 +01:00
import jakarta.persistence.PostPersist ;
2023-11-19 13:00:21 +01:00
import org.salespointframework.catalog.Product ;
import org.salespointframework.inventory.UniqueInventory ;
import org.salespointframework.inventory.UniqueInventoryItem ;
2023-11-20 22:08:08 +01:00
import org.salespointframework.order.* ;
2023-11-19 13:00:21 +01:00
import org.salespointframework.quantity.Quantity ;
import org.salespointframework.time.Interval ;
import org.salespointframework.useraccount.Role ;
import org.salespointframework.useraccount.UserAccount ;
import org.salespointframework.useraccount.web.LoggedIn ;
import org.springframework.data.domain.Pageable ;
2023-11-21 22:59:04 +01:00
import org.springframework.data.domain.Sort ;
2023-11-20 22:08:08 +01:00
import org.springframework.data.jpa.repository.query.Procedure ;
2023-11-19 13:00:21 +01:00
import org.springframework.security.access.prepost.PreAuthorize ;
2023-11-05 10:39:39 +01:00
import org.springframework.stereotype.Controller ;
2023-11-05 12:33:43 +01:00
import org.springframework.ui.Model ;
2023-11-07 20:53:31 +01:00
import org.springframework.web.bind.annotation.* ;
2023-11-05 10:39:39 +01:00
2023-11-07 22:23:48 +01:00
import java.time.LocalDateTime ;
2023-11-12 14:42:07 +01:00
import java.time.LocalDate ;
2023-11-20 22:08:08 +01:00
import java.time.LocalTime ;
2023-11-15 00:31:09 +01:00
import java.time.temporal.ChronoUnit ;
2023-11-15 00:34:16 +01:00
import java.time.format.DateTimeFormatter ;
2023-11-20 22:08:08 +01:00
import java.time.temporal.TemporalUnit ;
2023-11-21 22:59:04 +01:00
import java.util.* ;
2023-11-19 13:00:21 +01:00
import java.util.stream.Collectors ;
2023-11-05 15:36:46 +01:00
2023-11-12 14:42:07 +01:00
2023-11-05 10:39:39 +01:00
@Controller
2023-11-19 13:00:21 +01:00
@PreAuthorize ( " isAuthenticated() " )
@SessionAttributes ( " event " )
2023-11-05 10:39:39 +01:00
public class OrderController {
2023-11-19 13:00:21 +01:00
private final OrderManagement < CustomOrder > orderManagement ;
private final UniqueInventory < UniqueInventoryItem > inventory ;
2023-11-05 12:33:43 +01:00
2023-11-19 13:00:21 +01:00
public OrderController ( OrderManagement < CustomOrder > orderManagement , UniqueInventory < UniqueInventoryItem > inventory ) {
this . orderManagement = orderManagement ;
this . inventory = inventory ;
2023-11-05 12:33:43 +01:00
}
2023-11-19 13:00:21 +01:00
@GetMapping ( " /myOrders " )
@PreAuthorize ( " hasRole('CUSTOMER') " )
public String orders ( Model model , @LoggedIn Optional < UserAccount > userAccount ) {
List < CustomOrder > myOrders = orderManagement . findBy ( userAccount . get ( ) ) . stream ( ) . collect ( Collectors . toList ( ) ) ; // to be changed
model . addAttribute ( " orders " , myOrders ) ;
model . addAttribute ( " total " , myOrders . size ( ) ) ;
2023-11-20 22:08:08 +01:00
model . addAttribute ( " cancelled " , OrderStatus . CANCELED ) ;
model . addAttribute ( " completed " , OrderStatus . COMPLETED ) ;
2023-11-19 13:00:21 +01:00
return " orders " ;
}
@GetMapping ( " /allOrders " )
@PreAuthorize ( " hasRole('ADMIN') " )
2023-11-05 12:33:43 +01:00
public String orders ( Model model ) {
2023-11-19 13:00:21 +01:00
List < CustomOrder > myOrders = orderManagement . findAll ( Pageable . unpaged ( ) ) . stream ( ) . collect ( Collectors . toList ( ) ) ;
model . addAttribute ( " orders " , myOrders ) ;
model . addAttribute ( " total " , myOrders . size ( ) ) ;
2023-11-20 22:08:08 +01:00
model . addAttribute ( " cancelled " , OrderStatus . CANCELED ) ;
model . addAttribute ( " completed " , OrderStatus . COMPLETED ) ;
2023-11-05 12:33:43 +01:00
return " orders " ;
}
2023-11-05 16:41:22 +01:00
2023-11-14 20:31:12 +01:00
// For Theo: filters orders by day
2023-11-19 13:00:21 +01:00
@GetMapping ( " /allOrders/{day} " )
@PreAuthorize ( " hasRole('ADMIN') " )
2023-11-14 20:31:12 +01:00
public String orders ( @PathVariable String day , Model model ) {
// Obtains an instance of LocalDate from a text string such as 2007-12-03. (https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html)
LocalDate date = LocalDate . parse ( day ) ;
2023-11-19 13:00:21 +01:00
List < CustomOrder > myOrders = orderManagement . findAll ( Pageable . unpaged ( ) ) . stream ( ) . filter (
order - >
( order . getStart ( ) . toLocalDate ( ) . isBefore ( date ) | | order . getStart ( ) . toLocalDate ( ) . isEqual ( date ) )
& & ( order . getFinish ( ) . toLocalDate ( ) . isAfter ( date ) | | order . getFinish ( ) . toLocalDate ( ) . isEqual ( date ) )
) . collect ( Collectors . toList ( ) ) ;
2023-11-14 20:31:12 +01:00
model . addAttribute ( " orders " , myOrders ) ;
model . addAttribute ( " total " , myOrders . size ( ) ) ;
return " orders " ;
}
2023-11-19 13:00:21 +01:00
@ModelAttribute ( " event " )
CustomCart initializeCart ( ) {
2023-11-20 22:08:08 +01:00
return new CustomCart ( OrderType . SOMETHING_ELSE , LocalDateTime . now ( ) . plusDays ( 7 ) , LocalDateTime . now ( ) . plusDays ( 7 ) ) ;
2023-11-19 13:00:21 +01:00
}
2023-11-07 17:50:29 +01:00
@GetMapping ( " /event " )
2023-11-19 13:00:21 +01:00
@PreAuthorize ( " hasRole('CUSTOMER') " )
public String event ( Model model , @ModelAttribute ( " event " ) CustomCart cart ) {
model . addAttribute ( " items " , cart . stream ( ) . collect ( Collectors . toList ( ) ) ) ;
model . addAttribute ( " totalPrice " , cart . getPrice ( ) ) ;
model . addAttribute ( " invItems " , inventory . findAll ( ) . stream ( ) . collect ( Collectors . toList ( ) ) ) ;
2023-11-07 20:53:31 +01:00
return " event " ;
2023-11-07 17:50:29 +01:00
}
2023-11-19 13:00:21 +01:00
@PostMapping ( " /allOrders/remove " )
2023-11-21 23:51:56 +01:00
@PreAuthorize ( " hasRole('ADMIN') " )
2023-11-19 13:00:21 +01:00
public String removeOrder ( @RequestParam Order . OrderIdentifier orderID , @LoggedIn Optional < UserAccount > userAccount ) {
return userAccount . map ( account - > {
if ( account . hasRole ( Role . of ( " ADMIN " ) ) ) {
CustomOrder myOrder = orderManagement . get ( orderID ) . get ( ) ; // FIXME
orderManagement . cancelOrder ( myOrder , " I have my own reasons. " ) ;
return " redirect:/allOrders " ;
}
return " redirect:/ " ;
} ) . orElse ( " redirect:/ " ) ;
2023-11-05 16:41:22 +01:00
}
2023-11-07 20:53:31 +01:00
@PostMapping ( " /event/addProduct " )
2023-11-19 13:00:21 +01:00
@PreAuthorize ( " hasRole('CUSTOMER') " )
public String addProduct ( @RequestParam ( " pid " ) Product product , @RequestParam ( " number " ) int number , @ModelAttribute ( " event " ) CustomCart cart ) {
2023-11-20 22:08:08 +01:00
Quantity amount = Quantity . of ( number > 0 ? number : 1 ) ;
2023-11-19 13:00:21 +01:00
Quantity invAmount = inventory . findByProduct ( product ) . get ( ) . getQuantity ( ) ; // TODO ERROR HANDLING
Quantity cartQuantity = cart . getQuantity ( product ) ;
// check for possible miss-inputs
if ( amount . add ( cartQuantity ) . isGreaterThan ( invAmount ) ) {
cart . addOrUpdateItem ( product , cartQuantity . negate ( ) . add ( invAmount ) ) ;
} else {
cart . addOrUpdateItem ( product , amount ) ;
}
2023-11-07 20:53:31 +01:00
return " redirect:/event " ;
}
2023-11-07 22:23:48 +01:00
2023-11-20 22:08:08 +01:00
@PostMapping ( " /event/removeProduct " )
@PreAuthorize ( " hasRole('CUSTOMER') " )
public String removeProduct ( @RequestParam ( " itemId " ) String itemId , @ModelAttribute ( " event " ) CustomCart cart ) {
cart . removeItem ( itemId ) ;
return " redirect:/event " ;
}
@PostMapping ( " /event/changeDate " )
@PreAuthorize ( " hasRole('CUSTOMER') " )
public String changeDate ( @RequestParam ( " startDate " ) LocalDate start , @RequestParam ( " startHour " ) Optional < Integer > startHour , @RequestParam ( " finishDate " ) LocalDate finish , @RequestParam ( " finishHour " ) Optional < Integer > finishHour , @ModelAttribute ( " event " ) CustomCart cart ) {
int unwrappedStartHour = startHour . orElse ( cart . getStart ( ) . getHour ( ) ) ;
int unwrappedFinishHour = finishHour . orElse ( cart . getFinish ( ) . getHour ( ) ) ;
finish = finish . isBefore ( start ) ? start : finish ;
LocalDateTime startTime = LocalDateTime . of ( start , LocalTime . of ( unwrappedStartHour , 0 ) ) ; // TODO
LocalDateTime finishTime = LocalDateTime . of ( finish , LocalTime . of ( unwrappedFinishHour < = unwrappedStartHour ? unwrappedStartHour + 1 : unwrappedFinishHour , 0 ) ) ; // TODO
cart . setStart ( startTime ) ;
cart . setFinish ( finishTime ) ;
return " redirect:/event " ;
}
2023-11-07 22:23:48 +01:00
@PostMapping ( " /event/checkout " )
2023-11-19 13:00:21 +01:00
@PreAuthorize ( " hasRole('CUSTOMER') " )
2023-11-20 22:08:08 +01:00
public String checkout ( @ModelAttribute ( " event " ) CustomCart cart , @LoggedIn Optional < UserAccount > userAccount ) {
if ( cart . isEmpty ( ) ) {
return " redirect:/event " ;
}
2023-11-19 13:00:21 +01:00
return userAccount . map ( account - > {
CustomOrder myOrder = new CustomOrder ( account . getId ( ) , cart ) ;
cart . addItemsTo ( myOrder ) ;
orderManagement . payOrder ( myOrder ) ; // TODO: change this later
orderManagement . completeOrder ( myOrder ) ;
cart . clear ( ) ;
return " redirect:/myOrders " ;
} ) . orElse ( " redirect:/event " ) ;
2023-11-07 22:23:48 +01:00
}
@PostMapping ( " /event/changeOrderType " )
2023-11-19 13:00:21 +01:00
@PreAuthorize ( " hasRole('CUSTOMER') " )
public String changeOrderType ( @RequestParam ( name = " type " ) Optional < String > optionalOrderType , @ModelAttribute ( " event " ) CustomCart cart ) {
2023-11-09 22:17:47 +01:00
String orderType = optionalOrderType . orElse ( " FOO " ) ;
2023-11-07 22:23:48 +01:00
switch ( orderType ) {
case " RaK " :
2023-11-19 13:00:21 +01:00
cart . setOrderType ( OrderType . RENT_A_COOK ) ;
2023-11-07 22:23:48 +01:00
break ;
case " EK " :
2023-11-19 13:00:21 +01:00
cart . setOrderType ( OrderType . EVENT_CATERING ) ;
2023-11-07 22:23:48 +01:00
break ;
case " SN " :
2023-11-19 13:00:21 +01:00
cart . setOrderType ( OrderType . SUSHI_NIGHT ) ;
break ;
case " MB " :
cart . setOrderType ( OrderType . MOBILE_BREAKFAST ) ;
2023-11-07 22:23:48 +01:00
break ;
default :
2023-11-19 13:00:21 +01:00
cart . setOrderType ( OrderType . SOMETHING_ELSE ) ;
2023-11-07 22:23:48 +01:00
}
return " redirect:/event " ;
}
2023-11-21 22:59:04 +01:00
@GetMapping ( " /orders/calender " )
public String calender ( Model model ) {
ArrayList < ArrayList < String > > datesOfMonth = new ArrayList < ArrayList < String > > ( 28 ) ;
LocalDateTime startDateTime = LocalDateTime . now ( ) ;
LocalDateTime endDateTime = startDateTime . plusDays ( 27 ) . withHour ( 23 ) . withMinute ( 59 ) . withSecond ( 59 ) ; // FIXME: set me to end of day
LocalDate startDate = startDateTime . toLocalDate ( ) ;
LocalDate endDate = endDateTime . toLocalDate ( ) ;
// create all dates of the calender
for ( LocalDate date = startDate ; ! date . isAfter ( endDate ) ; date = date . plusDays ( 1 ) ) {
ArrayList < String > x = new ArrayList < String > ( 2 ) ;
x . add ( Integer . toString ( date . getDayOfMonth ( ) ) ) ;
x . add ( date . toString ( ) ) ;
datesOfMonth . add ( x ) ;
}
// add each order overlapping with the calender to the days it overlaps with
for ( CustomOrder order : this . orderManagement . findBy ( Interval . from ( startDateTime ) . to ( endDateTime ) ) ) {
int start_index_inclusive = Math . max ( ( int ) startDate . until ( order . getStart ( ) . toLocalDate ( ) , ChronoUnit . DAYS ) , 0 ) ;
int end_index_exclusive = Math . min ( ( int ) startDate . until ( order . getFinish ( ) . toLocalDate ( ) , ChronoUnit . DAYS ) , 27 ) + 1 ;
String order_id = Objects . requireNonNull ( order . getId ( ) ) . toString ( ) ;
for ( int i = start_index_inclusive ; i < end_index_exclusive ; i + + ) {
datesOfMonth . get ( i ) . add ( order_id ) ;
}
}
// get names of weekdays for table header starting with the current day
LocalDate endOfWeekDate = startDate . plusDays ( 6 ) ;
ArrayList < String > dayNames = new ArrayList < String > ( 7 ) ;
for ( LocalDate date = startDate ; ! date . isAfter ( endOfWeekDate ) ; date = date . plusDays ( 1 ) ) {
dayNames . add ( date . getDayOfWeek ( ) . toString ( ) ) ;
}
ArrayList < ArrayList < ArrayList < String > > > weeksOfMonth = new ArrayList < ArrayList < ArrayList < String > > > ( ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
weeksOfMonth . add ( new ArrayList < ArrayList < String > > ( 7 ) ) ;
for ( int j = 0 ; j < 7 ; j + + ) {
weeksOfMonth . get ( i ) . add ( new ArrayList < String > ( ) ) ;
weeksOfMonth . get ( i ) . get ( j ) . addAll ( datesOfMonth . get (
( i = = 0 ) ? j : ( j = = 0 ) ? i : i * j
)
) ;
}
}
model . addAttribute ( " weeksOfMonth " , weeksOfMonth ) ;
model . addAttribute ( " dayNames " , dayNames ) ;
return " orders_calender " ;
}
2023-11-05 10:39:39 +01:00
}