Search in sources :

Example 1 with ValidatedResponse

use of alfio.manager.support.response.ValidatedResponse in project alf.io by alfio-event.

the class EventApiV2Controller method getTicketCategories.

@GetMapping("event/{eventName}/ticket-categories")
public ResponseEntity<ItemsByCategory> getTicketCategories(@PathVariable("eventName") String eventName, @RequestParam(value = "code", required = false) String code) {
    // 
    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, DISPLAY_EXPIRED_CATEGORIES), event.getConfigurationLevel());
        var ticketCategoryLevelConfiguration = configurationManager.getAllCategoriesAndValueWith(event, MAX_AMOUNT_OF_TICKETS_BY_RESERVATION);
        var messageSource = messageSourceManager.getMessageSourceFor(event);
        var appliedPromoCode = promoCodeRequestManager.checkCode(event, code);
        Optional<SpecialPrice> specialCode = appliedPromoCode.getValue().getLeft();
        Optional<PromoCodeDiscount> promoCodeDiscount = appliedPromoCode.getValue().getRight();
        final ZonedDateTime now = event.now(clockProvider);
        // hide access restricted ticket categories
        var ticketCategories = ticketCategoryRepository.findAllTicketCategories(event.getId());
        List<SaleableTicketCategory> saleableTicketCategories = ticketCategories.stream().filter((c) -> !c.isAccessRestricted() || shouldDisplayRestrictedCategory(specialCode, c, promoCodeDiscount)).map((category) -> {
            int maxTickets = getMaxAmountOfTicketsPerReservation(configurations, ticketCategoryLevelConfiguration, category.getId());
            PromoCodeDiscount filteredPromoCode = promoCodeDiscount.filter(promoCode -> shouldApplyDiscount(promoCode, category)).orElse(null);
            if (specialCode.isPresent()) {
                maxTickets = Math.min(1, maxTickets);
            } else if (filteredPromoCode != null && filteredPromoCode.getMaxUsage() != null) {
                maxTickets = filteredPromoCode.getMaxUsage() - promoCodeRepository.countConfirmedPromoCode(filteredPromoCode.getId(), categoriesOrNull(filteredPromoCode), null, categoriesOrNull(filteredPromoCode) != null ? "X" : null);
            }
            return new SaleableTicketCategory(category, now, event, ticketReservationManager.countAvailableTickets(event, category), maxTickets, filteredPromoCode);
        }).collect(Collectors.toList());
        var valid = saleableTicketCategories.stream().filter(tc -> !tc.getExpired()).collect(Collectors.toList());
        // 
        var ticketCategoryIds = valid.stream().map(SaleableTicketCategory::getId).collect(Collectors.toList());
        var ticketCategoryDescriptions = ticketCategoryDescriptionRepository.descriptionsByTicketCategory(ticketCategoryIds);
        boolean displayTicketsLeft = configurations.get(DISPLAY_TICKETS_LEFT_INDICATOR).getValueAsBooleanOrDefault();
        var categoriesByExpiredFlag = saleableTicketCategories.stream().map(stc -> {
            var description = Formatters.applyCommonMark(ticketCategoryDescriptions.getOrDefault(stc.getId(), Collections.emptyMap()));
            var expiration = Formatters.getFormattedDate(event, stc.getZonedExpiration(), "common.ticket-category.date-format", messageSource);
            var inception = Formatters.getFormattedDate(event, stc.getZonedInception(), "common.ticket-category.date-format", messageSource);
            return new TicketCategory(stc, description, inception, expiration, displayTicketsLeft && !stc.isAccessRestricted());
        }).sorted(Comparator.comparingInt(TicketCategory::getOrdinal)).collect(partitioningBy(TicketCategory::isExpired));
        var promoCode = Optional.of(appliedPromoCode).filter(ValidatedResponse::isSuccess).map(ValidatedResponse::getValue).flatMap(Pair::getRight);
        // 
        var saleableAdditionalServices = additionalServiceRepository.loadAllForEvent(event.getId()).stream().map(as -> new SaleableAdditionalService(event, as, promoCode.orElse(null))).filter(SaleableAdditionalService::isNotExpired).collect(Collectors.toList());
        // will be used for fetching descriptions and titles for all the languages
        var saleableAdditionalServicesIds = saleableAdditionalServices.stream().map(SaleableAdditionalService::getId).collect(Collectors.toList());
        var additionalServiceTexts = additionalServiceTextRepository.getDescriptionsByAdditionalServiceIds(saleableAdditionalServicesIds);
        var additionalServicesRes = saleableAdditionalServices.stream().map(as -> {
            var expiration = Formatters.getFormattedDate(event, as.getZonedExpiration(), "common.ticket-category.date-format", messageSource);
            var inception = Formatters.getFormattedDate(event, as.getZonedInception(), "common.ticket-category.date-format", messageSource);
            var title = additionalServiceTexts.getOrDefault(as.getId(), Collections.emptyMap()).getOrDefault(AdditionalServiceText.TextType.TITLE, Collections.emptyMap());
            var description = Formatters.applyCommonMark(additionalServiceTexts.getOrDefault(as.getId(), Collections.emptyMap()).getOrDefault(AdditionalServiceText.TextType.DESCRIPTION, Collections.emptyMap()));
            return new AdditionalService(as.getId(), as.getType(), as.getSupplementPolicy(), as.isFixPrice(), as.getAvailableQuantity(), as.getMaxQtyPerOrder(), as.getFree(), as.getFormattedFinalPrice(), as.getSupportsDiscount(), as.getDiscountedPrice(), as.getVatApplies(), as.getVatIncluded(), as.getVatPercentage().toString(), as.isExpired(), as.getSaleInFuture(), inception, expiration, title, description);
        }).collect(Collectors.toList());
        // 
        // waiting queue parameters
        boolean displayWaitingQueueForm = EventUtil.displayWaitingQueueForm(event, saleableTicketCategories, configurationManager, eventStatisticsManager.noSeatsAvailable());
        boolean preSales = EventUtil.isPreSales(event, saleableTicketCategories);
        Predicate<SaleableTicketCategory> waitingQueueTargetCategory = tc -> !tc.getExpired() && !tc.isBounded();
        List<SaleableTicketCategory> unboundedCategories = saleableTicketCategories.stream().filter(waitingQueueTargetCategory).collect(Collectors.toList());
        var tcForWaitingList = unboundedCategories.stream().map(stc -> new ItemsByCategory.TicketCategoryForWaitingList(stc.getId(), stc.getName())).collect(toList());
        // 
        var activeCategories = categoriesByExpiredFlag.get(false);
        var expiredCategories = configurations.get(DISPLAY_EXPIRED_CATEGORIES).getValueAsBooleanOrDefault() ? categoriesByExpiredFlag.get(true) : List.<TicketCategory>of();
        return new ResponseEntity<>(new ItemsByCategory(activeCategories, expiredCategories, additionalServicesRes, displayWaitingQueueForm, preSales, tcForWaitingList), getCorsHeaders(), HttpStatus.OK);
    }).orElseGet(() -> ResponseEntity.notFound().headers(getCorsHeaders()).build());
}
Also used : ValidationResult(alfio.model.result.ValidationResult) alfio.repository(alfio.repository) PromoCodeDiscount.categoriesOrNull(alfio.model.PromoCodeDiscount.categoriesOrNull) ReservationForm(alfio.controller.form.ReservationForm) alfio.manager(alfio.manager) UriComponentsBuilder(org.springframework.web.util.UriComponentsBuilder) java.util(java.util) TicketReservationModification(alfio.model.modification.TicketReservationModification) SaleableAdditionalService(alfio.controller.decorator.SaleableAdditionalService) MessageSourceManager(alfio.manager.i18n.MessageSourceManager) ZonedDateTime(java.time.ZonedDateTime) BindingResult(org.springframework.validation.BindingResult) SaleableTicketCategory(alfio.controller.decorator.SaleableTicketCategory) ConfigurationManager(alfio.manager.system.ConfigurationManager) StringUtils(org.apache.commons.lang3.StringUtils) Function(java.util.function.Function) AdditionalService(alfio.controller.api.v2.model.AdditionalService) Formatters(alfio.controller.support.Formatters) alfio.util(alfio.util) ServletWebRequest(org.springframework.web.context.request.ServletWebRequest) HttpServletRequest(javax.servlet.http.HttpServletRequest) Pair(org.apache.commons.lang3.tuple.Pair) DefaultMessageSourceResolvable(org.springframework.context.support.DefaultMessageSourceResolvable) EventLoader(alfio.controller.api.v2.user.support.EventLoader) ValidatedResponse(alfio.manager.support.response.ValidatedResponse) HttpSession(javax.servlet.http.HttpSession) EventWithAdditionalInfo(alfio.controller.api.v2.model.EventWithAdditionalInfo) WaitingQueueSubscriptionForm(alfio.controller.form.WaitingQueueSubscriptionForm) HttpHeaders(org.springframework.http.HttpHeaders) Predicate(java.util.function.Predicate) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) SearchOptions(alfio.controller.form.SearchOptions) HttpStatus(org.springframework.http.HttpStatus) Validate(org.apache.commons.lang3.Validate) Principal(java.security.Principal) alfio.model(alfio.model) alfio.controller.api.v2.model(alfio.controller.api.v2.model) org.springframework.web.bind.annotation(org.springframework.web.bind.annotation) ResponseEntity(org.springframework.http.ResponseEntity) I18nManager(alfio.manager.i18n.I18nManager) AllArgsConstructor(lombok.AllArgsConstructor) ConfigurationKeys(alfio.model.system.ConfigurationKeys) TicketCategory(alfio.controller.api.v2.model.TicketCategory) SaleableAdditionalService(alfio.controller.decorator.SaleableAdditionalService) SaleableAdditionalService(alfio.controller.decorator.SaleableAdditionalService) AdditionalService(alfio.controller.api.v2.model.AdditionalService) SaleableTicketCategory(alfio.controller.decorator.SaleableTicketCategory) TicketCategory(alfio.controller.api.v2.model.TicketCategory) ValidatedResponse(alfio.manager.support.response.ValidatedResponse) Predicate(java.util.function.Predicate) ZonedDateTime(java.time.ZonedDateTime) SaleableTicketCategory(alfio.controller.decorator.SaleableTicketCategory)

