Skip to content

Commit

Permalink
#333 check-in: add date check range from ticket category
Browse files Browse the repository at this point in the history
  • Loading branch information
syjer committed Sep 21, 2017
1 parent 42638f6 commit 882c866
Show file tree
Hide file tree
Showing 16 changed files with 60 additions and 36 deletions.
8 changes: 4 additions & 4 deletions src/main/java/alfio/controller/TicketController.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public String showTicketForUpdate(@PathVariable("eventName") String eventName,
}
Triple<Event, TicketReservation, Ticket> data = oData.get();
Event event = data.getLeft();
TicketCategory ticketCategory = ticketCategoryRepository.getById(data.getRight().getCategoryId(), event.getId());
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(data.getRight().getCategoryId(), event.getId());
Organization organization = organizationRepository.getById(event.getOrganizationId());

boolean enableFreeCancellation = configurationManager.getBooleanConfigValue(Configuration.from(event.getOrganizationId(), event.getId(), ticketCategory.getId(), ALLOW_FREE_TICKETS_CANCELLATION), false);
Expand Down Expand Up @@ -176,7 +176,7 @@ private Ticket internalSendTicketByEmail(HttpServletRequest request, Triple<Even
Organization organization = organizationRepository.getById(event.getOrganizationId());
notificationManager.sendTicketByEmail(ticket,
event, locale, TemplateProcessor.buildPartialEmail(event, organization, reservation, templateManager, ticketReservationManager.ticketUpdateUrl(event, ticket.getUuid()), request),
reservation, ticketCategoryRepository.getById(ticket.getCategoryId(), event.getId()));
reservation, ticketCategoryRepository.getByIdAndActive(ticket.getCategoryId(), event.getId()));
return ticket;
}

Expand Down Expand Up @@ -234,7 +234,7 @@ public String cancelTicket(@PathVariable("eventName") String eventName,
}

private PartialTicketPDFGenerator preparePdfTicket(HttpServletRequest request, Event event, TicketReservation ticketReservation, Ticket ticket) throws WriterException, IOException {
TicketCategory ticketCategory = ticketCategoryRepository.getById(ticket.getCategoryId(), event.getId());
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(ticket.getCategoryId(), event.getId());
Organization organization = organizationRepository.getById(event.getOrganizationId());
String reservationID = ticketReservationManager.getShortReservationID(event, ticketReservation.getId());
return TemplateProcessor.buildPartialPDFTicket(LocaleUtil.getTicketLanguage(ticket, request), event, ticketReservation,
Expand All @@ -249,7 +249,7 @@ private String internalShowTicket(String eventName, String ticketIdentifier, boo
Triple<Event, TicketReservation, Ticket> data = oData.get();


TicketCategory ticketCategory = ticketCategoryRepository.getById(data.getRight().getCategoryId(), data.getLeft().getId());
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(data.getRight().getCategoryId(), data.getLeft().getId());
Organization organization = organizationRepository.getById(data.getLeft().getOrganizationId());
Event event = data.getLeft();

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/alfio/manager/AdminReservationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ private Stream<Pair<TicketCategory, TicketsInfo>> flattenTicketsInfo(Event event
attendees.addAll(ti2.getAttendees());
return new TicketsInfo(ti1.getCategory(), attendees, ti1.isAddSeatsIfNotAvailable() && ti2.isAddSeatsIfNotAvailable(), ti1.isUpdateAttendees() && ti2.isUpdateAttendees());
}).orElse(empty);
return Pair.of(ticketCategoryRepository.getById(entry.getKey(), event.getId()), ticketsInfo);
return Pair.of(ticketCategoryRepository.getByIdAndActive(entry.getKey(), event.getId()), ticketsInfo);
});
}

Expand Down Expand Up @@ -375,7 +375,7 @@ private Result<TicketCategory> createCategory(TicketsInfo ti, Event event, Admin
int notAllocated = getNotAllocatedTickets(event);
int missingTickets = Math.max(tickets - notAllocated, 0);
Event modified = increaseSeatsIfNeeded(ti, event, missingTickets, event);
return eventManager.insertCategory(modified, tcm, username).map(id -> ticketCategoryRepository.getById(id, event.getId()));
return eventManager.insertCategory(modified, tcm, username).map(id -> ticketCategoryRepository.getByIdAndActive(id, event.getId()));
}

