Skip to content

Commit

Permalink
fix #405 -
Browse files Browse the repository at this point in the history
(cherry picked from commit 24ea01e)
  • Loading branch information
cbellone committed Mar 18, 2018
1 parent 9724578 commit 438422e
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 25 deletions.
3 changes: 2 additions & 1 deletion src/main/java/alfio/manager/TicketReservationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,8 @@ List<SummaryRow> extractSummary(String reservationId, PriceContainer.VatStatus r
List<AdditionalServiceItemPriceContainer> prices = generateASIPriceContainers(event, null).apply(entry).collect(toList());
AdditionalServiceItemPriceContainer first = prices.get(0);
final int subtotal = prices.stream().mapToInt(AdditionalServiceItemPriceContainer::getSrcPriceCts).sum();
return new SummaryRow(title.getValue(), formatCents(first.getSrcPriceCts()), formatCents(first.getSrcPriceCts()), prices.size(), formatCents(subtotal), formatCents(subtotal), subtotal, SummaryRow.SummaryType.ADDITIONAL_SERVICE);
final int subtotalBeforeVat = prices.stream().mapToInt(AdditionalServiceItemPriceContainer::getSummaryPriceBeforeVatCts).sum();
return new SummaryRow(title.getValue(), formatCents(first.getSrcPriceCts()), formatCents(first.getSummaryPriceBeforeVatCts()), prices.size(), formatCents(subtotal), formatCents(subtotalBeforeVat), subtotal, SummaryRow.SummaryType.ADDITIONAL_SERVICE);
}).collect(Collectors.toList()));

