Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rest api, get ticket categories: remove n+1 query when fetching ticket category configuration #726

Merged
merged 1 commit into from
Aug 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ public ResponseEntity<ItemsByCategory> getTicketCategories(@PathVariable("eventN
//
return eventRepository.findOptionalByShortName(eventName).filter(e -> e.getStatus() != Event.Status.DISABLED).map(event -> {

var configurations = configurationManager.getFor(List.of(DISPLAY_TICKETS_LEFT_INDICATOR, MAX_AMOUNT_OF_TICKETS_BY_RESERVATION), ConfigurationLevel.event(event));
var ticketCategoryLevelConfiguration = configurationManager.getAllCategoriesAndValueWith(event, MAX_AMOUNT_OF_TICKETS_BY_RESERVATION);
var messageSource = messageSourceManager.getMessageSourceForEvent(event);
var appliedPromoCode = checkCode(event, code);

Expand All @@ -309,7 +311,7 @@ public ResponseEntity<ItemsByCategory> getTicketCategories(@PathVariable("eventN
List<SaleableTicketCategory> saleableTicketCategories = ticketCategories.stream()
.filter((c) -> !c.isAccessRestricted() || shouldDisplayRestrictedCategory(specialCode, c, promoCodeDiscount))
.map((m) -> {
int maxTickets = configurationManager.getFor(ConfigurationKeys.MAX_AMOUNT_OF_TICKETS_BY_RESERVATION, ConfigurationLevel.ticketCategory(event, m.getId())).getValueAsIntOrDefault(5); //<- TODO: N+1, find a better way
int maxTickets = getMaxAmountOfTicketsPerReservation(configurations, ticketCategoryLevelConfiguration, m.getId());
PromoCodeDiscount filteredPromoCode = promoCodeDiscount.filter(promoCode -> shouldApplyDiscount(promoCode, m)).orElse(null);
if (specialCode.isPresent()) {
maxTickets = Math.min(1, maxTickets);
Expand All @@ -330,7 +332,7 @@ public ResponseEntity<ItemsByCategory> getTicketCategories(@PathVariable("eventN
var ticketCategoryIds = valid.stream().map(SaleableTicketCategory::getId).collect(Collectors.toList());
var ticketCategoryDescriptions = ticketCategoryDescriptionRepository.descriptionsByTicketCategory(ticketCategoryIds);

boolean displayTicketsLeft = configurationManager.getFor(DISPLAY_TICKETS_LEFT_INDICATOR, ConfigurationLevel.event(event)).getValueAsBooleanOrDefault(false);
boolean displayTicketsLeft = configurations.get(DISPLAY_TICKETS_LEFT_INDICATOR).getValueAsBooleanOrDefault(false);
var converted = valid.stream()
.map(stc -> {
var description = applyCommonMark(ticketCategoryDescriptions.getOrDefault(stc.getId(), Collections.emptyMap()));
Expand Down Expand Up @@ -385,6 +387,16 @@ public ResponseEntity<ItemsByCategory> getTicketCategories(@PathVariable("eventN
});
}

private static int getMaxAmountOfTicketsPerReservation(Map<ConfigurationKeys, ConfigurationManager.MaybeConfiguration> eventLevelConf,
Map<Integer, String> ticketCategoryLevelConf,
int ticketCategory) {

if (ticketCategoryLevelConf.containsKey(ticketCategory)) {
return Integer.parseInt(ticketCategoryLevelConf.get(ticketCategory));
}
return eventLevelConf.get(MAX_AMOUNT_OF_TICKETS_BY_RESERVATION).getValueAsIntOrDefault(5);
}

@GetMapping("event/{eventName}/calendar/{locale}")
public void getCalendar(@PathVariable("eventName") String eventName,
@PathVariable("locale") String locale,
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/alfio/manager/system/ConfigurationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -597,4 +597,15 @@ public String getRequiredValue() {
}
}

/**
* Fetch all ticket_category_id, value that are present at the ticket category level with a given configuration key
*
* @param event
* @param key
* @return
*/
public Map<Integer, String> getAllCategoriesAndValueWith(EventAndOrganizationId event, ConfigurationKeys key) {
return configurationRepository.getAllCategoriesAndValueWith(event.getOrganizationId(), event.getId(), key);
}

}
4 changes: 0 additions & 4 deletions src/main/java/alfio/model/system/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,6 @@ private ConfigurationPathKey(ConfigurationPath path, ConfigurationKeys key) {
}
//

public static ConfigurationPathKey getSystemConfiguration(ConfigurationKeys configurationKey) {
return new ConfigurationPathKey(system(), configurationKey);
}

private static ConfigurationPathKey getOrganizationConfiguration(int organizationId, ConfigurationKeys configurationKey) {
return new ConfigurationPathKey(organization(organizationId), configurationKey);
}
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/alfio/repository/system/ConfigurationRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@
import alfio.model.support.JSONData;
import alfio.model.system.Configuration;
import alfio.model.system.ConfigurationKeyValuePathLevel;
import alfio.model.system.ConfigurationKeys;
import ch.digitalfondue.npjt.Bind;
import ch.digitalfondue.npjt.Query;
import ch.digitalfondue.npjt.QueryRepository;
import ch.digitalfondue.npjt.ConstructorAnnotationRowMapper.Column;
import lombok.Getter;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@QueryRepository
public interface ConfigurationRepository {
Expand All @@ -50,6 +54,24 @@ public interface ConfigurationRepository {
@Query(SELECT_FROM_TICKET_CATEGORY)
List<Configuration> findCategoryConfiguration(@Bind("organizationId") int organizationId, @Bind("eventId") int eventId, @Bind("ticketCategoryId") int categoryId);

@Query("SELECT ticket_category_id_fk, c_value FROM configuration_ticket_category where organization_id_fk = :organizationId and event_id_fk = :eventId and c_key = :key")
List<CategoryAndValue> findAllCategoriesAndValueWith(@Bind("organizationId") int organizationId, @Bind("eventId") int eventId, @Bind("key") String key);

@Getter
class CategoryAndValue {
final int ticketCategoryId;
final String value;

public CategoryAndValue(@Column("ticket_category_id_fk") int ticketCategoryId, @Column("c_value") String value) {
this.ticketCategoryId = ticketCategoryId;
this.value = value;
}
}

default Map<Integer, String> getAllCategoriesAndValueWith(int organizationId, int eventId, ConfigurationKeys key) {
return findAllCategoriesAndValueWith(organizationId, eventId, key.name()).stream().collect(Collectors.toMap(CategoryAndValue::getTicketCategoryId, CategoryAndValue::getValue));
}

String SYSTEM_FIND_BY_KEY = SELECT_FROM_SYSTEM + " where c_key = :key";
String ORGANIZATION_FIND_BY_KEY = SELECT_FROM_ORGANIZATION + " and c_key = :key ";
String EVENT_FIND_BY_KEY = SELECT_FROM_EVENT + " and c_key = :key ";
Expand Down