Skip to content

Commit

Permalink
#571 generate invoice number only when the payment gateway replies wi…
Browse files Browse the repository at this point in the history
…th a successful status
  • Loading branch information
cbellone committed Dec 29, 2018
1 parent 8e1afd5 commit f278c76
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
47 changes: 27 additions & 20 deletions src/main/java/alfio/manager/TicketReservationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,10 @@ Optional<SpecialPrice> fixToken(Optional<SpecialPrice> token, int ticketCategory
return specialPrice;
}

public PaymentResult performPayment( PaymentSpecification spec, TotalPrice reservationCost, Optional<String> specialPriceSessionId, Optional<PaymentProxy> method) {
public PaymentResult performPayment(PaymentSpecification spec,
TotalPrice reservationCost,
Optional<String> specialPriceSessionId,
Optional<PaymentProxy> method) {
PaymentProxy paymentProxy = evaluatePaymentProxy(method, reservationCost);

if(!acquireGroupMembers(spec.getReservationId(), spec.getEvent())) {
Expand All @@ -359,39 +362,26 @@ public PaymentResult performPayment( PaymentSpecification spec, TotalPrice reser
if(!initPaymentProcess(reservationCost, paymentProxy, spec)) {
return PaymentResult.failed("error.STEP2_UNABLE_TO_TRANSITION");
}

try {
PaymentResult paymentResult;
ticketReservationRepository.lockReservationForUpdate(spec.getReservationId());
//save billing data in case we have to go back to PENDING
ticketReservationRepository.updateBillingData(spec.getVatStatus(), spec.getVatNr(), spec.getVatCountryCode(), spec.isInvoiceRequested(), spec.getReservationId());
if(isDiscountCodeUsageExceeded(spec.getReservationId())) {
return PaymentResult.failed(ErrorsCode.STEP_2_DISCOUNT_CODE_USAGE_EXCEEDED);
}
if(reservationCost.getPriceWithVAT() > 0) {
if(spec.isInvoiceRequested() && configurationManager.hasAllConfigurationsForInvoice(spec.getEvent())) {
int invoiceSequence = invoiceSequencesRepository.lockReservationForUpdate(spec.getEvent().getOrganizationId());
invoiceSequencesRepository.incrementSequenceFor(spec.getEvent().getOrganizationId());
String pattern = configurationManager.getStringConfigValue(Configuration.from(spec.getEvent().getOrganizationId(), spec.getEvent().getId(), ConfigurationKeys.INVOICE_NUMBER_PATTERN), "%d");
ticketReservationRepository.setInvoiceNumber(spec.getReservationId(), String.format(pattern, invoiceSequence));
}
ticketReservationRepository.updateBillingData(spec.getVatStatus(), spec.getVatNr(), spec.getVatCountryCode(), spec.isInvoiceRequested(), spec.getReservationId());

//
extensionManager.handleInvoiceGeneration(spec, reservationCost, ticketReservationRepository.getBillingDetailsForReservation(spec.getReservationId()))
.ifPresent(invoiceGeneration -> {
if (invoiceGeneration.getInvoiceNumber() != null) {
ticketReservationRepository.setInvoiceNumber(spec.getReservationId(), invoiceGeneration.getInvoiceNumber());
}
});

if(reservationCost.requiresPayment()) {
paymentResult = paymentManager.lookupProviderByMethod(paymentProxy.getPaymentMethod(), spec.getPaymentContext())
.map( paymentProvider -> paymentProvider.getTokenAndPay(spec) )
.orElseGet( () -> PaymentResult.failed("error.STEP2_STRIPE_unexpected") );

} else {
paymentResult = PaymentResult.successful(NOT_YET_PAID_TRANSACTION_ID);
}

if (paymentResult.isSuccessful()) {
completeReservation( spec, specialPriceSessionId, paymentProxy );
generateInvoiceNumber(spec, reservationCost);
completeReservation(spec, specialPriceSessionId, paymentProxy);
} else if(paymentResult.isFailed()) {
reTransitionToPending(spec.getReservationId());
}
Expand All @@ -405,6 +395,23 @@ public PaymentResult performPayment( PaymentSpecification spec, TotalPrice reser

}

private void generateInvoiceNumber(PaymentSpecification spec, TotalPrice reservationCost) {
if(!reservationCost.requiresPayment() || !spec.isInvoiceRequested() || !configurationManager.hasAllConfigurationsForInvoice(spec.getEvent())) {
return;
}

String invoiceNumber = extensionManager.handleInvoiceGeneration(spec, reservationCost, ticketReservationRepository.getBillingDetailsForReservation(spec.getReservationId()))
.flatMap(invoiceGeneration -> Optional.ofNullable(StringUtils.trimToNull(invoiceGeneration.getInvoiceNumber())))
.orElseGet(() -> {
int invoiceSequence = invoiceSequencesRepository.lockReservationForUpdate(spec.getEvent().getOrganizationId());
invoiceSequencesRepository.incrementSequenceFor(spec.getEvent().getOrganizationId());
String pattern = configurationManager.getStringConfigValue(Configuration.from(spec.getEvent().getOrganizationId(), spec.getEvent().getId(), ConfigurationKeys.INVOICE_NUMBER_PATTERN), "%d");
return String.format(pattern, invoiceSequence);
});

ticketReservationRepository.setInvoiceNumber(spec.getReservationId(), invoiceNumber);
}

private boolean isDiscountCodeUsageExceeded(String reservationId) {
TicketReservation reservation = ticketReservationRepository.findReservationById(reservationId);
if(reservation.getPromoCodeDiscountId() != null) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/alfio/model/TotalPrice.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ public TotalPrice(@JsonProperty("priceWithVAT") int priceWithVAT,
this.discount = discount;
this.discountAppliedCount = discountAppliedCount;
}

public boolean requiresPayment() {
return this.priceWithVAT > 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ void returnFailureCodeIfPaymentNotSuccessful() {
verify(ticketReservationRepository).updateTicketReservation(eq(RESERVATION_ID), eq(TicketReservationStatus.IN_PAYMENT.toString()), anyString(), anyString(), isNull(), isNull(), anyString(), isNull(), isNull(), eq(PaymentProxy.STRIPE.toString()), isNull());
verify(ticketReservationRepository).lockReservationForUpdate(eq(RESERVATION_ID));
verify(ticketReservationRepository).updateReservationStatus(eq(RESERVATION_ID), eq(TicketReservationStatus.PENDING.toString()));
verify(configurationManager).hasAllConfigurationsForInvoice(eq(event));
verify(configurationManager, never()).hasAllConfigurationsForInvoice(eq(event));
verify(ticketReservationRepository).updateBillingData(eq(PriceContainer.VatStatus.INCLUDED), eq("12345"), eq("IT"), eq(true), eq(RESERVATION_ID));
}

Expand Down

0 comments on commit f278c76

Please sign in to comment.