public static void Refund(Usr actionUsr, List<Ticket> tickets, bool refundIncludeBookingFee, decimal chargeToPromoter) { try { if (tickets.Count > 0 && actionUsr.IsSuperAdmin) { chargeToPromoter = Math.Abs(chargeToPromoter); List<int> ticketRunKs = new List<int>(); int promoterK = tickets[0].TicketRun.PromoterK; int eventK = tickets[0].TicketRun.EventK; foreach (Ticket ticket in tickets) { if (promoterK != ticket.TicketRun.PromoterK) throw new Exception("Cannot automate refund for tickets belonging to more than 1 promoter."); if (eventK != ticket.TicketRun.EventK) throw new Exception("Cannot automate refund for tickets belonging to more than 1 event."); } TicketPromoterEvent ticketPromoterEvent = new TicketPromoterEvent(promoterK, eventK); bool chargePromoterTicketPrice = ticketPromoterEvent.FundsReleased && ticketPromoterEvent.FundsTransfer != null && ticketPromoterEvent.FundsTransfer.Status == Transfer.StatusEnum.Success; bool areFundsAlreadyReleased = chargePromoterTicketPrice; decimal sumTicketPrice = 0; string failedTicketKs = ""; List<Exception> failedRefundExceptions = new List<Exception>(); int successfulRefundTransferCount = 0; int successfulRefundQuantity = 0; foreach (Ticket ticket in tickets) { try { RefundTicket(actionUsr, ticket, refundIncludeBookingFee, areFundsAlreadyReleased); if (ticket.Cancelled) { if (!ticketRunKs.Contains(ticket.TicketRunK)) ticketRunKs.Add(ticket.TicketRunK); successfulRefundTransferCount++; successfulRefundQuantity += ticket.Quantity; if (chargePromoterTicketPrice) sumTicketPrice += ticket.Price; } } catch (Exception ex) { failedRefundExceptions.Add(ex); failedTicketKs += ticket.K.ToString() + ", "; } } if (successfulRefundTransferCount > 0 && (chargePromoterTicketPrice || chargeToPromoter > 0)) { // create invoice with tickets.count * chargeToPromoter invoice item for refund. DateTime now = DateTime.Now; InvoiceDataHolder refundChargeInvoiceDH = new InvoiceDataHolder(); refundChargeInvoiceDH.ActionUsrK = Usr.Current.K; refundChargeInvoiceDH.CreatedDateTime = now; refundChargeInvoiceDH.DueDateTime = now.AddDays(tickets[0].TicketRun.Promoter.InvoiceDueDaysEffective > Vars.InvoiceDueDaysDefault ? tickets[0].TicketRun.Promoter.InvoiceDueDaysEffective : Vars.InvoiceDueDaysDefault); refundChargeInvoiceDH.DuplicateGuid = Guid.NewGuid(); refundChargeInvoiceDH.PromoterK = tickets[0].TicketRun.PromoterK; refundChargeInvoiceDH.TaxDateTime = now; refundChargeInvoiceDH.Type = Invoice.Types.Invoice; if (tickets[0].TicketRun.Promoter.PrimaryUsrK != 0) refundChargeInvoiceDH.UsrK = tickets[0].TicketRun.Promoter.PrimaryUsrK; else refundChargeInvoiceDH.UsrK = Usr.Current.K; refundChargeInvoiceDH.VatCode = Invoice.VATCodes.T1; if (chargePromoterTicketPrice) { InvoiceItemDataHolder iidhPrice = new InvoiceItemDataHolder(); iidhPrice.RevenueStartDate = now; iidhPrice.RevenueEndDate = now; iidhPrice.Description = "Ticket price refund charge for " + successfulRefundQuantity.ToString() + " ticket" + (successfulRefundQuantity > 1 ? "s" : ""); iidhPrice.ShortDescription = "Ticket price refund charge"; iidhPrice.Type = InvoiceItem.Types.Misc; iidhPrice.VatCode = InvoiceItem.VATCodes.T9; iidhPrice.SetTotal(Math.Round(sumTicketPrice, 2)); refundChargeInvoiceDH.InvoiceItemDataHolderList.Add(iidhPrice); } InvoiceItemDataHolder iidh = new InvoiceItemDataHolder(); iidh.RevenueStartDate = now; iidh.RevenueEndDate = now; iidh.Description = "Ticket refund charge for " + successfulRefundTransferCount.ToString() + " ticket" + (successfulRefundTransferCount > 1 ? "s" : "") + " transfers"; iidh.ShortDescription = "Ticket refund charge"; iidh.Type = InvoiceItem.Types.Misc; iidh.VatCode = InvoiceItem.VATCodes.T1; iidh.SetTotal(Math.Round(successfulRefundTransferCount * chargeToPromoter, 2)); refundChargeInvoiceDH.InvoiceItemDataHolderList.Add(iidh); Invoice refundChargeInovice = refundChargeInvoiceDH.UpdateInsertDelete(); foreach (int ticketRunK in ticketRunKs) { new TicketRun(ticketRunK).CalculateSoldTicketsAndUpdate(); } refundChargeInovice.UpdateAndAutoApplySuccessfulTransfersWithAvailableMoney(); Utilities.EmailInvoice(refundChargeInovice, true); if (areFundsAlreadyReleased) ticketPromoterEvent.CalculateTotalFundsAndVat(); } failedTicketKs = failedTicketKs.Trim(); if (failedTicketKs.Length > 0) { string exceptionMessages = ""; foreach (Exception ex in failedRefundExceptions) exceptionMessages += ex.Message + "\n\n"; failedTicketKs = failedTicketKs.Substring(0, failedTicketKs.Length - 1); throw new Exception("Failed to refund the following tickets #" + failedTicketKs + ". Exception messages: " + exceptionMessages); } } } catch (Exception ex) { Utilities.AdminEmailAlert("Exception in Ticket.Refund(List<Ticket> tickets)", "Exception in Ticket.Refund(List<Ticket> tickets)", ex, tickets.ConvertAll(ticket => (IBobAsHTML)ticket)); throw ex; } }