Optional.ofNullable(promoCodeDiscount).ifPresent(promo -> {
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/alfio/model/SummaryPriceContainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* This file is part of alf.io.
*
* alf.io is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* alf.io is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with alf.io. If not, see <http://www.gnu.org/licenses/>.
*/
package alfio.model;

import static alfio.util.MonetaryUtil.centsToUnit;
import static alfio.util.MonetaryUtil.unitToCents;

public interface SummaryPriceContainer extends PriceContainer {
Integer getVatCts();
Integer getFinalPriceCts();

default int getSummaryPriceBeforeVatCts() {
PriceContainer.VatStatus vatStatus = getVatStatus();
if(vatStatus == PriceContainer.VatStatus.NOT_INCLUDED_EXEMPT) {
return getSrcPriceCts();
} else if(vatStatus == PriceContainer.VatStatus.INCLUDED_EXEMPT) {
return getSrcPriceCts() + unitToCents(vatStatus.extractVat(centsToUnit(getSrcPriceCts()), getVatPercentageOrZero()));
}
return getFinalPriceCts() - getVatCts();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import java.util.Optional;

@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class AdditionalServiceItemPriceContainer implements PriceContainer {
public class AdditionalServiceItemPriceContainer implements SummaryPriceContainer {
@Delegate(excludes = PriceContainer.class)
private final AdditionalServiceItem additionalServiceItem;
private final AdditionalService additionalService;
Expand Down
32 changes: 18 additions & 14 deletions src/main/java/alfio/model/decorator/TicketPriceContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package alfio.model.decorator;

import alfio.model.Event;
import alfio.model.PriceContainer;
import alfio.model.PromoCodeDiscount;
import alfio.model.SummaryPriceContainer;
import alfio.model.Ticket;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
Expand All @@ -27,13 +27,12 @@
import java.math.BigDecimal;
import java.util.Optional;

import static alfio.util.MonetaryUtil.centsToUnit;
import static alfio.util.MonetaryUtil.unitToCents;

@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class TicketPriceContainer implements PriceContainer {
public class TicketPriceContainer implements SummaryPriceContainer {

@Delegate
@Delegate(excludes = OverridePriceContainer.class)
private final Ticket ticket;
private final PromoCodeDiscount promoCodeDiscount;
private final String currencyCode;
Expand Down Expand Up @@ -68,18 +67,23 @@ public int getSummarySrcPriceCts() {
return getSrcPriceCts();
}

public int getSummaryPriceBeforeVatCts() {
VatStatus vatStatus = getVatStatus();
if(vatStatus == VatStatus.NOT_INCLUDED_EXEMPT) {
return getSrcPriceCts();
} else if(vatStatus == VatStatus.INCLUDED_EXEMPT) {
return getSrcPriceCts() + unitToCents(vatStatus.extractVat(centsToUnit(getSrcPriceCts()), getVatPercentageOrZero()));
}
return getFinalPriceCts() - getVatCts();
}

public static TicketPriceContainer from(Ticket t, VatStatus reservationVatStatus, Event e, PromoCodeDiscount discount) {
VatStatus vatStatus = Optional.ofNullable(reservationVatStatus).filter(s -> s == VatStatus.INCLUDED_EXEMPT || s == VatStatus.NOT_INCLUDED_EXEMPT).orElseGet(e::getVatStatus);
return new TicketPriceContainer(t, discount, e.getCurrency(), e.getVat(), vatStatus);
}

@Override
public Integer getVatCts() {
return ticket.getVatCts();
}

@Override
public Integer getFinalPriceCts() {
return ticket.getFinalPriceCts();
}

private interface OverridePriceContainer {
int getVatCts();
int getFinalPriceCts();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,9 @@
import alfio.manager.support.PaymentResult;
import alfio.manager.user.UserManager;
import alfio.model.*;
import alfio.model.modification.DateTimeModification;
import alfio.model.modification.TicketCategoryModification;
import alfio.model.modification.TicketReservationModification;
import alfio.model.modification.TicketReservationWithOptionalCodeModification;
import alfio.model.modification.*;
import alfio.model.transaction.PaymentProxy;
import alfio.repository.EventRepository;
import alfio.repository.TicketCategoryRepository;
import alfio.repository.TicketRepository;
import alfio.repository.TicketReservationRepository;
import alfio.repository.*;
import alfio.repository.system.ConfigurationRepository;
import alfio.repository.user.OrganizationRepository;
import alfio.test.util.IntegrationTestUtil;
Expand All @@ -50,7 +44,9 @@
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static alfio.test.util.IntegrationTestUtil.AVAILABLE_SEATS;
import static alfio.test.util.IntegrationTestUtil.initEvent;
Expand Down Expand Up @@ -89,6 +85,8 @@ public class TicketReservationManagerIntegrationTest {
private WaitingQueueManager waitingQueueManager;
@Autowired
private EventRepository eventRepository;
@Autowired
private AdditionalServiceRepository additionalServiceRepository;

@Before
public void ensureConfiguration() {
Expand Down Expand Up @@ -273,6 +271,52 @@ public void testTicketWithDiscount() {

}

@Test
public void testWithAdditionalServices() {
List<TicketCategoryModification> categories = Collections.singletonList(
new TicketCategoryModification(null, "default", AVAILABLE_SEATS,
new DateTimeModification(LocalDate.now(), LocalTime.now()),
new DateTimeModification(LocalDate.now(), LocalTime.now()),
DESCRIPTION, BigDecimal.TEN, false, "", false, null, null, null, null, null));

List<EventModification.AdditionalService> additionalServices = Collections.singletonList(new EventModification.AdditionalService(null, BigDecimal.TEN, true, 1, 100, 5,
DateTimeModification.fromZonedDateTime(ZonedDateTime.now().minusDays(1L)), DateTimeModification.fromZonedDateTime(ZonedDateTime.now().plusDays(1L)),
BigDecimal.TEN, AdditionalService.VatType.INHERITED, Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), AdditionalService.AdditionalServiceType.SUPPLEMENT, AdditionalService.SupplementPolicy.OPTIONAL_UNLIMITED_AMOUNT));
Event event = initEvent(categories, organizationRepository, userManager, eventManager, eventRepository, additionalServices).getKey();

TicketCategory unbounded = ticketCategoryRepository.findByEventId(event.getId()).stream().filter(t -> !t.isBounded()).findFirst().orElseThrow(IllegalStateException::new);

TicketReservationModification tr = new TicketReservationModification();
tr.setAmount(3);
tr.setTicketCategoryId(unbounded.getId());
TicketReservationWithOptionalCodeModification mod = new TicketReservationWithOptionalCodeModification(tr, Optional.empty());

AdditionalServiceReservationModification asrm = new AdditionalServiceReservationModification();
asrm.setAdditionalServiceId(additionalServiceRepository.loadAllForEvent(event.getId()).get(0).getId());
asrm.setQuantity(1);

ASReservationWithOptionalCodeModification asMod = new ASReservationWithOptionalCodeModification(asrm, Optional.empty());

String reservationId = ticketReservationManager.createTicketReservation(event, Collections.singletonList(mod), Collections.singletonList(asMod), DateUtils.addDays(new Date(), 1), Optional.empty(), Optional.of("MYPROMOCODE"), Locale.ENGLISH, false);

TotalPrice totalPrice = ticketReservationManager.totalReservationCostWithVAT(reservationId);

Assert.assertEquals(4000, totalPrice.getPriceWithVAT());//3 tickets + 1 AS
Assert.assertEquals(40, totalPrice.getVAT());
Assert.assertEquals(0, totalPrice.getDiscount());
Assert.assertEquals(0, totalPrice.getDiscountAppliedCount());

OrderSummary orderSummary = ticketReservationManager.orderSummaryForReservationId(reservationId, event, Locale.ENGLISH);
Assert.assertEquals("40.00", orderSummary.getTotalPrice());
Assert.assertEquals("0.40", orderSummary.getTotalVAT());
Assert.assertEquals(3, orderSummary.getTicketAmount());
List<SummaryRow> asRows = orderSummary.getSummary().stream().filter(s -> s.getType() == SummaryRow.SummaryType.ADDITIONAL_SERVICE).collect(Collectors.toList());
Assert.assertEquals(1, asRows.size());
Assert.assertEquals("9.90", asRows.get(0).getPriceBeforeVat());
Assert.assertEquals("9.90", asRows.get(0).getSubTotalBeforeVat());
Assert.assertEquals("10.00", asRows.get(0).getSubTotal());
}

@Test(expected = TicketReservationManager.NotEnoughTicketsException.class)
public void testTicketSelectionNotEnoughTicketsAvailable() {
List<TicketCategoryModification> categories = Collections.singletonList(
Expand Down
11 changes: 10 additions & 1 deletion src/test/java/alfio/test/util/IntegrationTestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ public static Pair<Event, String> initEvent(List<TicketCategoryModification> cat
UserManager userManager,
EventManager eventManager,
EventRepository eventRepository) {
return initEvent(categories, organizationRepository, userManager, eventManager, eventRepository, null);
}

public static Pair<Event, String> initEvent(List<TicketCategoryModification> categories,
OrganizationRepository organizationRepository,
UserManager userManager,
EventManager eventManager,
EventRepository eventRepository,
List<EventModification.AdditionalService> additionalServices) {

String organizationName = UUID.randomUUID().toString();
String username = UUID.randomUUID().toString();
Expand All @@ -108,7 +117,7 @@ public static Pair<Event, String> initEvent(List<TicketCategoryModification> cat
"muh location", "0.0", "0.0", ZoneId.systemDefault().getId(), desc,
new DateTimeModification(LocalDate.now().plusDays(5), LocalTime.now()),
new DateTimeModification(expiration.toLocalDate(), expiration.toLocalTime()),
BigDecimal.TEN, "CHF", AVAILABLE_SEATS, BigDecimal.ONE, true, Collections.singletonList(PaymentProxy.OFFLINE), categories, false, new LocationDescriptor("","","",""), 7, null, null);
BigDecimal.TEN, "CHF", AVAILABLE_SEATS, BigDecimal.ONE, true, Collections.singletonList(PaymentProxy.OFFLINE), categories, false, new LocationDescriptor("","","",""), 7, null, additionalServices);
eventManager.createEvent(em);
Event event = eventManager.getSingleEvent(eventName, username);
Assert.assertEquals(AVAILABLE_SEATS, eventRepository.countExistingTickets(event.getId()).intValue());
Expand Down

0 comments on commit 438422e

Please sign in to comment.