use of alfio.model.PriceContainer.VatStatus.NOT_INCLUDED_NOT_CHARGED in project alf.io by alfio-event.
the class ReverseChargeManager method checkAndApplyVATRules.
public void checkAndApplyVATRules(PurchaseContext purchaseContext, String reservationId, ContactAndTicketsForm contactAndTicketsForm, BindingResult bindingResult) {
String country = contactAndTicketsForm.getVatCountryCode();
// validate VAT presence if Reverse Charge is enabled
var reverseChargeConfiguration = EuVatChecker.loadConfigurationForReverseChargeCheck(configurationManager, purchaseContext);
if (EuVatChecker.reverseChargeEnabled(reverseChargeConfiguration) && (country == null || isEUCountry(country))) {
ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "vatNr", "error.emptyField");
}
boolean isEvent = purchaseContext.ofType(PurchaseContext.PurchaseContextType.event);
// we must take into account specific configuration only if the purchase context is an Event.
// Otherwise, specific settings do not apply
boolean reverseChargeInPerson = !isEvent || reverseChargeConfiguration.get(ENABLE_REVERSE_CHARGE_IN_PERSON).getValueAsBooleanOrDefault();
boolean reverseChargeOnline = !isEvent || reverseChargeConfiguration.get(ENABLE_REVERSE_CHARGE_ONLINE).getValueAsBooleanOrDefault();
try {
var optionalReservation = ticketReservationRepository.findOptionalReservationById(reservationId);
List<TicketCategory> categoriesList = optionalReservation.filter(// skip load if the current context is not "event"
res -> isEvent).map(res -> ticketCategoryRepository.findCategoriesInReservation(res.getId())).orElse(List.of());
Optional<VatDetail> vatDetail = optionalReservation.filter(e -> {
if (purchaseContext.ofType(PurchaseContext.PurchaseContextType.event) && (!reverseChargeInPerson || !reverseChargeOnline)) {
var eventFormat = purchaseContext.event().orElseThrow().getFormat();
// if we find at least one category matching the criteria, then we can proceed
return categoriesList.stream().anyMatch(findReverseChargeCategory(reverseChargeInPerson, reverseChargeOnline, eventFormat));
}
var vatStatus = purchaseContext.getVatStatus();
return vatStatus == INCLUDED || vatStatus == NOT_INCLUDED;
}).filter(e -> vatChecker.isReverseChargeEnabledFor(purchaseContext)).flatMap(e -> vatChecker.checkVat(contactAndTicketsForm.getVatNr(), country, purchaseContext));
if (vatDetail.isPresent()) {
var vatValidation = vatDetail.get();
if (!vatValidation.isValid()) {
bindingResult.rejectValue("vatNr", "error.STEP_2_INVALID_VAT");
} else {
var reservation = ticketReservationManager.findById(reservationId).orElseThrow();
var currencyCode = reservation.getCurrencyCode();
PriceContainer.VatStatus vatStatus = determineVatStatus(purchaseContext.getVatStatus(), vatValidation.isVatExempt());
// standard case: Reverse Charge is applied to the entire reservation
var discount = reservation.getPromoCodeDiscountId() != null ? promoCodeDiscountRepository.findById(reservation.getPromoCodeDiscountId()) : null;
if (!isEvent || (reverseChargeOnline && reverseChargeInPerson)) {
if (isEvent) {
var event = purchaseContext.event().orElseThrow();
var priceContainers = mapPriceContainersByCategoryId(categoriesList, (a) -> true, currencyCode, vatStatus, discount, event);
// update all tickets in reservation to match the VAT_STATUS
ticketRepository.updateVatStatusForReservation(reservationId, vatStatus);
updateTicketPricesByCategory(reservationId, currencyCode, vatStatus, event, priceContainers);
}
updateBillingData(reservationId, contactAndTicketsForm, purchaseContext, country, trimToNull(vatValidation.getVatNr()), reservation, vatStatus);
} else {
var event = purchaseContext.event().orElseThrow();
var eventFormat = event.getFormat();
var matchingCategories = mapPriceContainersByCategoryId(categoriesList, findReverseChargeCategory(reverseChargeInPerson, reverseChargeOnline, eventFormat), currencyCode, vatStatus, discount, event);
updateTicketPricesByCategory(reservationId, currencyCode, vatStatus, event, matchingCategories);
// update billing data for the reservation, using the original VatStatus from reservation
updateBillingData(reservationId, contactAndTicketsForm, purchaseContext, country, trimToNull(vatValidation.getVatNr()), reservation, reservation.getVatStatus());
}
vatChecker.logSuccessfulValidation(vatValidation, reservationId, purchaseContext);
}
} else if (optionalReservation.isPresent() && contactAndTicketsForm.isItalyEInvoicingSplitPayment()) {
var reservation = optionalReservation.get();
var vatStatus = purchaseContext.getVatStatus() == INCLUDED ? INCLUDED_NOT_CHARGED : NOT_INCLUDED_NOT_CHARGED;
updateBillingData(reservationId, contactAndTicketsForm, purchaseContext, country, trimToNull(contactAndTicketsForm.getVatNr()), reservation, vatStatus);
}
} catch (IllegalStateException ise) {
// vat checker failure
bindingResult.rejectValue("vatNr", "error.vatVIESDown");
}
}
Aggregations