private Event increaseSeatsIfNeeded(TicketsInfo ti, Event event, int missingTickets, Event modified) {
Expand All @@ -398,7 +398,7 @@ private Result<TicketCategory> checkExistingCategory(TicketsInfo ti, Event event
List<Attendee> attendees = ti.getAttendees();
int tickets = attendees.size();
int eventId = event.getId();
TicketCategory existing = ticketCategoryRepository.getById(category.getExistingCategoryId(), eventId);
TicketCategory existing = ticketCategoryRepository.getByIdAndActive(category.getExistingCategoryId(), eventId);
int existingCategoryId = existing.getId();
int freeTicketsInCategory = ticketRepository.countFreeTickets(eventId, existingCategoryId);
int notAllocated = getNotAllocatedTickets(event);
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/alfio/manager/CheckInManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
Expand All @@ -69,6 +70,7 @@ public class CheckInManager {
private final EventRepository eventRepository;
private final TicketReservationRepository ticketReservationRepository;
private final TicketFieldRepository ticketFieldRepository;
private final TicketCategoryRepository ticketCategoryRepository;
private final ScanAuditRepository scanAuditRepository;
private final AuditingRepository auditingRepository;
private final ConfigurationManager configurationManager;
Expand Down Expand Up @@ -185,6 +187,19 @@ private TicketAndCheckInResult extractStatus(Optional<Event> maybeEvent, Optiona
Event event = maybeEvent.get();
String code = ticketCode.get();

TicketCategory tc = ticketCategoryRepository.getById(ticket.getCategoryId());

ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
if(!tc.hasValidCheckIn(now, event.getZoneId())) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy - hh:mm");
String from = tc.getValidCheckInFrom() == null ? ".." : formatter.format(tc.getValidCheckInFrom(event.getZoneId()));
String to = tc.getValidCheckInTo() == null ? ".." : formatter.format(tc.getValidCheckInTo(event.getZoneId()));
String formattedNow = formatter.format(now);
return new TicketAndCheckInResult(ticket, new DefaultCheckInResult(INVALID_TICKET_CATEGORY_CHECK_IN_DATE,
String.format("Invalid check-in date: valid range for category %s is from %s to %s, current time is: %s",
tc.getName(), from, to, formattedNow)));
}

log.trace("scanned code is {}", code);
log.trace("true code is {}", ticket.ticketCode(event.getPrivateKey()));

Expand Down
14 changes: 7 additions & 7 deletions src/main/java/alfio/manager/EventManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ public Result<TicketCategory> updateCategory(int categoryId, Event event, Ticket
return categories.stream().filter(tc -> tc.getId() == categoryId).findFirst()
.map(existing -> new Result.Builder<>(() -> {
updateCategory(tcm, event.isFreeOfCharge(), event.getZoneId(), event);
return ticketCategoryRepository.getById(categoryId, eventId);
return ticketCategoryRepository.getByIdAndActive(categoryId, eventId);
})
.addValidation(() -> tcm.getExpiration().toZonedDateTime(event.getZoneId()).isBefore(event.getEnd()), ErrorCode.CategoryError.EXPIRATION_AFTER_EVENT_END)
.addValidation(() -> tcm.getMaxTickets() - existing.getMaxTickets() + ticketRepository.countAllocatedTicketsForEvent(eventId) <= eventRepository.countExistingTickets(eventId), ErrorCode.CategoryError.NOT_ENOUGH_SEATS)
Expand Down Expand Up @@ -402,7 +402,7 @@ private void fixTicketCategoryDates(ZonedDateTime end, TicketCategory tc, ZonedD

public void reallocateTickets(int srcCategoryId, int targetCategoryId, int eventId) {
Event event = eventRepository.findById(eventId);
reallocateTickets(ticketCategoryRepository.findStatisticWithId(srcCategoryId, eventId), Optional.of(ticketCategoryRepository.getById(targetCategoryId, event.getId())), event);
reallocateTickets(ticketCategoryRepository.findStatisticWithId(srcCategoryId, eventId), Optional.of(ticketCategoryRepository.getByIdAndActive(targetCategoryId, event.getId())), event);
}

void reallocateTickets(TicketCategoryStatisticView src, Optional<TicketCategory> target, Event event) {
Expand Down Expand Up @@ -496,7 +496,7 @@ private void createCategoriesForEvent(EventModification em, Event event) {
insertOrUpdateTicketCategoryDescription(category.getKey(), tc, event);

if (tc.isTokenGenerationRequested()) {
final TicketCategory ticketCategory = ticketCategoryRepository.getById(category.getKey(), event.getId());
final TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(category.getKey(), event.getId());
final MapSqlParameterSource[] args = prepareTokenBulkInsertParameters(ticketCategory, ticketCategory.getMaxTickets());
jdbc.batchUpdate(specialPriceRepository.bulkInsert(), args);
}
Expand All @@ -511,7 +511,7 @@ private Integer insertCategory(TicketCategoryModification tc, Event event) {
tc.getExpiration().toZonedDateTime(zoneId), tc.getName(), tc.isBounded() ? tc.getMaxTickets() : 0, tc.isTokenGenerationRequested(), eventId, tc.isBounded(), price, StringUtils.trimToNull(tc.getCode()),
DateTimeModification.toZonedDateTime(tc.getValidCheckInFrom(), zoneId),
DateTimeModification.toZonedDateTime(tc.getValidCheckInTo(), zoneId));
TicketCategory ticketCategory = ticketCategoryRepository.getById(category.getKey(), eventId);
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(category.getKey(), eventId);
if(tc.isBounded()) {
List<Integer> lockedTickets = ticketRepository.selectNotAllocatedTicketsForUpdate(eventId, ticketCategory.getMaxTickets(), asList(TicketStatus.FREE.name(), TicketStatus.RELEASED.name()));
jdbc.batchUpdate(ticketRepository.bulkTicketUpdate(), lockedTickets.stream().map(id -> new MapSqlParameterSource("id", id).addValue("categoryId", ticketCategory.getId()).addValue("srcPriceCts", ticketCategory.getSrcPriceCts())).toArray(MapSqlParameterSource[]::new));
Expand Down Expand Up @@ -551,12 +551,12 @@ private void insertOrUpdateTicketCategoryDescription(int tcId, TicketCategoryMod
private void updateCategory(TicketCategoryModification tc, boolean freeOfCharge, ZoneId zoneId, Event event) {
int eventId = event.getId();
final int price = evaluatePrice(tc.getPriceInCents(), freeOfCharge);
TicketCategory original = ticketCategoryRepository.getById(tc.getId(), eventId);
TicketCategory original = ticketCategoryRepository.getByIdAndActive(tc.getId(), eventId);
ticketCategoryRepository.update(tc.getId(), tc.getName(), tc.getInception().toZonedDateTime(zoneId),
tc.getExpiration().toZonedDateTime(zoneId), tc.getMaxTickets(), tc.isTokenGenerationRequested(), price, StringUtils.trimToNull(tc.getCode()),
DateTimeModification.toZonedDateTime(tc.getValidCheckInFrom(), zoneId),
DateTimeModification.toZonedDateTime(tc.getValidCheckInTo(), (zoneId)));
TicketCategory updated = ticketCategoryRepository.getById(tc.getId(), eventId);
TicketCategory updated = ticketCategoryRepository.getByIdAndActive(tc.getId(), eventId);
int addedTickets = 0;
if(original.isBounded() ^ tc.isBounded()) {
handleTicketAllocationStrategyChange(event, original, tc);
Expand Down Expand Up @@ -689,7 +689,7 @@ private String collectPaymentProxies(EventModification em) {
}

public TicketCategory getTicketCategoryById(int id, int eventId) {
return ticketCategoryRepository.getById(id, eventId);
return ticketCategoryRepository.getByIdAndActive(id, eventId);
}

public AdditionalService getAdditionalServiceById(int id, int eventId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void generatePendingCodesForCategory(int categoryId) {

private void generateCode(SpecialPrice specialPrice) {

TicketCategory ticketCategory = ticketCategoryRepository.getById(specialPrice.getTicketCategoryId()).orElseThrow(IllegalStateException::new);
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(specialPrice.getTicketCategoryId()).orElseThrow(IllegalStateException::new);
Event event = eventRepository.findById(ticketCategory.getEventId());
int maxLength = configurationManager.getIntConfigValue(Configuration.from(event.getOrganizationId(), event.getId(), ticketCategory.getId(), ConfigurationKeys.SPECIAL_PRICE_CODE_LENGTH), 6);

Expand Down
14 changes: 7 additions & 7 deletions src/main/java/alfio/manager/TicketReservationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ void reserveTicketsForCategory(Event event, Optional<String> specialPriceSession
throw new NotEnoughTicketsException();
}

TicketCategory category = ticketCategoryRepository.getById(ticketReservation.getTicketCategoryId(), event.getId());
TicketCategory category = ticketCategoryRepository.getByIdAndActive(ticketReservation.getTicketCategoryId(), event.getId());
if (specialPrice.isPresent()) {
if(reservedForUpdate.size() != 1) {
throw new NotEnoughTicketsException();
Expand Down Expand Up @@ -295,7 +295,7 @@ List<Integer> reserveTickets(int eventId, TicketReservationWithOptionalCodeModif
}

List<Integer> reserveTickets(int eventId , int categoryId, int qty, List<TicketStatus> requiredStatuses) {
TicketCategory category = ticketCategoryRepository.getById(categoryId, eventId);
TicketCategory category = ticketCategoryRepository.getByIdAndActive(categoryId, eventId);
List<String> statusesAsString = requiredStatuses.stream().map(TicketStatus::name).collect(toList());
if(category.isBounded()) {
return ticketRepository.selectTicketInCategoryForUpdate(eventId, categoryId, qty, statusesAsString);
Expand All @@ -305,7 +305,7 @@ List<Integer> reserveTickets(int eventId , int categoryId, int qty, List<TicketS

Optional<SpecialPrice> fixToken(Optional<SpecialPrice> token, int ticketCategoryId, int eventId, Optional<String> specialPriceSessionId, TicketReservationWithOptionalCodeModification ticketReservation) {

TicketCategory ticketCategory = ticketCategoryRepository.getById(ticketCategoryId, eventId);
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(ticketCategoryId, eventId);
if(!ticketCategory.isAccessRestricted()) {
return Optional.empty();
}
Expand Down Expand Up @@ -752,7 +752,7 @@ private String formatPromoCode(PromoCodeDiscount promoCodeDiscount, List<Ticket>
.map(Ticket::getCategoryId)
.collect(toSet())
.stream()
.map(categoryId -> ticketCategoryRepository.getById(categoryId, promoCodeDiscount.getEventId()).getName())
.map(categoryId -> ticketCategoryRepository.getByIdAndActive(categoryId, promoCodeDiscount.getEventId()).getName())
.collect(Collectors.joining(", ", "(", ")"));


Expand Down Expand Up @@ -787,7 +787,7 @@ List<SummaryRow> extractSummary(String reservationId, PriceContainer.VatStatus r
TicketPriceContainer firstTicket = ticketsByCategory.get(0);
final int ticketPriceCts = firstTicket.getSummarySrcPriceCts();
final int priceBeforeVat = firstTicket.getSummaryPriceBeforeVatCts();
String categoryName = ticketCategoryRepository.getById(categoryId, event.getId()).getName();
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));
});

Expand Down Expand Up @@ -1044,7 +1044,7 @@ private boolean isAdmin(Optional<UserDetails> userDetails) {
void sendTicketByEmail(Ticket ticket, Locale locale, Event event, PartialTicketTextGenerator confirmationTextBuilder) {
try {
TicketReservation reservation = ticketReservationRepository.findReservationById(ticket.getTicketsReservationId());
TicketCategory ticketCategory = ticketCategoryRepository.getById(ticket.getCategoryId(), event.getId());
TicketCategory ticketCategory = ticketCategoryRepository.getByIdAndActive(ticket.getCategoryId(), event.getId());
notificationManager.sendTicketByEmail(ticket, event, locale, confirmationTextBuilder, reservation, ticketCategory);
} catch (IOException e) {
throw new IllegalStateException(e);
Expand Down Expand Up @@ -1214,7 +1214,7 @@ public int countAvailableTickets(Event event, TicketCategory category) {
}

public void releaseTicket(Event event, TicketReservation ticketReservation, Ticket ticket) {
TicketCategory category = ticketCategoryRepository.getById(ticket.getCategoryId(), event.getId());
TicketCategory category = ticketCategoryRepository.getByIdAndActive(ticket.getCategoryId(), event.getId());
if(!CategoryEvaluator.isTicketCancellationAvailable(ticketCategoryRepository, ticket)) {
throw new IllegalStateException("Cannot release reserved tickets");
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/alfio/manager/support/CategoryEvaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private CategoryEvaluator() {
}

public static Function<Ticket, Boolean> ticketCancellationAvailabilityChecker(TicketCategoryRepository ticketCategoryRepository) {
return ticket -> ticket.getStatus() == Ticket.TicketStatus.ACQUIRED && (!ticketCategoryRepository.getById(ticket.getCategoryId(), ticket.getEventId()).isAccessRestricted()
return ticket -> ticket.getStatus() == Ticket.TicketStatus.ACQUIRED && (!ticketCategoryRepository.getByIdAndActive(ticket.getCategoryId(), ticket.getEventId()).isAccessRestricted()
|| ticketCategoryRepository.countUnboundedCategoriesByEventId(ticket.getEventId()) > 0);
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/alfio/manager/support/CheckInStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
package alfio.manager.support;

public enum CheckInStatus {
EVENT_NOT_FOUND, TICKET_NOT_FOUND, EMPTY_TICKET_CODE, INVALID_TICKET_CODE, INVALID_TICKET_STATE, ALREADY_CHECK_IN, MUST_PAY, OK_READY_TO_BE_CHECKED_IN, SUCCESS
EVENT_NOT_FOUND, TICKET_NOT_FOUND, EMPTY_TICKET_CODE, INVALID_TICKET_CODE, INVALID_TICKET_STATE, ALREADY_CHECK_IN, MUST_PAY, OK_READY_TO_BE_CHECKED_IN, SUCCESS, INVALID_TICKET_CATEGORY_CHECK_IN_DATE
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public void sendMessages(String eventName, Optional<Integer> categoryId, List<Me
List<Mailer.Attachment> attachments = new ArrayList<>();
if(m.isAttachTicket()) {
ticketReservationManager.findById(ticket.getTicketsReservationId()).ifPresent(reservation -> {
ticketCategoryRepository.getById(ticket.getCategoryId()).ifPresent(ticketCategory -> {
ticketCategoryRepository.getByIdAndActive(ticket.getCategoryId()).ifPresent(ticketCategory -> {
attachments.add(generateTicketAttachment(ticket, reservation, ticketCategory, organization));
});
});
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/alfio/model/TicketCategory.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,10 @@ public ZonedDateTime getValidCheckInFrom(ZoneId zoneId) {
public ZonedDateTime getValidCheckInTo(ZoneId zoneId) {
return validCheckInTo == null ? null : validCheckInTo.withZoneSameInstant(zoneId);
}

public boolean hasValidCheckIn(ZonedDateTime now, ZoneId eventZoneId) {
// check from boundary -> from cannot be after now
// check to boundary -> to cannot be before now
return (validCheckInFrom == null || !getValidCheckInFrom(eventZoneId).isAfter(now)) && (validCheckInTo == null || !getValidCheckInTo(eventZoneId).isBefore(now));
}
}

0 comments on commit 882c866

Please sign in to comment.