in src/Relecloud.Web.CallCenter.Api/Controllers/TicketController.cs [83:183]
public async Task<IActionResult> PurchaseTicketsAsync(PurchaseTicketsRequest purchaseTicketRequest)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest();
}
var errors = new List<string>();
if (purchaseTicketRequest == null)
{
errors.Add("Purchase ticket request must not be null");
}
else
{
if (purchaseTicketRequest.PaymentDetails == null)
{
errors.Add("Missing required payment details");
}
if (purchaseTicketRequest.ConcertIdsAndTicketCounts == null)
{
errors.Add("Missing required concert ticket details");
}
if (string.IsNullOrEmpty(purchaseTicketRequest.UserId))
{
errors.Add("Missing required userId");
}
}
if (errors.Any())
{
return BadRequest(PurchaseTicketsResult.ErrorResponse(errors));
}
await this.concertRepository.CreateOrUpdateUserAsync(new User{
Id = purchaseTicketRequest!.UserId ?? Guid.Empty.ToString(),
DisplayName = purchaseTicketRequest!.PaymentDetails!.Name
});
var orderTotal = await TotalInvoiceAmountAsync(purchaseTicketRequest);
var preAuthRequest = new PreAuthPaymentRequest
{
Amount = orderTotal,
PaymentDetails = purchaseTicketRequest.PaymentDetails!,
Tickets = purchaseTicketRequest.ConcertIdsAndTicketCounts
};
var preAuthResponse = await paymentGatewayService.PreAuthPaymentAsync(preAuthRequest);
if (preAuthResponse.Status != PreAuthPaymentResultStatus.FundsOnHold)
{
return BadRequest(PurchaseTicketsResult.ErrorResponse("We were unable to process this card. Please review your payment details."));
}
var customer = await this.concertRepository.GetCustomerByEmailAsync(purchaseTicketRequest.PaymentDetails!.Email);
var customerId = customer?.Id ?? 0;
if (customerId == 0)
{
var createResult = await this.concertRepository.CreateCustomerAsync(new Customer
{
Name = purchaseTicketRequest.PaymentDetails.Name,
Email = purchaseTicketRequest.PaymentDetails.Email,
Phone = purchaseTicketRequest.PaymentDetails.Phone,
});
if (createResult.Success)
{
customerId = createResult.NewId;
}
}
foreach (var concertAndTickets in purchaseTicketRequest.ConcertIdsAndTicketCounts!)
{
var reserveResult = await this.ticketService.ReserveTicketsAsync(concertAndTickets.Key, purchaseTicketRequest.UserId!, concertAndTickets.Value, customerId);
if (reserveResult.Status != ReserveTicketsResultStatus.Success)
{
return BadRequest(PurchaseTicketsResult.ErrorResponse($"{reserveResult.Status}: Tickets not successfully reserved"));
}
}
//built-in assumption: if generating a ticket throws an error then we should not reach this code
// and the hold on the customer's card will automatically be released by the Payment Gateway
var captureRequest = new CapturePaymentRequest
{
HoldCode = preAuthResponse.HoldCode,
TotalPrice = orderTotal
};
await paymentGatewayService.CapturePaymentAsync(captureRequest);
return Accepted(new PurchaseTicketsResult
{
Status = PurchaseTicketsResultStatus.Success
});
}
catch (Exception ex)
{
logger.LogError(ex, "Unhandled exception from TicketController.PurchaseTicketsAsync");
return Problem("Unable to Create the ticket");
}
}