Example 2 with ValidatedResponse

use of alfio.manager.support.response.ValidatedResponse in project alf.io by alfio-event.

the class TicketApiV2Controller method updateTicketInfo.

@PutMapping("/api/v2/public/event/{eventName}/ticket/{ticketIdentifier}")
public ResponseEntity<ValidatedResponse<Boolean>> updateTicketInfo(@PathVariable("eventName") String eventName, @PathVariable("ticketIdentifier") String ticketIdentifier, @RequestBody UpdateTicketOwnerForm updateTicketOwner, BindingResult bindingResult, Authentication authentication) {
    var a = ticketReservationManager.fetchComplete(eventName, ticketIdentifier);
    if (a.isEmpty()) {
        return ResponseEntity.notFound().build();
    }
    Optional<UserDetails> userDetails = Optional.ofNullable(authentication).map(Authentication::getPrincipal).filter(UserDetails.class::isInstance).map(UserDetails.class::cast);
    Locale locale = LocaleUtil.forLanguageTag(a.get().getMiddle().getUserLanguage(), a.get().getLeft());
    var assignmentResult = ticketHelper.assignTicket(eventName, ticketIdentifier, updateTicketOwner, Optional.of(bindingResult), locale, userDetails, false);
    return assignmentResult.map(r -> ResponseEntity.status(r.getLeft().isSuccess() ? HttpStatus.OK : HttpStatus.UNPROCESSABLE_ENTITY).body(new ValidatedResponse<>(r.getLeft(), r.getLeft().isSuccess()))).orElseThrow(IllegalStateException::new);
}
Also used : Locale(java.util.Locale) TicketInfo(alfio.controller.api.v2.model.TicketInfo) TicketHelper(alfio.controller.api.support.TicketHelper) TicketCategoryRepository(alfio.repository.TicketCategoryRepository) PaymentProxy(alfio.model.transaction.PaymentProxy) TemplateProcessor(alfio.controller.support.TemplateProcessor) MessageSourceManager(alfio.manager.i18n.MessageSourceManager) MessageDigest(java.security.MessageDigest) BindingResult(org.springframework.validation.BindingResult) StringUtils(org.apache.commons.lang3.StringUtils) Formatters(alfio.controller.support.Formatters) Locale(java.util.Locale) ValidatedResponse(alfio.manager.support.response.ValidatedResponse) UserDetails(org.springframework.security.core.userdetails.UserDetails) ReservationInfo(alfio.controller.api.v2.model.ReservationInfo) DatesWithTimeZoneOffset(alfio.controller.api.v2.model.DatesWithTimeZoneOffset) OutputStream(java.io.OutputStream) OrganizationRepository(alfio.repository.user.OrganizationRepository) TicketRepository(alfio.repository.TicketRepository) Organization(alfio.model.user.Organization) EventUtil.firstMatchingCallLink(alfio.util.EventUtil.firstMatchingCallLink) TemplateManager(alfio.util.TemplateManager) MediaType(org.springframework.http.MediaType) UpdateTicketOwnerForm(alfio.controller.form.UpdateTicketOwnerForm) HttpServletResponse(javax.servlet.http.HttpServletResponse) IOException(java.io.IOException) StandardCharsets(java.nio.charset.StandardCharsets) ZoneId(java.time.ZoneId) HttpStatus(org.springframework.http.HttpStatus) TicketReservationManager(alfio.manager.TicketReservationManager) List(java.util.List) ImageUtil(alfio.util.ImageUtil) ChronoUnit(java.time.temporal.ChronoUnit) OnlineCheckInInfo(alfio.controller.api.v2.model.OnlineCheckInInfo) alfio.model(alfio.model) NotificationManager(alfio.manager.NotificationManager) LocaleUtil(alfio.util.LocaleUtil) org.springframework.web.bind.annotation(org.springframework.web.bind.annotation) BookingInfoTicketLoader(alfio.controller.api.v2.user.support.BookingInfoTicketLoader) Optional(java.util.Optional) FileUploadManager(alfio.manager.FileUploadManager) ResponseEntity(org.springframework.http.ResponseEntity) ExtensionManager(alfio.manager.ExtensionManager) AllArgsConstructor(lombok.AllArgsConstructor) DigestUtils(org.apache.commons.codec.digest.DigestUtils) Authentication(org.springframework.security.core.Authentication) UserDetails(org.springframework.security.core.userdetails.UserDetails) Authentication(org.springframework.security.core.Authentication)

