public string CancelEvent(long hostId, CancelEventRequest value) { //Validate if event EventsServices eventsServices = new EventsServices(); EventInfo eventInfo = eventsServices.GetEventByRef(hostId, value.ReferenceId); if (eventInfo == null) { return(CancelEventStatuses.EventNotFound); } //Validate event status if (eventInfo.Status != EventStatuses.Active) { return(CancelEventStatuses.EventNotActive); } //Validate if event start date is over if (DateTime.UtcNow >= eventInfo.StartDate) { return(CancelEventStatuses.EventHasAlreadyStarted); } //Cancel and Refund all tickets BookingServices bookingService = new BookingServices(); var tickets = bookingService.GetTicketsByEvent(hostId, value.ReferenceId); if (tickets != null) { foreach (var ticket in tickets) { string status = null; CancelAndRefundTicket(hostId, ticket.TicketId.Value, out status); //Not required to check on status as cancel event will try to cancel and refund all tickets } } //Update event status to Cancelled UpdateEventStatusRequest req = new UpdateEventStatusRequest(); req.ReferenceId = value.ReferenceId; req.NewStatus = EventStatuses.Cancelled; UpdateEventStatus(hostId, req); return(CancelEventStatuses.Success); }
public BookEventResponse BookEvent(long hostId, BookEventRequest value, out string status) { BookEventResponse result = null; //Validate if customer exist CustomerServices customerServices = new CustomerServices(); var customer = customerServices.GetCustomerByRef(hostId, value.CustomerReferenceId); if (customer == null) { status = BookEventStatuses.CustomerNotFound; return(null); } //Validate if event and tier exist EventsServices eventsServices = new EventsServices(); EventInfo eventInfo = eventsServices.GetEventByRef(hostId, value.EventReferenceId); if (eventInfo == null) { status = BookEventStatuses.EventNotFound; return(null); } List <EventTierInfo> eventTiers = eventsServices.GetEventTiersByEventId(eventInfo.EventId.Value); if (eventTiers == null && eventTiers.Count == 0) { status = BookEventStatuses.EventNotFound; return(null); } //Validate event status if (eventInfo.Status != "Active") { status = BookEventStatuses.EventNotActive; return(null); } //Validate if event has already started if (DateTime.UtcNow >= eventInfo.StartDate) { status = BookEventStatuses.EventHasAlreadyStarted; return(null); } //Validate if all requested tiers exist List <string> allAvailableEventTiers = eventTiers.Select(x => x.ReferenceId).ToList(); List <string> requestedEventTiers = value.Tickets.Select(x => x.EventTierReferenceId).ToList(); bool contained = !requestedEventTiers.Except(allAvailableEventTiers).Any(); if (!contained) { status = BookEventStatuses.TierNotFound; return(null); } //Validate requested ticket quantities (must be more than zero) if (value.Tickets.Where(x => x.Quantity < 1).Count() > 0) { status = BookEventStatuses.InvalidTicketQuantity; return(null); } //Validate if tickets are still available for the requested quantities foreach (var ticket in value.Tickets) { var tier = eventTiers.Where(x => x.ReferenceId == ticket.EventTierReferenceId).ToList()[0]; if (tier.AvailableTickets < ticket.Quantity) { status = BookEventStatuses.InsufficientTickets; return(null); } } //Calculate total cost decimal totalCost = 0; foreach (var ticket in value.Tickets) { var tier = eventTiers.Where(x => x.ReferenceId == ticket.EventTierReferenceId).ToList()[0]; totalCost += (ticket.Quantity * tier.Price.Value); } //Check customer wallet balance if (customer.WalletBalance < totalCost) { status = BookEventStatuses.CustomerInsufficientFunds; return(null); } //TODO: Transaction lock for thread safety string bookingConfirmation = null; string ticketNumber = null; string ticketUniqueId = null; List <KeyValuePair <long, string> > tierTicketNumbers = new List <KeyValuePair <long, string> >(); //Insert customer booking bookingConfirmation = GenerateBookingConfirmation(hostId); long bookingId = InsertUserBooking(customer.CustomerId.Value, eventInfo.EventId.Value, bookingConfirmation); //Perform transaction WalletServices walletService = new WalletServices(); walletService.Transfer(customer.WalletAddress, eventInfo.WalletAddress, totalCost, bookingId, "Booking"); //Insert customer tickets foreach (var ticketPurchase in value.Tickets) { var tier = eventTiers.Where(x => x.ReferenceId == ticketPurchase.EventTierReferenceId).ToList()[0]; for (int i = 0; i < ticketPurchase.Quantity; i++) { ticketNumber = GenerateTicketNumber(eventInfo.EventId.Value); ticketUniqueId = HashUtility.GenerateHash(); InsertUserTicket(customer.CustomerId.Value, bookingId, eventInfo.EventId.Value, tier.TierId.Value, ticketNumber, tier.Price.Value, "Active", ticketUniqueId); tierTicketNumbers.Add(new KeyValuePair <long, string>(tier.TierId.Value, ticketNumber)); } } //Update tickets availability foreach (var ticket in value.Tickets) { var tier = eventTiers.Where(x => x.ReferenceId == ticket.EventTierReferenceId).ToList()[0]; UpdateAvailableTickets(tier.TierId.Value, tier.AvailableTickets.Value - ticket.Quantity); } //Commit to blockchain ContractApi blockchainContract = new ContractApi(); for (int i = 0; i < value.Tickets.Count; i++) { var ticket = value.Tickets[i]; var tier = eventTiers .Where(x => x.ReferenceId == ticket.EventTierReferenceId).ToList()[0]; List <string> ticketNumbers = tierTicketNumbers .Where(x => x.Key == tier.TierId.Value) .Select(x => x.Value).ToList(); // Update: Use BookEventV2 method on smart contract //blockchainContract.BookEvent(customer.CustomerAddress, eventInfo.EventUniqueId, tier.TierUniqueId, ticketNumbers); foreach (string number in ticketNumbers) { blockchainContract.BookEventV2(customer.CustomerAddress, eventInfo.EventUniqueId, tier.TierUniqueId, number); } } result = new BookEventResponse(); result.ConfirmationNumber = bookingConfirmation; result.TicketNumbers = tierTicketNumbers.Select(x => x.Value).ToList(); status = BookEventStatuses.Success; return(result); }