use of alfio.manager.payment.PaymentSpecification in project alf.io by alfio-event.
the class AdminReservationManager method performConfirmation.
private Result<Triple<TicketReservation, List<Ticket>, PurchaseContext>> performConfirmation(String reservationId, PurchaseContext purchaseContext, TicketReservation original, Notification notification, String username, UUID subscriptionId) {
try {
var reservation = original;
if (subscriptionId != null && purchaseContext.ofType(PurchaseContextType.event)) {
if (reservation.getVatStatus() == null && purchaseContext.getVatStatus() != null) {
// set default vatStatus if not present
ticketReservationRepository.updateVatStatus(reservationId, purchaseContext.getVatStatus());
reservation = ticketReservationManager.findById(reservationId).orElseThrow();
}
var subscriptionDetails = subscriptionRepository.findSubscriptionById(subscriptionId);
var bindingResult = new MapBindingResult(new HashMap<>(), "");
boolean result = ticketReservationManager.validateAndApplySubscriptionCode(purchaseContext, reservation, Optional.of(subscriptionId), subscriptionId.toString(), subscriptionDetails.getEmail(), bindingResult);
if (!result) {
var message = bindingResult.getGlobalErrors().stream().findFirst().map(DefaultMessageSourceResolvable::getCode).orElse("Unknown error");
return Result.error(ErrorCode.custom(message, String.format("Cannot assign subscription %s to Reservation %s", subscriptionId, reservationId)));
}
reservation = ticketReservationManager.findById(reservationId).orElseThrow();
}
PaymentSpecification spec = new PaymentSpecification(reservationId, null, reservation.getFinalPriceCts(), purchaseContext, reservation.getEmail(), new CustomerName(reservation.getFullName(), reservation.getFirstName(), reservation.getLastName(), purchaseContext.mustUseFirstAndLastName()), reservation.getBillingAddress(), reservation.getCustomerReference(), LocaleUtil.forLanguageTag(reservation.getUserLanguage()), false, false, null, reservation.getVatCountryCode(), reservation.getVatNr(), reservation.getVatStatus(), false, false);
ticketReservationManager.completeReservation(spec, PaymentProxy.ADMIN, notification.isCustomer(), notification.isAttendees(), username);
return loadReservation(reservationId);
} catch (Exception e) {
return Result.error(ErrorCode.ReservationError.UPDATE_FAILED);
}
}
use of alfio.manager.payment.PaymentSpecification in project alf.io by alfio-event.
the class TicketReservationManagerIntegrationTest method testTicketSelection.
@Test
void testTicketSelection() {
List<TicketCategoryModification> categories = List.of(new TicketCategoryModification(null, "default", TicketCategory.TicketAccessType.INHERIT, AVAILABLE_SEATS, new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null, 0, null, null, AlfioMetadata.empty()), new TicketCategoryModification(null, "default", TicketCategory.TicketAccessType.INHERIT, 10, new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), DESCRIPTION, BigDecimal.TEN, false, "", true, null, null, null, null, null, 0, null, null, AlfioMetadata.empty()));
Pair<Event, String> eventAndUsername = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository);
Event event = eventAndUsername.getKey();
TicketCategory bounded = ticketCategoryRepository.findAllTicketCategories(event.getId()).stream().filter(TicketCategory::isBounded).findFirst().orElseThrow(IllegalStateException::new);
TicketCategory unbounded = ticketCategoryRepository.findAllTicketCategories(event.getId()).stream().filter(t -> !t.isBounded()).findFirst().orElseThrow(IllegalStateException::new);
assertEquals(0, eventStatisticsManager.loadModifiedTickets(event.getId(), bounded.getId(), 0, null).size());
assertEquals(Integer.valueOf(0), eventStatisticsManager.countModifiedTicket(event.getId(), bounded.getId(), null));
assertEquals(0, eventStatisticsManager.loadModifiedTickets(event.getId(), unbounded.getId(), 0, null).size());
TicketReservationModification tr = new TicketReservationModification();
tr.setQuantity(10);
tr.setTicketCategoryId(bounded.getId());
TicketReservationModification tr2 = new TicketReservationModification();
tr2.setQuantity(9);
tr2.setTicketCategoryId(unbounded.getId());
TicketReservationWithOptionalCodeModification mod = new TicketReservationWithOptionalCodeModification(tr, Optional.empty());
TicketReservationWithOptionalCodeModification mod2 = new TicketReservationWithOptionalCodeModification(tr2, Optional.empty());
String reservationId = ticketReservationManager.createTicketReservation(event, List.of(mod, mod2), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Locale.ENGLISH, false, null);
List<TicketReservation> reservations = purchaseContextSearchManager.findAllReservationsFor(event, 0, null, null).getKey();
assertEquals(1, reservations.size());
assertEquals(reservationId, reservations.get(0).getId());
List<Ticket> pendingTickets = ticketRepository.findPendingTicketsInCategories(List.of(bounded.getId(), unbounded.getId()));
assertEquals(19, pendingTickets.size());
pendingTickets.forEach(t -> assertEquals(1000, t.getFinalPriceCts()));
List<Ticket> tickets = ticketRepository.findFreeByEventId(event.getId());
assertEquals(1, tickets.size());
assertTrue(tickets.stream().allMatch(t -> t.getCategoryId() == null));
Pair<TotalPrice, Optional<PromoCodeDiscount>> priceAndDiscount = ticketReservationManager.totalReservationCostWithVAT(reservationId);
TotalPrice totalPrice = priceAndDiscount.getLeft();
assertTrue(priceAndDiscount.getRight().isEmpty());
assertEquals(0, ticketReservationManager.getPendingPayments(event.getShortName()).size());
PaymentSpecification specification = new PaymentSpecification(reservationId, null, totalPrice.getPriceWithVAT(), event, "email@example.com", new CustomerName("full name", "full", "name", event.mustUseFirstAndLastName()), "billing address", null, Locale.ENGLISH, true, false, null, "IT", "123456", PriceContainer.VatStatus.INCLUDED, true, false);
PaymentResult confirm = ticketReservationManager.performPayment(specification, totalPrice, PaymentProxy.OFFLINE, PaymentMethod.BANK_TRANSFER, null);
assertTrue(confirm.isSuccessful());
assertEquals(TicketReservation.TicketReservationStatus.OFFLINE_PAYMENT, ticketReservationManager.findById(reservationId).get().getStatus());
assertEquals(1, ticketReservationManager.getPendingPayments(event.getShortName()).size());
var from = ZonedDateTime.now(Clock.systemUTC()).minusDays(1).with(d -> d.with(ChronoField.HOUR_OF_DAY, 0));
var to = ZonedDateTime.now(Clock.systemUTC()).plusDays(1).with(ChronoField.HOUR_OF_DAY, 23);
// -> no reservations
assertTrue(ticketReservationRepository.getSoldStatistic(event.getId(), from, to, "day").stream().allMatch(tds -> tds.getCount() == 0L));
ticketReservationManager.validateAndConfirmOfflinePayment(reservationId, event, new BigDecimal("190.00"), eventAndUsername.getValue());
var soldStatisticsList = ticketReservationRepository.getSoldStatistic(event.getId(), from, to, "day");
assertEquals(3, soldStatisticsList.size());
assertEquals(LocalDate.now(ClockProvider.clock()).toString(), soldStatisticsList.get(1).getDate());
// -> 19 tickets reserved
assertEquals(19L, soldStatisticsList.get(1).getCount());
assertEquals(19L, soldStatisticsList.stream().mapToLong(TicketsByDateStatistic::getCount).sum());
assertEquals(10, eventStatisticsManager.loadModifiedTickets(event.getId(), bounded.getId(), 0, null).size());
assertEquals(Integer.valueOf(10), eventStatisticsManager.countModifiedTicket(event.getId(), bounded.getId(), null));
assertEquals(9, eventStatisticsManager.loadModifiedTickets(event.getId(), unbounded.getId(), 0, null).size());
assertEquals(Integer.valueOf(9), eventStatisticsManager.countModifiedTicket(event.getId(), unbounded.getId(), null));
assertEquals(TicketReservation.TicketReservationStatus.COMPLETE, ticketReservationManager.findById(reservationId).get().getStatus());
// -------------------
TicketReservationModification trForDelete = new TicketReservationModification();
trForDelete.setQuantity(1);
trForDelete.setTicketCategoryId(unbounded.getId());
TicketReservationWithOptionalCodeModification modForDelete = new TicketReservationWithOptionalCodeModification(trForDelete, Optional.empty());
String reservationId2 = ticketReservationManager.createTicketReservation(event, Collections.singletonList(modForDelete), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Locale.ENGLISH, false, null);
PaymentSpecification specification2 = new PaymentSpecification(reservationId2, null, totalPrice.getPriceWithVAT(), event, "email@example.com", new CustomerName("full name", "full", "name", event.mustUseFirstAndLastName()), "billing address", null, Locale.ENGLISH, true, false, null, "IT", "123456", PriceContainer.VatStatus.INCLUDED, true, false);
PaymentResult confirm2 = ticketReservationManager.performPayment(specification2, totalPrice, PaymentProxy.OFFLINE, PaymentMethod.BANK_TRANSFER, null);
assertTrue(confirm2.isSuccessful());
ticketReservationManager.deleteOfflinePayment(event, reservationId2, false, false, null);
assertFalse(ticketReservationManager.findById(reservationId2).isPresent());
}
use of alfio.manager.payment.PaymentSpecification in project alf.io by alfio-event.
the class TicketReservationManagerIntegrationTest method testDeletePendingPaymentUnboundedCategory.
@Test
void testDeletePendingPaymentUnboundedCategory() {
List<TicketCategoryModification> categories = Collections.singletonList(new TicketCategoryModification(null, "default", TicketCategory.TicketAccessType.INHERIT, AVAILABLE_SEATS, new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null, 0, null, null, AlfioMetadata.empty()));
Event event = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository).getKey();
TicketCategory unbounded = ticketCategoryRepository.findAllTicketCategories(event.getId()).get(0);
TicketReservationModification tr = new TicketReservationModification();
tr.setQuantity(AVAILABLE_SEATS / 2 + 1);
tr.setTicketCategoryId(unbounded.getId());
TicketReservationWithOptionalCodeModification mod = new TicketReservationWithOptionalCodeModification(tr, Optional.empty());
String reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(mod), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Locale.ENGLISH, false, null);
Pair<TotalPrice, Optional<PromoCodeDiscount>> priceAndDiscount = ticketReservationManager.totalReservationCostWithVAT(reservationId);
TotalPrice reservationCost = priceAndDiscount.getLeft();
assertTrue(priceAndDiscount.getRight().isEmpty());
PaymentSpecification specification = new PaymentSpecification(reservationId, null, reservationCost.getPriceWithVAT(), event, "email@example.com", new CustomerName("full name", "full", "name", event.mustUseFirstAndLastName()), "billing address", null, Locale.ENGLISH, true, false, null, "IT", "123456", PriceContainer.VatStatus.INCLUDED, true, false);
PaymentResult result = ticketReservationManager.performPayment(specification, reservationCost, PaymentProxy.OFFLINE, PaymentMethod.BANK_TRANSFER, null);
assertTrue(result.isSuccessful());
ticketReservationManager.deleteOfflinePayment(event, reservationId, false, false, null);
waitingQueueManager.distributeSeats(event);
mod = new TicketReservationWithOptionalCodeModification(tr, Optional.empty());
reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(mod), Collections.emptyList(), DateUtils.addDays(new Date(), 1), Optional.empty(), Locale.ENGLISH, false, null);
priceAndDiscount = ticketReservationManager.totalReservationCostWithVAT(reservationId);
reservationCost = priceAndDiscount.getLeft();
assertTrue(priceAndDiscount.getRight().isEmpty());
PaymentSpecification specification2 = new PaymentSpecification(reservationId, null, reservationCost.getPriceWithVAT(), event, "email@example.com", new CustomerName("full name", "full", "name", event.mustUseFirstAndLastName()), "billing address", null, Locale.ENGLISH, true, false, null, "IT", "123456", PriceContainer.VatStatus.INCLUDED, true, false);
result = ticketReservationManager.performPayment(specification2, reservationCost, PaymentProxy.OFFLINE, PaymentMethod.BANK_TRANSFER, null);
assertTrue(result.isSuccessful());
}
use of alfio.manager.payment.PaymentSpecification in project alf.io by alfio-event.
the class CheckInManagerIntegrationTest method testReturnOnlyOnce.
@Test
void testReturnOnlyOnce() {
IntegrationTestUtil.ensureMinimalConfiguration(configurationRepository);
List<TicketCategoryModification> categories = List.of(new TicketCategoryModification(null, "default", TicketCategory.TicketAccessType.INHERIT, AVAILABLE_SEATS, new DateTimeModification(LocalDate.now(ClockProvider.clock()).minusDays(1), LocalTime.now(ClockProvider.clock())), new DateTimeModification(LocalDate.now(ClockProvider.clock()).plusDays(1), LocalTime.now(ClockProvider.clock())), DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null, 0, null, null, AlfioMetadata.empty()));
Pair<Event, String> eventAndUser = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository);
var event = eventAndUser.getLeft();
var additionalServiceRequest = new EventModification.AdditionalService(null, BigDecimal.ONE, true, 1, 100, 2, DateTimeModification.fromZonedDateTime(ZonedDateTime.now(ClockProvider.clock()).minusDays(1)), DateTimeModification.fromZonedDateTime(ZonedDateTime.now(ClockProvider.clock()).plusDays(1)), BigDecimal.ZERO, AdditionalService.VatType.INHERITED, List.of(), List.of(new EventModification.AdditionalServiceText(null, "en", "bla", AdditionalServiceText.TextType.TITLE)), List.of(new EventModification.AdditionalServiceText(null, "en", "blabla", AdditionalServiceText.TextType.DESCRIPTION)), AdditionalService.AdditionalServiceType.SUPPLEMENT, AdditionalService.SupplementPolicy.OPTIONAL_UNLIMITED_AMOUNT);
var additionalService = eventManager.insertAdditionalService(event, additionalServiceRequest);
var category = ticketCategoryRepository.findAllTicketCategories(event.getId()).get(0);
TicketReservationModification tr = new TicketReservationModification();
tr.setQuantity(AVAILABLE_SEATS);
tr.setTicketCategoryId(category.getId());
var tickets = new TicketReservationWithOptionalCodeModification(tr, Optional.empty());
var additionalServices = new AdditionalServiceReservationModification();
additionalServices.setAdditionalServiceId(additionalService.getId());
additionalServices.setQuantity(1);
var additionalServicesModification = new ASReservationWithOptionalCodeModification(additionalServices, Optional.empty());
String reservationId = ticketReservationManager.createTicketReservation(event, List.of(tickets), List.of(additionalServicesModification), DateUtils.addDays(new Date(), 1), Optional.empty(), Locale.ENGLISH, false, null);
Pair<TotalPrice, Optional<PromoCodeDiscount>> priceAndDiscount = ticketReservationManager.totalReservationCostWithVAT(reservationId);
TotalPrice reservationCost = priceAndDiscount.getLeft();
assertTrue(priceAndDiscount.getRight().isEmpty());
PaymentSpecification specification = new PaymentSpecification(reservationId, null, reservationCost.getPriceWithVAT(), event, "email@example.com", new CustomerName("full name", "full", "name", event.mustUseFirstAndLastName()), "billing address", null, Locale.ENGLISH, true, false, null, "IT", "123456", PriceContainer.VatStatus.INCLUDED, true, false);
PaymentResult result = ticketReservationManager.performPayment(specification, reservationCost, PaymentProxy.OFFLINE, PaymentMethod.BANK_TRANSFER, null);
assertTrue(result.isSuccessful());
ticketReservationManager.confirmOfflinePayment(event, reservationId, eventAndUser.getRight());
var returnedAdditionalServices = ticketReservationManager.findTicketsInReservation(reservationId).stream().filter(ticket -> !checkInManager.getAdditionalServicesForTicket(ticket).isEmpty()).collect(Collectors.toList());
//
assertEquals(1, returnedAdditionalServices.size());
assertEquals((int) ticketRepository.findFirstTicketIdInReservation(reservationId).orElseThrow(), returnedAdditionalServices.get(0).getId());
}
use of alfio.manager.payment.PaymentSpecification in project alf.io by alfio-event.
the class TicketReservationManagerIntegrationTest method testCleanupOfflineExpiredReservations.
@Test
void testCleanupOfflineExpiredReservations() {
List<TicketCategoryModification> categories = List.of(new TicketCategoryModification(null, "default", TicketCategory.TicketAccessType.INHERIT, 10, new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), new DateTimeModification(LocalDate.now(ClockProvider.clock()), LocalTime.now(ClockProvider.clock())), DESCRIPTION, BigDecimal.TEN, false, "", true, null, null, null, null, null, 0, null, null, AlfioMetadata.empty()));
Pair<Event, String> eventAndUsername = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository);
Event event = eventAndUsername.getKey();
TicketCategory bounded = ticketCategoryRepository.findAllTicketCategories(event.getId()).stream().filter(TicketCategory::isBounded).findFirst().orElseThrow(IllegalStateException::new);
TicketReservationModification tr = new TicketReservationModification();
tr.setQuantity(10);
tr.setTicketCategoryId(bounded.getId());
TicketReservationWithOptionalCodeModification mod = new TicketReservationWithOptionalCodeModification(tr, Optional.empty());
Date past = DateUtils.addDays(new Date(), -2);
Date now = new Date();
String reservationId = ticketReservationManager.createTicketReservation(event, List.of(mod), Collections.emptyList(), past, Optional.empty(), Locale.ENGLISH, false, null);
final Supplier<List<String>> idsOfflinePayment = () -> jdbcTemplate.queryForList("select id from tickets_reservation where validity < :date and status = 'OFFLINE_PAYMENT'", Collections.singletonMap("date", now), String.class);
assertTrue(idsOfflinePayment.get().isEmpty());
Pair<TotalPrice, Optional<PromoCodeDiscount>> priceAndDiscount = ticketReservationManager.totalReservationCostWithVAT(reservationId);
TotalPrice reservationCost = priceAndDiscount.getLeft();
assertTrue(priceAndDiscount.getRight().isEmpty());
PaymentSpecification specification = new PaymentSpecification(reservationId, null, reservationCost.getPriceWithVAT(), event, "email@example.com", new CustomerName("full name", "full", "name", event.mustUseFirstAndLastName()), "billing address", null, Locale.ENGLISH, true, false, null, "IT", "123456", PriceContainer.VatStatus.INCLUDED, true, false);
PaymentResult result = ticketReservationManager.performPayment(specification, reservationCost, PaymentProxy.OFFLINE, PaymentMethod.BANK_TRANSFER, null);
assertTrue(result.isSuccessful());
//
assertEquals(1, jdbcTemplate.update("update tickets_reservation set validity = :date where id = :id", Map.of("date", past, "id", reservationId)));
//
List<String> idsOffline = idsOfflinePayment.get();
assertEquals(1, idsOffline.size());
assertEquals(reservationId, idsOffline.get(0));
ticketReservationManager.cleanupExpiredOfflineReservations(now);
assertFalse(idsOfflinePayment.get().isEmpty());
configurationRepository.insert(AUTOMATIC_REMOVAL_EXPIRED_OFFLINE_PAYMENT.name(), "true", "");
ticketReservationManager.cleanupExpiredOfflineReservations(now);
assertTrue(idsOfflinePayment.get().isEmpty());
}
Aggregations