void migrateEventToCurrentVersion(Event event) { Optional<EventMigration> optional = optionally(() -> eventMigrationRepository.loadEventMigration(event.getId())); boolean alreadyDefined = optional.isPresent(); if (!alreadyDefined || optional.filter(this::needsFixing).isPresent()) { transactionTemplate.execute( s -> { optional.ifPresent( eventMigration -> eventMigrationRepository.lockEventMigrationForUpdate(eventMigration.getId())); createMissingTickets(event); fillDescriptions(event); if (alreadyDefined) { EventMigration eventMigration = optional.get(); int result = eventMigrationRepository.updateMigrationData( eventMigration.getId(), currentVersionAsString, buildTimestamp, EventMigration.Status.COMPLETE.name()); Validate.isTrue(result == 1, "error during update " + result); } else { eventMigrationRepository.insertMigrationData( event.getId(), currentVersionAsString, buildTimestamp, EventMigration.Status.COMPLETE.name()); } return null; }); } }
private void createMissingTickets(Event event) { int existingTickets = ticketRepository.countExistingTicketsForEvent(event.getId()); if (existingTickets < event.getAvailableSeats()) { MapSqlParameterSource[] tickets = EventUtil.generateEmptyTickets( event, new Date(), event.getAvailableSeats() - existingTickets) .toArray(MapSqlParameterSource[]::new); jdbc.batchUpdate(ticketRepository.bulkTicketInitialization(), tickets); } }
@RequestMapping( value = "/events/{eventName}/additional-field/swap-position/{id1}/{id2}", method = POST) public void swapAdditionalFieldPosition( @PathVariable("eventName") String eventName, @PathVariable("id1") int id1, @PathVariable("id2") int id2, Principal principal) { Event event = eventManager.getSingleEvent(eventName, principal.getName()); eventManager.swapAdditionalFieldPosition(event.getId(), id1, id2); }
public PaymentResult processOfflinePayment(String reservationId, int price, Event event) { String transactionId = UUID.randomUUID().toString(); transactionRepository.insert( transactionId, reservationId, ZonedDateTime.now(event.getZoneId()), price, event.getCurrency(), "Offline payment confirmation", PaymentProxy.OFFLINE.toString()); return PaymentResult.successful(transactionId); }
@RequestMapping(value = "/events/{eventName}/categories-containing-tickets", method = GET) public List<TicketCategoryModification> getCategoriesWithTickets( @PathVariable("eventName") String eventName, Principal principal) { Event event = loadEvent(eventName, principal); return eventStatisticsManager .loadTicketCategoriesWithStats(event) .stream() .filter(tc -> !tc.getTickets().isEmpty()) .map( tc -> TicketCategoryModification.fromTicketCategory( tc.getTicketCategory(), ticketCategoryDescriptionRepository.findByTicketCategoryId(tc.getId()), event.getZoneId())) .collect(Collectors.toList()); }
/** * This method processes the pending payment using the configured payment gateway (at the time of * writing, only STRIPE) and returns a PaymentResult. In order to preserve the consistency of the * payment, when a non-gateway Exception is thrown, it rethrows an IllegalStateException * * @param reservationId * @param gatewayToken * @param price * @param event * @param email * @param customerName * @param billingAddress * @return PaymentResult * @throws java.lang.IllegalStateException if there is an error after charging the credit card */ public PaymentResult processPayment( String reservationId, String gatewayToken, int price, Event event, String email, CustomerName customerName, String billingAddress) { try { final Charge charge = stripeManager.chargeCreditCard( gatewayToken, price, event, reservationId, email, customerName.getFullName(), billingAddress); log.info("transaction {} paid: {}", reservationId, charge.getPaid()); transactionRepository.insert( charge.getId(), reservationId, ZonedDateTime.now(), price, event.getCurrency(), charge.getDescription(), PaymentProxy.STRIPE.name()); return PaymentResult.successful(charge.getId()); } catch (Exception e) { if (e instanceof StripeException) { return PaymentResult.unsuccessful(stripeManager.handleException((StripeException) e)); } throw new IllegalStateException(e); } }
public PaymentResult processPaypalPayment( String reservationId, String token, String payerId, int price, Event event) { try { String transactionId = paypalManager.commitPayment(reservationId, token, payerId, event); transactionRepository.insert( transactionId, reservationId, ZonedDateTime.now(), price, event.getCurrency(), "Paypal confirmation", PaymentProxy.PAYPAL.name()); return PaymentResult.successful(transactionId); } catch (Exception e) { log.warn("errow while processing paypal payment: " + e.getMessage(), e); if (e instanceof PayPalRESTException) { return PaymentResult.unsuccessful(ErrorsCode.STEP_2_PAYPAL_UNEXPECTED); } throw new IllegalStateException(e); } }
private void fillDescriptions(Event event) { int result = eventRepository.fillDisplayNameIfRequired(event.getId()); if (result > 0) { log.info("Event {} didn't have displayName, filled with shortName", event.getShortName()); } }
@RequestMapping("/events/{eventName}/sponsor-scan/export.csv") public void downloadSponsorScanExport( @PathVariable("eventName") String eventName, HttpServletResponse response, Principal principal) throws IOException { Event event = loadEvent(eventName, principal); List<TicketFieldConfiguration> fields = ticketFieldRepository.findAdditionalFieldsForEvent(event.getId()); response.setContentType("text/csv;charset=UTF-8"); response.setHeader( "Content-Disposition", "attachment; filename=" + eventName + "-sponsor-scan.csv"); try (ServletOutputStream out = response.getOutputStream(); CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { for (int marker : BOM_MARKERS) { out.write(marker); } List<String> header = new ArrayList<>(); header.add("Username"); header.add("Timestamp"); header.add("Full name"); header.add("Email"); header.addAll( fields.stream().map(TicketFieldConfiguration::getName).collect(Collectors.toList())); writer.writeNext(header.toArray(new String[header.size()])); userManager .findAllUsers(principal.getName()) .stream() .map(u -> Pair.of(u, userManager.getUserRole(u))) .filter(p -> p.getRight() == Role.SPONSOR) .flatMap( p -> sponsorScanRepository .loadSponsorData( event.getId(), p.getKey().getId(), SponsorScanRepository.DEFAULT_TIMESTAMP) .stream() .map( v -> Pair.of( v, ticketFieldRepository.findAllValuesForTicketId( v.getTicket().getId())))) .map( p -> { DetailedScanData data = p.getLeft(); Map<String, String> descriptions = p.getRight(); return Pair.of( data, fields .stream() .map(x -> descriptions.getOrDefault(x.getName(), "")) .collect(Collectors.toList())); }) .map( p -> { List<String> line = new ArrayList<>(); Ticket ticket = p.getLeft().getTicket(); SponsorScan sponsorScan = p.getLeft().getSponsorScan(); line.add(userManager.findUser(sponsorScan.getUserId()).getUsername()); line.add(sponsorScan.getTimestamp().toString()); line.add(ticket.getFullName()); line.add(ticket.getEmail()); line.addAll(p.getRight()); return line.toArray(new String[line.size()]); }) .forEachOrdered(writer::writeNext); writer.flush(); out.flush(); } }
@RequestMapping("/events/{eventName}/export.csv") public void downloadAllTicketsCSV( @PathVariable("eventName") String eventName, HttpServletRequest request, HttpServletResponse response, Principal principal) throws IOException { List<String> fields = Arrays.asList( Optional.ofNullable(request.getParameterValues("fields")).orElse(new String[] {})); Event event = loadEvent(eventName, principal); Map<Integer, TicketCategory> categoriesMap = eventManager .loadTicketCategories(event) .stream() .collect(Collectors.toMap(TicketCategory::getId, Function.identity())); ZoneId eventZoneId = event.getZoneId(); Predicate<String> contains = FIXED_FIELDS::contains; response.setContentType("text/csv;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + eventName + "-export.csv"); try (ServletOutputStream out = response.getOutputStream(); CSVWriter writer = new CSVWriter(new OutputStreamWriter(out))) { for (int marker : BOM_MARKERS) { // UGLY-MODE_ON: specify that the file is written in UTF-8 with BOM, thanks // to alexr http://stackoverflow.com/a/4192897 out.write(marker); } writer.writeNext(fields.toArray(new String[fields.size()])); eventManager .findAllConfirmedTickets(eventName, principal.getName()) .stream() .map( t -> { List<String> line = new ArrayList<>(); if (fields.contains("ID")) { line.add(t.getUuid()); } if (fields.contains("creation")) { line.add(t.getCreation().withZoneSameInstant(eventZoneId).toString()); } if (fields.contains("category")) { line.add(categoriesMap.get(t.getCategoryId()).getName()); } if (fields.contains("event")) { line.add(eventName); } if (fields.contains("status")) { line.add(t.getStatus().toString()); } if (fields.contains("originalPrice")) { line.add(MonetaryUtil.centsToUnit(t.getSrcPriceCts()).toString()); } if (fields.contains("paidPrice")) { line.add(MonetaryUtil.centsToUnit(t.getFinalPriceCts()).toString()); } if (fields.contains("discount")) { line.add(MonetaryUtil.centsToUnit(t.getDiscountCts()).toString()); } if (fields.contains("vat")) { line.add(MonetaryUtil.centsToUnit(t.getVatCts()).toString()); } if (fields.contains("reservationID")) { line.add(t.getTicketsReservationId()); } if (fields.contains("Full Name")) { line.add(t.getFullName()); } if (fields.contains("First Name")) { line.add(t.getFirstName()); } if (fields.contains("Last Name")) { line.add(t.getLastName()); } if (fields.contains("E-Mail")) { line.add(t.getEmail()); } if (fields.contains("locked")) { line.add(String.valueOf(t.getLockedAssignment())); } if (fields.contains("Language")) { line.add(String.valueOf(t.getUserLanguage())); } // obviously not optimized Map<String, String> additionalValues = ticketFieldRepository.findAllValuesForTicketId(t.getId()); fields .stream() .filter(contains.negate()) .forEachOrdered( field -> { line.add(additionalValues.getOrDefault(field, "").replaceAll("\"", "")); }); return line.toArray(new String[line.size()]); }) .forEachOrdered(writer::writeNext); writer.flush(); out.flush(); } }