use of alfio.model.decorator.TicketPriceContainer in project alf.io by alfio-event.
the class TicketReservationManager method totalReservationCostWithVAT.
private static TotalPrice totalReservationCostWithVAT(PromoCodeDiscount promoCodeDiscount, Event event, PriceContainer.VatStatus reservationVatStatus, List<Ticket> tickets, Stream<Pair<AdditionalService, List<AdditionalServiceItem>>> additionalServiceItems) {
List<TicketPriceContainer> ticketPrices = tickets.stream().map(t -> TicketPriceContainer.from(t, reservationVatStatus, event, promoCodeDiscount)).collect(toList());
BigDecimal totalVAT = ticketPrices.stream().map(TicketPriceContainer::getVAT).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalDiscount = ticketPrices.stream().map(TicketPriceContainer::getAppliedDiscount).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal totalNET = ticketPrices.stream().map(TicketPriceContainer::getFinalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
int discountedTickets = (int) ticketPrices.stream().filter(t -> t.getAppliedDiscount().compareTo(BigDecimal.ZERO) > 0).count();
int discountAppliedCount = discountedTickets <= 1 || promoCodeDiscount.getDiscountType() == DiscountType.FIXED_AMOUNT ? discountedTickets : 1;
List<AdditionalServiceItemPriceContainer> asPrices = additionalServiceItems.flatMap(generateASIPriceContainers(event, null)).collect(toList());
BigDecimal asTotalVAT = asPrices.stream().map(AdditionalServiceItemPriceContainer::getVAT).reduce(BigDecimal.ZERO, BigDecimal::add);
// FIXME discount is not applied to donations, as it wouldn't make sense. Must be implemented for #111
BigDecimal asTotalNET = asPrices.stream().map(AdditionalServiceItemPriceContainer::getFinalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
return new TotalPrice(unitToCents(totalNET.add(asTotalNET)), unitToCents(totalVAT.add(asTotalVAT)), -(MonetaryUtil.unitToCents(totalDiscount)), discountAppliedCount);
}
use of alfio.model.decorator.TicketPriceContainer in project alf.io by alfio-event.
the class TicketReservationManager method extractSummary.
List<SummaryRow> extractSummary(String reservationId, PriceContainer.VatStatus reservationVatStatus, Event event, Locale locale, PromoCodeDiscount promoCodeDiscount, TotalPrice reservationCost) {
List<SummaryRow> summary = new ArrayList<>();
List<TicketPriceContainer> tickets = ticketRepository.findTicketsInReservation(reservationId).stream().map(t -> TicketPriceContainer.from(t, reservationVatStatus, event, promoCodeDiscount)).collect(toList());
tickets.stream().collect(Collectors.groupingBy(TicketPriceContainer::getCategoryId)).forEach((categoryId, ticketsByCategory) -> {
final int subTotal = ticketsByCategory.stream().mapToInt(TicketPriceContainer::getSummarySrcPriceCts).sum();
final int subTotalBeforeVat = ticketsByCategory.stream().mapToInt(TicketPriceContainer::getSummaryPriceBeforeVatCts).sum();
TicketPriceContainer firstTicket = ticketsByCategory.get(0);
final int ticketPriceCts = firstTicket.getSummarySrcPriceCts();
final int priceBeforeVat = firstTicket.getSummaryPriceBeforeVatCts();
String categoryName = ticketCategoryRepository.getByIdAndActive(categoryId, event.getId()).getName();
summary.add(new SummaryRow(categoryName, formatCents(ticketPriceCts), formatCents(priceBeforeVat), ticketsByCategory.size(), formatCents(subTotal), formatCents(subTotalBeforeVat), subTotal, SummaryRow.SummaryType.TICKET));
});
summary.addAll(collectAdditionalServiceItems(reservationId, event).map(entry -> {
String language = locale.getLanguage();
AdditionalServiceText title = additionalServiceTextRepository.findBestMatchByLocaleAndType(entry.getKey().getId(), language, AdditionalServiceText.TextType.TITLE);
if (!title.getLocale().equals(language) || title.getId() == -1) {
log.debug("additional service {}: title not found for locale {}", title.getAdditionalServiceId(), language);
}
List<AdditionalServiceItemPriceContainer> prices = generateASIPriceContainers(event, null).apply(entry).collect(toList());
AdditionalServiceItemPriceContainer first = prices.get(0);
final int subtotal = prices.stream().mapToInt(AdditionalServiceItemPriceContainer::getSrcPriceCts).sum();
final int subtotalBeforeVat = prices.stream().mapToInt(AdditionalServiceItemPriceContainer::getSummaryPriceBeforeVatCts).sum();
return new SummaryRow(title.getValue(), formatCents(first.getSrcPriceCts()), formatCents(first.getSummaryPriceBeforeVatCts()), prices.size(), formatCents(subtotal), formatCents(subtotalBeforeVat), subtotal, SummaryRow.SummaryType.ADDITIONAL_SERVICE);
}).collect(Collectors.toList()));
Optional.ofNullable(promoCodeDiscount).ifPresent(promo -> {
String formattedSingleAmount = "-" + (promo.getDiscountType() == DiscountType.FIXED_AMOUNT ? formatCents(promo.getDiscountAmount()) : (promo.getDiscountAmount() + "%"));
summary.add(new SummaryRow(formatPromoCode(promo, ticketRepository.findTicketsInReservation(reservationId)), formattedSingleAmount, formattedSingleAmount, reservationCost.getDiscountAppliedCount(), formatCents(reservationCost.getDiscount()), formatCents(reservationCost.getDiscount()), reservationCost.getDiscount(), SummaryRow.SummaryType.PROMOTION_CODE));
});
return summary;
}
use of alfio.model.decorator.TicketPriceContainer in project alf.io by alfio-event.
the class TicketReservationManager method reserveTicketsForCategory.
void reserveTicketsForCategory(Event event, Optional<String> specialPriceSessionId, String transactionId, TicketReservationWithOptionalCodeModification ticketReservation, Locale locale, boolean forWaitingQueue, PromoCodeDiscount discount) {
// 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(), specialPriceSessionId, ticketReservation);
List<Integer> reservedForUpdate = reserveTickets(event.getId(), ticketReservation, forWaitingQueue ? asList(TicketStatus.RELEASED, TicketStatus.PRE_RESERVED) : singletonList(TicketStatus.FREE));
int requested = ticketReservation.getAmount();
if (reservedForUpdate.size() != requested) {
throw new NotEnoughTicketsException();
}
TicketCategory category = ticketCategoryRepository.getByIdAndActive(ticketReservation.getTicketCategoryId(), event.getId());
if (specialPrice.isPresent()) {
if (reservedForUpdate.size() != 1) {
throw new NotEnoughTicketsException();
}
SpecialPrice sp = specialPrice.get();
ticketRepository.reserveTicket(transactionId, reservedForUpdate.stream().findFirst().orElseThrow(IllegalStateException::new), sp.getId(), locale.getLanguage(), category.getSrcPriceCts());
specialPriceRepository.updateStatus(sp.getId(), Status.PENDING.toString(), sp.getSessionIdentifier());
} else {
ticketRepository.reserveTickets(transactionId, reservedForUpdate, ticketReservation.getTicketCategoryId(), locale.getLanguage(), category.getSrcPriceCts());
}
Ticket ticket = ticketRepository.findById(reservedForUpdate.get(0), category.getId());
TicketPriceContainer priceContainer = TicketPriceContainer.from(ticket, null, event, discount);
ticketRepository.updateTicketPrice(reservedForUpdate, category.getId(), event.getId(), category.getSrcPriceCts(), MonetaryUtil.unitToCents(priceContainer.getFinalPrice()), MonetaryUtil.unitToCents(priceContainer.getVAT()), MonetaryUtil.unitToCents(priceContainer.getAppliedDiscount()));
}
use of alfio.model.decorator.TicketPriceContainer in project alf.io by alfio-event.
the class AdminReservationManager method reserveForTicketsInfo.
private Result<List<Ticket>> reserveForTicketsInfo(Event event, AdminReservationModification arm, String reservationId, String specialPriceSessionId, Pair<TicketCategory, TicketsInfo> pair) {
TicketCategory category = pair.getLeft();
TicketsInfo ticketsInfo = pair.getRight();
int categoryId = category.getId();
List<Attendee> attendees = ticketsInfo.getAttendees();
List<Integer> reservedForUpdate = ticketReservationManager.reserveTickets(event.getId(), categoryId, attendees.size(), singletonList(Ticket.TicketStatus.FREE));
if (reservedForUpdate.size() != attendees.size()) {
return Result.error(ErrorCode.CategoryError.NOT_ENOUGH_SEATS);
}
ticketRepository.reserveTickets(reservationId, reservedForUpdate, categoryId, arm.getLanguage(), category.getSrcPriceCts());
Ticket ticket = ticketRepository.findById(reservedForUpdate.get(0), categoryId);
TicketPriceContainer priceContainer = TicketPriceContainer.from(ticket, null, event, null);
ticketRepository.updateTicketPrice(reservedForUpdate, categoryId, event.getId(), category.getSrcPriceCts(), MonetaryUtil.unitToCents(priceContainer.getFinalPrice()), MonetaryUtil.unitToCents(priceContainer.getVAT()), MonetaryUtil.unitToCents(priceContainer.getAppliedDiscount()));
List<SpecialPrice> codes = category.isAccessRestricted() ? bindSpecialPriceTokens(specialPriceSessionId, categoryId, attendees) : Collections.emptyList();
assignTickets(event, attendees, categoryId, reservedForUpdate, codes, reservationId, arm.getLanguage(), category.getSrcPriceCts());
List<Ticket> tickets = reservedForUpdate.stream().map(id -> ticketRepository.findById(id, categoryId)).collect(toList());
return Result.success(tickets);
}
Aggregations