public static void Run() { OutboundMail mail = OutboundMail.GetFirstUnresolved(); if (mail == null) { return; // No unresolved -- nothing to do } // Use a dictionary to add people int downwardCount = 0; int upwardCount = 0; Dictionary <int, bool> officerIds = new Dictionary <int, bool>(); Dictionary <int, bool> personIds = new Dictionary <int, bool>(); // Add the affected people switch (mail.MailType) { case (int)TypedMailTemplate.TemplateType.MemberMail: // All members at this org and geography People people = People.FromOrganizationAndGeography(mail.Organization, mail.Geography); downwardCount = people.Count; foreach (Person person in people) { personIds[person.Identity] = true; } break; case (int)TypedMailTemplate.TemplateType.OfficerMail: // All officers at this org and geography int[] officers = Roles.GetAllDownwardRoles(mail.OrganizationId, mail.GeographyId); downwardCount = officers.Length; foreach (int personId in officers) { officerIds[personId] = true; } break; default: throw new InvalidOperationException("Unhandled mail mode; can't resolve mail id " + mail.Identity); } int[] upwardIds = Roles.GetAllUpwardRoles(mail.OrganizationId, mail.GeographyId); upwardCount = upwardIds.Length; foreach (int personId in upwardIds) { // Filter for subscription of copies to local mail. Inefficient filter, room for optimization. if (Person.FromIdentity(personId).IsSubscribing(NewsletterFeed.TypeID.OfficerUpwardCopies)) { officerIds[personId] = true; } } // Assemble arrays List <int> officerIdList = new List <int>(); foreach (int officerId in officerIds.Keys) { officerIdList.Add(officerId); if (personIds.ContainsKey(officerId)) { // If somebody is going to recieve this mail both due to area coverage and // chain of command, send as chain of command only personIds.Remove(officerId); } } List <int> personIdList = new List <int>(); foreach (int personId in personIds.Keys) { personIdList.Add(personId); } // Check for people who have declined local mail Dictionary <int, bool> decliners = new Dictionary <int, bool>(); int declineCount = decliners.Count; if (declineCount > 0) { foreach (int personId in decliners.Keys) { personIds.Remove(personId); } // Rebuild list after decliners gone personIdList = new List <int>(); foreach (int personId in personIds.Keys) { personIdList.Add(personId); } } // TODO: Get queue count to give a time estimate until transmission // Create recipients mail.AddRecipients(personIdList.ToArray(), false); mail.AddRecipients(officerIdList.ToArray(), true); int countTotal = personIdList.Count + officerIdList.Count; // Mark as ready mail.SetRecipientCount(countTotal); mail.SetResolved(); // TODO: Set recipient count of mail // Create a mail to the author string mailBody = "Your outbound mail with the title \"" + mail.Title + "\" has been resolved for recipients and " + "will be sent to " + countTotal.ToString("#,##0") + " people.\r\n\r\nOut of these " + countTotal.ToString("#,##0") + ", " + (downwardCount - declineCount).ToString("#,##0") + " are people within the requested " + "organization/geography (" + Organization.FromIdentity(mail.OrganizationId).Name + "/" + Geography.FromIdentity(mail.GeographyId).Name + "), and " + upwardCount.ToString("#,##0") + " are people in the chain of command who are " + "copied on the mail to know what's happening in the organization. There is normally some overlap between these two groups.\r\n\r\n"; if (declineCount > 1) { mailBody += declineCount.ToString("#,##0") + " people will not receive the message because they have declined local mail.\r\n\r\n"; } else if (declineCount == 1) { mailBody += "One person will not receive the message because he or she has declined local mail.\r\n\r\n"; } mailBody += "Transmissions will begin " + (mail.ReleaseDateTime < DateTime.Now ? "immediately" : "in " + (mail.ReleaseDateTime - DateTime.Now).Minutes + " minutes") + ".\r\n"; new MailTransmitter( "PirateWeb", "*****@*****.**", "Mail resolved: " + mail.Title + " (" + countTotal + " recipients)", mailBody, Person.FromIdentity(mail.AuthorPersonId), true).Send(); }