Example 3 with ValidatedResponse

use of alfio.manager.support.response.ValidatedResponse in project alf.io by alfio-event.

the class PromoCodeRequestManager method checkCode.

public ValidatedResponse<Pair<Optional<SpecialPrice>, Optional<PromoCodeDiscount>>> checkCode(Event event, String promoCode) {
    ZoneId eventZoneId = event.getZoneId();
    ZonedDateTime now = ZonedDateTime.now(clockProvider.withZone(eventZoneId));
    Optional<String> maybeSpecialCode = Optional.ofNullable(StringUtils.trimToNull(promoCode));
    Optional<SpecialPrice> specialCode = maybeSpecialCode.flatMap(specialPriceRepository::getByCode);
    Optional<PromoCodeDiscount> promotionCodeDiscount = maybeSpecialCode.flatMap((trimmedCode) -> promoCodeRepository.findPublicPromoCodeInEventOrOrganization(event.getId(), trimmedCode));
    var result = Pair.of(specialCode, promotionCodeDiscount);
    var errorResponse = new ValidatedResponse<>(ValidationResult.failed(new ValidationResult.ErrorDescriptor("promoCode", ErrorsCode.STEP_1_CODE_NOT_FOUND, ErrorsCode.STEP_1_CODE_NOT_FOUND)), result);
    // 
    if (specialCode.isPresent()) {
        if (eventManager.getOptionalByIdAndActive(specialCode.get().getTicketCategoryId(), event.getId()).isEmpty()) {
            return errorResponse;
        }
        if (specialCode.get().getStatus() != SpecialPrice.Status.FREE) {
            return errorResponse;
        }
    } else if (promotionCodeDiscount.isPresent() && !promotionCodeDiscount.get().isCurrentlyValid(eventZoneId, now)) {
        return errorResponse;
    } else if (promotionCodeDiscount.isPresent() && isDiscountCodeUsageExceeded(promotionCodeDiscount.get())) {
        return errorResponse;
    } else if (promotionCodeDiscount.isEmpty()) {
        return errorResponse;
    }
    return new ValidatedResponse<>(ValidationResult.success(), result);
}
Also used : ZoneId(java.time.ZoneId) ZonedDateTime(java.time.ZonedDateTime) SpecialPrice(alfio.model.SpecialPrice) PromoCodeDiscount(alfio.model.PromoCodeDiscount) ValidatedResponse(alfio.manager.support.response.ValidatedResponse)

