private void SetAuthorInfo(ApplicationCore.Models.Ticket entity) { if (User.IsPerson()) { Guid currentUserId = User.GetUserId(); entity.EditorId = currentUserId; if (entity.Id == Guid.Empty) { entity.CreatorId = currentUserId; } } else { // API Client (S2S) without user. // TODO: Save client id as author information. entity.EditorId = null; } var timestamp = DateTime.UtcNow; entity.EditedAt = timestamp; if (entity.Id == Guid.Empty) { entity.CreatedAt = timestamp; } }
private async Task <IActionResult> ValidateTicketAsync(ApplicationCore.Models.Ticket ticket, string ticketNumber = null, string ticketSecret = null) { if (ticket == null) { string lookupValueType = ticketNumber == null ? "secret" : "number"; string lookupValue = ticketNumber ?? ticketSecret; _logger.LogInformation( $"Ticket with {lookupValueType} {lookupValue} was not found in the database.", lookupValue); return(TicketNotFound()); } ClaimsPrincipal currentUser = await TryGetAuthenticatedUser(); UserContext context = currentUser.GetContext(); // If the user is logged in for a single event only, // check if the ticket and the event are the same. if (context.EventId != null && context.EventId != ticket.EventId) { return(WrongEvent()); } if (!currentUser.Identity.IsAuthenticated) { _logger.LogInformation("Unauthorized. Redirect to event homepage."); string validationUri = GetTicketValidationUri(ticket.TicketSecret); string redirectUrl = await _ticketRedirectService.GetRedirectUrlAsync(ticket.Id, validationUri); return(Redirect(redirectUrl)); } var currentEvent = ticket.Event; if (currentEvent == null) { // try to get the event for which the master qr code was issued. UserContext userContext = User.GetContext(); if (userContext?.EventId != null) { currentEvent = _context.Events.Find(userContext.EventId); } } if (currentEvent != null && currentEvent.IsConference) { return(ConferenceCheckInDialog(ticket)); } if (ticket.Validated) { _logger.LogInformation("The ticket has already been used before."); return(View("TicketUsed", ticket)); } ticket.Validated = true; _context.SaveChanges(); return(View("TicketValid", ticket)); }
public async Task <IActionResult> ValidateTicketByQrCodeValueAsync(string secret) { if (secret == null) { return(NotFound()); } ApplicationCore.Models.Ticket ticket = await FindTicketAsync(e => e.TicketSecret == secret); return(await ValidateTicketAsync(ticket, ticketSecret : secret)); }
public async Task <IActionResult> ValidateTicketByNumberAsync(string number) { if (number == null) { return(NotFound()); } ApplicationCore.Models.Ticket ticket = await FindTicketAsync(e => e.TicketNumber == number); return(await ValidateTicketAsync(ticket, ticketNumber : number)); }
public async Task <ActionResult <Ticket> > CreateTicketAsync(Ticket model) { if (model.Id != Guid.Empty) { return(BadRequest( new ProblemDetails { Detail = "This method can't be used to update tickets." })); } if (await _context.Tickets.AnyAsync(t => t.TicketNumber == model.TicketNumber)) { return(BadRequest( new ProblemDetails { Detail = $"The ticket number \"{model.TicketNumber}\" is already in use." })); } var evt = await _context.Events.FindAsync(model.EventId); if (evt == null) { return(BadRequest( new ProblemDetails { Detail = $"There's no event with id {model.EventId}." })); } var entity = new ApplicationCore.Models.Ticket(); _mapper.Map(model, entity); entity.TicketSecret = Guid.NewGuid().ToString("N"); entity.TicketNumber = entity.TicketNumber ?? _ticketNumberService.GenerateTicketNumber(evt); SetAuthorInfo(entity); _context.Add(entity); _context.SaveChanges(); _context.Entry(entity).Reference(e => e.TicketType).Load(); if (entity.BookingDate != null) { await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent { Time = entity.BookingDate.Value, TicketId = entity.Id, Action = EventManagementConstants.Auditing.Actions.TicketOrder, Detail = $"Ticket der Kategorie \"{entity.TicketType.Name}\" wurde für {entity.TicketType.Price:c} bestellt." }); } model = _mapper.Map <Ticket>(entity); return(CreatedAtAction(nameof(GetById), new { id = model.Id }, model)); }
private async Task SendMailAsync(ApplicationCore.Models.Ticket ticket, int secondsDelay = BatchMailSentIntervalSeconds) { var deliveryType = TicketDeliveryType.Email; await _ticketDeliveryService.ValidateAsync(ticket.Id, deliveryType); string validationUriFormat = GetTicketValidationUriFormatString(); string validationUri = GetTicketValidationUri(ticket.TicketSecret); string homepageUrl = await _ticketRedirectService.GetRedirectUrlAsync(ticket.Id, validationUri); Expression <Action> methodCall = () => _ticketDeliveryService.SendTicketAsync( ticket.Id, deliveryType, validationUriFormat, homepageUrl); _backgroundJobs.Schedule( methodCall, TimeSpan.FromSeconds(secondsDelay)); }
/// <summary>Update ticket data and return the right <see cref="IActionResult"/>.</summary> /// <param name="id">Id of the ticket to update.</param> /// <param name="modelResolver">Function that returns the new model with updated values.</param> private async Task <IActionResult> UpdateTicketResultAsync(Guid id, Func <ApplicationCore.Models.Ticket, Ticket> modelResolver) { ApplicationCore.Models.Ticket entity = await _context.Tickets.FindAsync(id); if (entity == null) { return(NotFound()); } Ticket model = modelResolver(entity); if (model.TicketNumber != entity.TicketNumber) { return(BadRequest( new ProblemDetails { Detail = "The TicketNumber can't be changed." })); } if (model.EventId != entity.EventId) { return(BadRequest( new ProblemDetails { Detail = "The ticket is only valid for a single event." })); } if (model.TermsAccepted != entity.TermsAccepted) { await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent(model.TermsAccepted) { Time = DateTime.UtcNow, TicketId = entity.Id, Action = EventManagementConstants.Auditing.Actions.TermsAccepted, Detail = model.TermsAccepted ? "Die Einverständniserklärung der Eltern wurde abgegeben." : "Status der Einverständniserklärung wurde in \"nicht abgegeben\" geändert." }); } if (model.Validated != entity.Validated) { var checkInStatus = model.Validated ? "erfolgreich" : "ausstehend"; await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent(model.Validated) { Time = DateTime.UtcNow, TicketId = entity.Id, Action = EventManagementConstants.Auditing.Actions.TicketStatusChanged, Detail = $"Check-in-Status wurde von einem Administrator auf \"{checkInStatus}\" geändert." }); } _mapper.Map(model, entity); SetAuthorInfo(entity); bool ticketTypeModified = _context.Entry(entity).Property(e => e.TicketTypeId).IsModified; bool paymentStatusModified = _context.Entry(entity).Property(e => e.PaymentStatus).IsModified; if (ticketTypeModified) { _context.Entry(entity).Reference(e => e.TicketType).Load(); await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent { Time = DateTime.UtcNow, TicketId = entity.Id, Action = EventManagementConstants.Auditing.Actions.TicketTypeChanged, Detail = $"Der Ticket-Typ wurde auf \"{entity.TicketType.Name}\" geändert." }); } if (paymentStatusModified) { string description = entity.PaymentStatus.GetDescription(); float amountPaid = entity.AmountPaid.GetValueOrDefault(); _context.Entry(entity).Reference(e => e.TicketType).Load(); await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent { Time = DateTime.UtcNow, TicketId = entity.Id, Action = EventManagementConstants.Auditing.Actions.PaymentStatusUpdated, Detail = $"Der Zahlungstatus wurde auf \"{description}\" geändert. " + $"Bereits bezahlter Betrag: {amountPaid:c} von {entity.TicketType.Price:c}. " + $"Ticket-Typ: {entity.TicketType.Name}.", Level = _levels[entity.PaymentStatus] }); } await _context.SaveChangesAsync(); return(NoContent()); }
private IActionResult ConferenceCheckInDialog(ApplicationCore.Models.Ticket ticket) { var model = _mapper.Map <Models.ConferenceDialogModel>(ticket); return(View("ConferenceDialog", model)); }