use of alfio.model.metadata.TicketMetadata in project alf.io by alfio-event.
the class TicketReservationManager method acquireEventTickets.
private void acquireEventTickets(PaymentProxy paymentProxy, String reservationId, PurchaseContext purchaseContext, Event event) {
TicketStatus ticketStatus = paymentProxy.isDeskPaymentRequired() ? TicketStatus.TO_BE_PAID : TicketStatus.ACQUIRED;
AdditionalServiceItemStatus asStatus = paymentProxy.isDeskPaymentRequired() ? AdditionalServiceItemStatus.TO_BE_PAID : AdditionalServiceItemStatus.ACQUIRED;
Map<Integer, Ticket> preUpdateTicket = ticketRepository.findTicketsInReservation(reservationId).stream().collect(toMap(Ticket::getId, Function.identity()));
int updatedTickets = ticketRepository.updateTicketsStatusWithReservationId(reservationId, ticketStatus.toString());
if (!configurationManager.getFor(ENABLE_TICKET_TRANSFER, purchaseContext.getConfigurationLevel()).getValueAsBooleanOrDefault()) {
// automatically lock assignment
int locked = ticketRepository.forbidReassignment(preUpdateTicket.keySet());
Validate.isTrue(updatedTickets == locked, "Expected to lock " + updatedTickets + " tickets, locked " + locked);
Map<Integer, Ticket> postUpdateTicket = ticketRepository.findTicketsInReservation(reservationId).stream().collect(toMap(Ticket::getId, Function.identity()));
postUpdateTicket.forEach((id, ticket) -> auditUpdateTicket(preUpdateTicket.get(id), Collections.emptyMap(), ticket, Collections.emptyMap(), event.getId()));
}
var ticketsWithMetadataById = ticketRepository.findTicketsInReservationWithMetadata(reservationId).stream().collect(toMap(twm -> twm.getTicket().getId(), Function.identity()));
ticketsWithMetadataById.forEach((id, ticketWithMetadata) -> {
var newMetadataOptional = extensionManager.handleTicketAssignmentMetadata(ticketWithMetadata, event);
newMetadataOptional.ifPresent(metadata -> {
var existingContainer = TicketMetadataContainer.copyOf(ticketWithMetadata.getMetadata());
var general = new HashMap<>(existingContainer.getMetadataForKey(TicketMetadataContainer.GENERAL).orElseGet(TicketMetadata::empty).getAttributes());
general.putAll(metadata.getAttributes());
existingContainer.putMetadata(TicketMetadataContainer.GENERAL, new TicketMetadata(null, null, general));
ticketRepository.updateTicketMetadata(id, existingContainer);
auditUpdateMetadata(reservationId, id, event.getId(), existingContainer, ticketWithMetadata.getMetadata());
});
auditUpdateTicket(preUpdateTicket.get(id), Collections.emptyMap(), ticketWithMetadata.getTicket(), Collections.emptyMap(), event.getId());
});
int updatedAS = additionalServiceItemRepository.updateItemsStatusWithReservationUUID(reservationId, asStatus);
Validate.isTrue(updatedTickets + updatedAS > 0, "no items have been updated");
}
use of alfio.model.metadata.TicketMetadata 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