/// <summary> /// Sends mail to all members. /// </summary> /// <param name="inputStream"></param> /// <param name="debug"></param> private void SendMail(Stream inputStream, bool debug) { if (inputStream == null) // No input information. { return; } // Get birthday tree: string from = string.Empty; XmlData properties = new XmlData(); List <BirthdayBoy> fees = new List <BirthdayBoy>(); lock (_lockObject) { properties.Load(inputStream); from = properties.Keys[XmlData.MAIL_FROM][XmlData.VAL]; // Fill birthday tree to simplify computing: foreach (string fileName in Directory.GetFiles(BIRTHDAYS_PATH, "*.xml")) { var fee = new XmlData(); fee.Load(fileName); if (fee.DocumentElement?.Attributes == null) { continue; } var birthdayFee = new BirthdayBoy { Id = fee.DocumentElement.Attributes[XmlData.ID].Value, Val = fee.DocumentElement.Attributes[XmlData.VAL].Value // Comments. }; fees.Add(birthdayFee); foreach (Dictionary <string, string> attributes in fee.Keys.Values) { // Get attributes: string id = attributes[XmlData.ID], name = attributes[XmlData.NAME], email = attributes[XmlData.EMAIL]; if (!DateTime.TryParse(attributes[XmlData.BIRTHDAY], out DateTime birthday)) { birthday = DateTime.MinValue; //_logger.Error(() => $"Incorrect birthday format for the '{name}'."); } if (!double.TryParse(attributes[XmlData.FEE], NumberStyles.None, CultureInfo.InvariantCulture, out double funds)) { funds = 0; } // Save fee information: if (birthdayFee.Id == id) { birthdayFee.Name = name; birthdayFee.Email = email; birthdayFee.Birthday = birthday; birthdayFee.Fee = funds; continue; // Not subscribe the birthday boy. } // Check minimal fee: if (funds < BIRTHDAY_MIN_FEE && attributes[XmlData.ACTIVE] == "1" || // Compute mailing list only for active members. email == from) // Send mail for admin everytime. { var birthdayBoy = new BirthdayBoy { Id = id, Name = name, Email = email, Birthday = birthday, Fee = funds }; birthdayFee.Subscribers.Add(birthdayBoy); } } } } // Compute groups to send letters: StringBuilder debugMessage = new StringBuilder(); var groups = GetCombinations(fees); List <BirthdayBoy> sent = new List <BirthdayBoy>(); foreach (List <BirthdayBoy> boys in groups.OrderByDescending(b => b.Count)) { IEnumerable <BirthdayBoy> mailingList = boys[0].Subscribers; for (int i = 1; i < boys.Count; i++) { if (boys[i].Subscribers != null) { mailingList = boys[i].Subscribers.Intersect(mailingList); } } // Generate messages: debugMessage.AppendLine("<div style='font-size:11px'>"); string macrosBirthdayBoysRuRu = string.Empty; foreach (BirthdayBoy boy in boys) { DateTime birthday = new DateTime(DateTime.Now.Year, boy.Birthday.Month, boy.Birthday.Day); // Birthday in this year. string dayOfWeek = Thread.CurrentThread.CurrentCulture.DateTimeFormat.GetDayName(birthday.DayOfWeek).ToLower(); macrosBirthdayBoysRuRu += $"{boy.Name} - {(string.IsNullOrEmpty(boy.Val) ? $"{birthday:d MMMM} ({dayOfWeek})" : $"{boy.Val}")}"; debugMessage.Append($"<b>{boy.Name} <a href='mailto:{boy.Email}'>{boy.Email}</a></b>"); if (boys.IndexOf(boy) < boys.Count - 1) { macrosBirthdayBoysRuRu += ",<br/>"; debugMessage.Append("; "); } } debugMessage.AppendLine("<br/>"); // Generate mailing list: List <BirthdayBoy> members = new List <BirthdayBoy>(); foreach (BirthdayBoy boy in mailingList.ToList()) { if (!sent.Contains(boy)) { debugMessage.AppendLine($"{boy.Name}<br/>"); sent.Add(boy); // List to filter. members.Add(boy); // List to send. } } debugMessage.AppendLine("<br/>"); // Sending: if (!debug) { SendMessage(from, members, properties.Keys[XmlData.MAIL_SUBJECT][XmlData.VAL], properties.Keys[XmlData.MAIL_MESSAGE][XmlData.VAL] .Replace(MACROS_BIRTHDAY_BOYS_RU_RU, macrosBirthdayBoysRuRu) .Replace(MACROS_RANDOM_HEX_COLOR, GenerateRandomHexColor())); } else if (members.Any(m => m.Email == from)) { SendMessage(from, new List <BirthdayBoy> { new BirthdayBoy { Email = from } }, properties.Keys[XmlData.MAIL_SUBJECT][XmlData.VAL], properties.Keys[XmlData.MAIL_MESSAGE][XmlData.VAL] .Replace(MACROS_BIRTHDAY_BOYS_RU_RU, macrosBirthdayBoysRuRu) .Replace(MACROS_RANDOM_HEX_COLOR, GenerateRandomHexColor())); } }