use of alfio.model.metadata.TicketMetadataContainer in project alf.io by alfio-event.
the class TicketReservationManager method reserveTicketsForCategory.
void reserveTicketsForCategory(Event event, String reservationId, TicketReservationWithOptionalCodeModification ticketReservation, Locale locale, boolean forWaitingQueue, PromoCodeDiscount accessCodeOrDiscount, PromoCodeDiscount dynamicDiscount) {
List<SpecialPrice> specialPrices;
if (accessCodeOrDiscount != null && accessCodeOrDiscount.getCodeType() == CodeType.ACCESS && ticketReservation.getTicketCategoryId().equals(accessCodeOrDiscount.getHiddenCategoryId()) && Boolean.TRUE.equals(ticketCategoryRepository.isAccessRestricted(accessCodeOrDiscount.getHiddenCategoryId()))) {
specialPrices = reserveTokensForAccessCode(ticketReservation, accessCodeOrDiscount);
} else {
// first check if there is another pending special price token bound to the current sessionId
Optional<SpecialPrice> specialPrice = fixToken(ticketReservation.getSpecialPrice(), ticketReservation.getTicketCategoryId(), event.getId(), ticketReservation);
specialPrices = specialPrice.stream().collect(toList());
}
List<Integer> reservedForUpdate = reserveTickets(event.getId(), ticketReservation, forWaitingQueue ? asList(TicketStatus.RELEASED, TicketStatus.PRE_RESERVED) : singletonList(TicketStatus.FREE));
int requested = ticketReservation.getQuantity();
if (reservedForUpdate.size() != requested) {
throw new NotEnoughTicketsException();
}
TicketCategory category = ticketCategoryRepository.getByIdAndActive(ticketReservation.getTicketCategoryId(), event.getId());
List<Map<String, String>> ticketMetadata = requireNonNullElse(ticketReservation.getMetadata(), List.of());
if (!specialPrices.isEmpty()) {
if (specialPrices.size() != reservedForUpdate.size()) {
throw new NotEnoughTicketsException();
}
AtomicInteger counter = new AtomicInteger(0);
var ticketsAndSpecialPrices = specialPrices.stream().map(sp -> {
int index = counter.getAndIncrement();
return Triple.of(reservedForUpdate.get(index), sp, getAtIndexOrNull(ticketMetadata, index));
}).collect(Collectors.toList());
if (specialPrices.size() == 1) {
var ticketId = reservedForUpdate.get(0);
var sp = specialPrices.get(0);
var accessCodeId = accessCodeOrDiscount != null && accessCodeOrDiscount.getHiddenCategoryId() != null ? accessCodeOrDiscount.getId() : null;
TicketMetadata metadata = null;
var attributes = getAtIndexOrNull(ticketMetadata, 0);
if (attributes != null) {
metadata = new TicketMetadata(null, null, attributes);
}
ticketRepository.reserveTicket(reservationId, ticketId, sp.getId(), locale.getLanguage(), category.getSrcPriceCts(), category.getCurrencyCode(), event.getVatStatus(), TicketMetadataContainer.fromMetadata(metadata));
specialPriceRepository.updateStatus(sp.getId(), Status.PENDING.toString(), null, accessCodeId);
} else {
jdbcTemplate.batchUpdate(ticketRepository.batchReserveTicketsForSpecialPrice(), ticketsAndSpecialPrices.stream().map(triple -> {
TicketMetadataContainer metadata = null;
if (triple.getRight() != null) {
metadata = TicketMetadataContainer.fromMetadata(new TicketMetadata(null, null, triple.getRight()));
}
return new MapSqlParameterSource(RESERVATION_ID, reservationId).addValue("ticketId", triple.getLeft()).addValue("specialCodeId", triple.getMiddle().getId()).addValue("userLanguage", locale.getLanguage()).addValue("srcPriceCts", category.getSrcPriceCts()).addValue("currencyCode", category.getCurrencyCode()).addValue("ticketMetadata", json.asJsonString(metadata)).addValue("vatStatus", event.getVatStatus().toString());
}).toArray(MapSqlParameterSource[]::new));
specialPriceRepository.batchUpdateStatus(specialPrices.stream().map(SpecialPrice::getId).collect(toList()), Status.PENDING, Objects.requireNonNull(accessCodeOrDiscount).getId());
}
} else {
int reserved = ticketRepository.reserveTickets(reservationId, reservedForUpdate, category, locale.getLanguage(), event.getVatStatus(), idx -> {
var metadata = getAtIndexOrNull(ticketMetadata, idx);
if (metadata != null) {
return json.asJsonString(TicketMetadataContainer.fromMetadata(new TicketMetadata(null, null, metadata)));
}
return null;
});
Validate.isTrue(reserved == reservedForUpdate.size(), "Cannot reserve all tickets");
}
Ticket ticket = ticketRepository.findById(reservedForUpdate.get(0), category.getId());
var discountToApply = ObjectUtils.firstNonNull(dynamicDiscount, accessCodeOrDiscount);
TicketPriceContainer priceContainer = TicketPriceContainer.from(ticket, null, event.getVat(), event.getVatStatus(), discountToApply);
var currencyCode = priceContainer.getCurrencyCode();
ticketRepository.updateTicketPrice(reservedForUpdate, category.getId(), event.getId(), category.getSrcPriceCts(), MonetaryUtil.unitToCents(priceContainer.getFinalPrice(), currencyCode), MonetaryUtil.unitToCents(priceContainer.getVAT(), currencyCode), MonetaryUtil.unitToCents(priceContainer.getAppliedDiscount(), currencyCode), category.getCurrencyCode(), priceContainer.getVatStatus());
}
Aggregations