Aggregations

ValidatedResponse (alfio.manager.support.response.ValidatedResponse)3 Formatters (alfio.controller.support.Formatters)2 MessageSourceManager (alfio.manager.i18n.MessageSourceManager)2 alfio.model (alfio.model)2 IOException (java.io.IOException)2 HttpServletResponse (javax.servlet.http.HttpServletResponse)2 AllArgsConstructor (lombok.AllArgsConstructor)2 StringUtils (org.apache.commons.lang3.StringUtils)2 HttpStatus (org.springframework.http.HttpStatus)2 ResponseEntity (org.springframework.http.ResponseEntity)2 BindingResult (org.springframework.validation.BindingResult)2 org.springframework.web.bind.annotation (org.springframework.web.bind.annotation)2 TicketHelper (alfio.controller.api.support.TicketHelper)1 alfio.controller.api.v2.model (alfio.controller.api.v2.model)1 AdditionalService (alfio.controller.api.v2.model.AdditionalService)1 DatesWithTimeZoneOffset (alfio.controller.api.v2.model.DatesWithTimeZoneOffset)1 EventWithAdditionalInfo (alfio.controller.api.v2.model.EventWithAdditionalInfo)1 OnlineCheckInInfo (alfio.controller.api.v2.model.OnlineCheckInInfo)1 ReservationInfo (alfio.controller.api.v2.model.ReservationInfo)1 TicketCategory (alfio.controller.api.v2.model.TicketCategory)1