use of alfio.model.modification.TicketReservationModification in project alf.io by alfio-event.
the class ReservationFlowIntegrationTest method reserveTicket.
private String reserveTicket(String eventName) {
ReservationForm reservationForm = new ReservationForm();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("POST");
ServletWebRequest servletWebRequest = new ServletWebRequest(request);
BindingResult bindingResult = new BeanPropertyBindingResult(reservationForm, "reservation");
Model model = new BindingAwareModelMap();
RedirectAttributes redirectAttributes = new RedirectAttributesModelMap();
TicketReservationModification ticketReservation = new TicketReservationModification();
ticketReservation.setAmount(1);
ticketReservation.setTicketCategoryId(ticketCategoryRepository.findByEventId(event.getId()).stream().findFirst().map(TicketCategory::getId).orElseThrow(IllegalStateException::new));
reservationForm.setReservation(Collections.singletonList(ticketReservation));
return eventController.reserveTicket(eventName, reservationForm, bindingResult, model, servletWebRequest, redirectAttributes, Locale.ENGLISH);
}
use of alfio.model.modification.TicketReservationModification in project alf.io by alfio-event.
the class ReservationForm method validate.
public Optional<Pair<List<TicketReservationWithOptionalCodeModification>, List<ASReservationWithOptionalCodeModification>>> validate(Errors bindingResult, TicketReservationManager tickReservationManager, AdditionalServiceRepository additionalServiceRepository, EventManager eventManager, Event event) {
int selectionCount = ticketSelectionCount();
if (selectionCount <= 0) {
bindingResult.reject(ErrorsCode.STEP_1_SELECT_AT_LEAST_ONE);
return Optional.empty();
}
List<Pair<TicketReservationModification, Integer>> maxTicketsByTicketReservation = selected().stream().map(r -> Pair.of(r, tickReservationManager.maxAmountOfTicketsForCategory(event.getOrganizationId(), event.getId(), r.getTicketCategoryId()))).collect(toList());
Optional<Pair<TicketReservationModification, Integer>> error = maxTicketsByTicketReservation.stream().filter(p -> p.getKey().getAmount() > p.getValue()).findAny();
if (error.isPresent()) {
bindingResult.reject(ErrorsCode.STEP_1_OVER_MAXIMUM, new Object[] { error.get().getValue() }, null);
return Optional.empty();
}
final List<TicketReservationModification> categories = selected();
final List<AdditionalServiceReservationModification> additionalServices = selectedAdditionalServices();
final boolean validCategorySelection = categories.stream().allMatch(c -> {
TicketCategory tc = eventManager.getTicketCategoryById(c.getTicketCategoryId(), event.getId());
return OptionalWrapper.optionally(() -> eventManager.findEventByTicketCategory(tc)).isPresent();
});
final boolean validAdditionalServiceSelected = additionalServices.stream().allMatch(asm -> {
AdditionalService as = eventManager.getAdditionalServiceById(asm.getAdditionalServiceId(), event.getId());
ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
return as.getInception(event.getZoneId()).isBefore(now) && as.getExpiration(event.getZoneId()).isAfter(now) && asm.getQuantity() >= 0 && ((as.isFixPrice() && asm.isQuantityValid(as, selectionCount)) || (!as.isFixPrice() && asm.getAmount() != null && asm.getAmount().compareTo(BigDecimal.ZERO) >= 0)) && OptionalWrapper.optionally(() -> eventManager.findEventByAdditionalService(as)).isPresent();
});
if (!validCategorySelection || !validAdditionalServiceSelected) {
bindingResult.reject(ErrorsCode.STEP_1_TICKET_CATEGORY_MUST_BE_SALEABLE);
return Optional.empty();
}
List<TicketReservationWithOptionalCodeModification> res = new ArrayList<>();
//
Optional<SpecialPrice> specialCode = Optional.ofNullable(StringUtils.trimToNull(promoCode)).flatMap((trimmedCode) -> tickReservationManager.getSpecialPriceByCode(trimmedCode));
//
final ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
maxTicketsByTicketReservation.forEach((pair) -> validateCategory(bindingResult, tickReservationManager, eventManager, event, pair.getRight(), res, specialCode, now, pair.getLeft()));
return bindingResult.hasErrors() ? Optional.empty() : Optional.of(Pair.of(res, additionalServices.stream().map(as -> new ASReservationWithOptionalCodeModification(as, specialCode)).collect(Collectors.toList())));
}
use of alfio.model.modification.TicketReservationModification in project alf.io by alfio-event.
the class EventController method makeSimpleReservation.
private String makeSimpleReservation(String eventName, ServletWebRequest request, RedirectAttributes redirectAttributes, Locale locale, String trimmedCode, Event event, int ticketCategoryId) {
ReservationForm form = new ReservationForm();
form.setPromoCode(trimmedCode);
TicketReservationModification reservation = new TicketReservationModification();
reservation.setAmount(1);
reservation.setTicketCategoryId(ticketCategoryId);
form.setReservation(Collections.singletonList(reservation));
return validateAndReserve(eventName, form, new BeanPropertyBindingResult(form, "reservationForm"), request, redirectAttributes, locale, event);
}
use of alfio.model.modification.TicketReservationModification in project alf.io by alfio-event.
the class WaitingQueueManager method distributeAvailableSeats.
private Stream<Triple<WaitingQueueSubscription, TicketReservationWithOptionalCodeModification, ZonedDateTime>> distributeAvailableSeats(Event event, Ticket.TicketStatus status, Supplier<Integer> availableSeatSupplier) {
int availableSeats = availableSeatSupplier.get();
int eventId = event.getId();
log.debug("processing {} subscribers from waiting queue", availableSeats);
List<TicketCategory> unboundedCategories = ticketCategoryRepository.findUnboundedOrderByExpirationDesc(eventId);
Iterator<Ticket> tickets = ticketRepository.selectWaitingTicketsForUpdate(eventId, status.name(), availableSeats).stream().filter(t -> t.getCategoryId() != null || unboundedCategories.size() > 0).iterator();
int expirationTimeout = configurationManager.getIntConfigValue(Configuration.from(event.getOrganizationId(), event.getId(), WAITING_QUEUE_RESERVATION_TIMEOUT), 4);
ZonedDateTime expiration = ZonedDateTime.now(event.getZoneId()).plusHours(expirationTimeout).with(WorkingDaysAdjusters.defaultWorkingDays());
if (!tickets.hasNext()) {
log.warn("Unable to assign tickets, returning an empty stream");
return Stream.empty();
}
return waitingQueueRepository.loadWaiting(eventId, availableSeats).stream().map(wq -> Pair.of(wq, tickets.next())).map(pair -> {
TicketReservationModification ticketReservation = new TicketReservationModification();
ticketReservation.setAmount(1);
Integer categoryId = Optional.ofNullable(pair.getValue().getCategoryId()).orElseGet(() -> findBestCategory(unboundedCategories, pair.getKey()).orElseThrow(RuntimeException::new).getId());
ticketReservation.setTicketCategoryId(categoryId);
return Pair.of(pair.getLeft(), new TicketReservationWithOptionalCodeModification(ticketReservation, Optional.<SpecialPrice>empty()));
}).map(pair -> Triple.of(pair.getKey(), pair.getValue(), expiration));
}
Aggregations