/// <summary> /// send an email message with a summary of all warnings in the TestOpportunityStatus table since the last time the email was sent /// NOTE: Currently have it set not to get the Details table. To include the details table in the emails change the parameter to "true" in GetWarningsSummary, /// and uncomment the lines regarding the `detailsTable` variable. /// </summary> public static void SendWarningSummaryEmail(DateTime startDate) { string tdsQCConnectionString = ServiceLocator.Resolve <ISystemConfigurationManager>().GetConfigSettingsValue(clientName, "TDSQCConnectionString"); //getting the tables from QC_ValidationExceptions table. The first table is a summary, the second is a detailed report of all warnings. DataSet ds = TDSQC.GetWarningsSummary(startDate, 100, false, serviceName, tdsQCConnectionString); DataTable summaryTable = ds.Tables["Summary"].Copy(); //get the list of all test IDs that have warnings, so we can separate them out and report them each in their own table in the email List <String> testIDs = new List <string>(); foreach (DataRow row in summaryTable.Rows) { if (!testIDs.Contains(row["TestID"].ToString())) { testIDs.Add(row["TestID"].ToString()); } } //DataTable detailsTable = ds.Tables["Details"].Copy(); StringBuilder sb = new StringBuilder(); sb.Append(@"<html><body style=""font-family:verdana;font-size:12px;"">"); sb.Append(@"<div style=""font-weight:bolder;font-size:14px;color:darkRed;"">"); sb.Append("The following test opportunities were successfully processed with warnings on " + DateTime.Now.ToShortDateString()); sb.Append("</div><br>"); if (testIDs.Count == 0) { sb.Append(@"<div style=""font-weight:bolder;font-size:14px;color:darkRed;"">"); sb.Append("No warnings found since " + startDate.ToShortDateString()); sb.Append("</div><br>"); } else // else isn't really needed... { //now add a table for each test ID foreach (string id in testIDs) { DataTable currentSummaryTable = summaryTable.Clone(); foreach (DataRow row in summaryTable.Select("TestID = '" + id + "'")) { currentSummaryTable.ImportRow(row); } currentSummaryTable.Columns.Remove("TestID"); sb.Append(CreateHTMLTable("Summary for Test ID '" + id + "':", startDate, false, currentSummaryTable)); //DataTable currentDetailsTable = detailsTable.Clone(); //foreach (DataRow row in detailsTable.Select("TestID = '" + id + "'")) // currentDetailsTable.ImportRow(row); //currentDetailsTable.Columns.Remove("TestID"); //sb.Append(CreateHTMLTable("Details for Test ID '" + id + "':", startDate, true, currentDetailsTable)); } } sb.Append("</body></html>"); using (MailMessage mailMessage = new MailMessage()) { mailMessage.To.Add(warningTos); if (!String.IsNullOrEmpty(warningCc)) { mailMessage.CC.Add(warningCc); } //Subject = (<Environment>) <Message Type> - <Client> <System> - <Instance Name, if applicable> <- configurable info, if any> mailMessage.Subject = "(" + environment + ") Information - " + clientName; mailMessage.Subject += " QA System"; if (serviceName.Length > 0) { mailMessage.Subject += " - " + serviceName; } mailMessage.Subject += " - QA System Warnings Summary For " + DateTime.Now.ToShortDateString(); mailMessage.Body = sb.ToString(); mailMessage.BodyEncoding = Encoding.ASCII; mailMessage.IsBodyHtml = true; SmtpClient smtpClient = new SmtpClient(); smtpClient.Send(mailMessage); } }
/// <summary> /// Generates an email message for validation exceptions that displays all /// exceptions that occurred during processing in a formatted HTML table. /// The fileName allows us to uniquely identify a file that was processed by QA; /// however, we may process a file more than once. So we'll also use the datetime /// that QA processing started on this file in order to exclude errors that may /// have occurred in a previous run. /// </summary> /// <param name="headerMessage">This will be the header of the email; should be a short description</param> /// <param name="tr">The TestResult instance that's being processed, if it exists. /// It's possible that errors may have occurred before it could be created.</param> /// <param name="fileName">The name of the file being processed by QA.</param> /// <param name="startDateTime">Should be the datetime that processing started for this file.</param> /// <param name="connectionString">the TDS connection string</param> /// <param name="minimumSeverity">min Severity to include in the email. Warning, Information, /// and Fatal are supported. Unknown/Null Severity records are always included.</param> /// <returns>A string containing the formatted HTML email, or NULL if there are no records to send.</returns> private static string GetValidationEmailContent(string headerMessage, TestResult tr, long fileId, DateTime startDateTime, String connectionString, Severity minimumSeverity) { // Get all exceptions that were logged to the QC_ValidationExceptions table. This includes // validation biz rule failures as well as general exceptions. It may also include warnings and possibly // informational records depending on the minimumSeverity. DataTable valExceptions = TDSQC.GetQC_ValidationExceptions(fileId, startDateTime, (int)minimumSeverity, connectionString); // if there are no records, do not generate the email. Just return null. if (valExceptions.Rows.Count == 0) { return(null); } // there are records to email. Build the email and return the formatted message. StringBuilder formattedExceptions = new StringBuilder(); formattedExceptions.Append(@"<html><body style=""font-family:verdana;font-size:12px;"">"); // if there was a message passed in, put that at the top. if (!String.IsNullOrEmpty(headerMessage)) { formattedExceptions.Append(@"<div style=""font-weight:bolder;font-size:14px;color:darkRed;"">"); formattedExceptions.Append(headerMessage); formattedExceptions.Append("</div><br>"); } // start the table formattedExceptions.Append(@"<table border=""0"" cellpadding=""4"" cellspacing=""1"">"); if (valExceptions.Rows.Count == 0) { formattedExceptions.Append(@"<tr><td style=""font-family:verdana;font-size:12px;"">No validation exceptions logged for fileId '"); formattedExceptions.Append(fileId); formattedExceptions.Append("' starting at "); formattedExceptions.Append(startDateTime.ToString("MM/dd/yyyy hh:mm:ss:fff tt")); formattedExceptions.Append("."); formattedExceptions.Append("</td></tr>"); } else { valExceptions.Columns["_efk_ruleID"].ColumnName = "Rule"; valExceptions.Columns["_efk_Testee"].ColumnName = "StudentID"; valExceptions.Columns["_efk_TestID"].ColumnName = "Test"; // header row formattedExceptions.Append("<tr>"); foreach (DataColumn col in valExceptions.Columns) { formattedExceptions.Append(@"<td style=""font-family:verdana;font-size:12px;font-weight:bolder;background-color:gainsboro;"">"); formattedExceptions.Append(col.ColumnName); formattedExceptions.Append("</td>"); } formattedExceptions.Append("</tr>"); // data foreach (DataRow valException in valExceptions.Rows) { formattedExceptions.Append("<tr>"); int i = 0; foreach (DataColumn col in valExceptions.Columns) { if (i % 2 == 0) { formattedExceptions.Append(@"<td style=""font-family:verdana;font-size:12px;"">"); } else { formattedExceptions.Append(@"<td style=""font-family:verdana;font-size:12px;background-color:lightYellow;"">"); } formattedExceptions.Append(valException[col]); formattedExceptions.Append("</td>"); i++; } formattedExceptions.Append("</tr>"); } } formattedExceptions.Append(@"<tr><td style=""font-family:verdana;font-size:10px;padding-top:10px;"" colspan="""); formattedExceptions.Append(valExceptions.Columns.Count); formattedExceptions.Append(@"""><i>Severity: Unknown = 0/(blank), Information = 10, Warning = 100, Fatal = 200</i></td></tr>"); // close out the message formattedExceptions.Append("</table></body></html>"); return(formattedExceptions.ToString()); }