using System; using System.Threading; using CSLA.Security; using Chilkat; namespace GZTW.AyaNova.BLL { /// /// Process client notification list and /// deliver appropriately /// public class GenProcessClientNotifications { private GenProcessClientNotifications() { // // TODO: Add constructor logic here // } /// /// Compile a list of all pending Client notifications and deliver them /// public static void DeliverNotifications() { //case 1904 if (!AyaBizUtils.GlobalSettings.UseNotification) return; //case 1904 moved up here for early exit if nothing to process to avoid //probing possibly not set up smtp server ClientNotificationList nl = ClientNotificationList.GetList(); if (nl.Count == 0) return; NotifyDeliveryLog.LogSMTPDeliveryMessage("Found " + nl.Count.ToString() + " Client notification messages awaiting delivery"); // Create a mailman object for sending email. MailMan mailman = new MailMan(); mailman.UnlockComponent("AYANVA.CB1052023_c9TZbuFYBd7f"); // Set the SMTP variables mailman.SmtpHost = GZTW.AyaNova.BLL.AyaBizUtils.GlobalSettings.NotifySMTPHostPortionOnly; mailman.SmtpPort = GZTW.AyaNova.BLL.AyaBizUtils.GlobalSettings.NotifySMTPPort; //case 1136 if (GZTW.AyaNova.BLL.AyaBizUtils.GlobalSettings.NotifySMTPUseSSL) mailman.SmtpSsl = true; if (GZTW.AyaNova.BLL.AyaBizUtils.GlobalSettings.NotifySMTPUseTLS) mailman.StartTLS = true; mailman.SmtpUsername = GZTW.AyaNova.BLL.AyaBizUtils.GlobalSettings.NotifySMTPAccount; mailman.SmtpPassword = GZTW.AyaNova.BLL.AyaBizUtils.GlobalSettings.NotifySMTPPassword; //case 1382 //if can't use smtp server then log and conditionally abort //## NOTE: this operation sets up what tls level is being used etc if (!mailman.SmtpNoop()) { //case 1608 NotifyDeliveryLog.LogSMTPConnectFailure("Code:" + mailman.LastSmtpStatus.ToString() + "\r\n" + mailman.LastErrorText); //If retry then don't proceed or notifications will be deleted if (AyaBizUtils.GlobalSettings.SMTPRetry) return; } //case 3808 prevent dupes in single delivery tranche //If this doesn't prevent it, it means it's duping in separate runs of this method // so would need an external static location to store a limited number of dupes in some kind of //queue, probably in ayabizutils with everything else System.Collections.Generic.List Hashes = new System.Collections.Generic.List(); foreach (ClientNotificationList.ClientNotificationListInfo info in nl) { string NotifySummary = string.Empty; try { //reload email from stored mime ClientNotifyEvent n = ClientNotifyEvent.GetItem(info.mID); string[] sMessageFields = n.GetContentAsString.Split('|'); int nFieldCount = sMessageFields.GetLength(0); if (nFieldCount < 5 || sMessageFields[0] != "CLIENTNOTIFYEVENT") { NotifyDeliveryLog.LogClientDelivery(n.ClientID, false, "Invalid event data: " + n.GetContentAsString); ClientNotifyEvent.DeleteItem(n.ID); continue; } Chilkat.Email email = new Chilkat.Email(); //email.SetFromMimeText(n.GetContentAsString); email.Mailer = AyaBizUtils.ReplaceBareLineFeeds("AyaNova service management software licensed to " + AyaBizUtils.REGTO); email.Body = AyaBizUtils.ReplaceBareLineFeeds(sMessageFields[1]);//case 4180 email.Subject = AyaBizUtils.ReplaceBareLineFeeds(sMessageFields[2]); //case 1601 string ToAddress = AyaBizUtils.ReplaceBareLineFeeds(sMessageFields[3]); //case 3808 NotifySummary = ToAddress + "|" + email.Subject; if (nFieldCount > 4) { NotifySummary += "|woid:" + sMessageFields[4];//case 3829 } if (nFieldCount > 5) { NotifySummary += "|woid:" + sMessageFields[5]; } NotifyDeliveryLog.LogSMTPDeliveryMessage("Preparing to send client notification: " + NotifySummary); if (ToAddress.Contains(";")) ToAddress = ToAddress.Replace(";", ","); if (ToAddress.Contains(",")) email.AddMultipleTo(ToAddress); else email.AddTo("", ToAddress); email.From = AyaBizUtils.ReplaceBareLineFeeds(sMessageFields[4]); if (nFieldCount > 5) { string sWOID = sMessageFields[5]; if (!string.IsNullOrEmpty(sWOID)) { NotifySummary += "|woid:" + sWOID;//case 3808 Guid woid = new Guid(sWOID); //attach a workorder Report r = Report.GetItem(new Guid(sMessageFields[6])); object o = null; if (r.ReportKey == "WorkorderServiceList") o = WorkorderServiceList.GetListForSingleItem(woid); else if (r.ReportKey == "WorkorderServiceDetailed") o = WorkorderServiceDetailedReportData.GetItem(woid); else if (r.ReportKey == "WorkorderQuoteList") o = WorkorderQuoteList.GetListForSingleItem(woid); else if (r.ReportKey == "WorkorderQuoteDetailed") o = WorkorderQuoteDetailedReportData.GetItem(woid); NotifySummary += "|reportkey:" + r.ReportKey + "|reportid:" + sMessageFields[6];//case 3808 //ms.toarray = byte array from memory stream email.AddDataAttachment(DateTime.Now.ToString("yyyy_MM_dd_HH_mm") + ".pdf", ReportGenerator.GetReportAsPDF(r, o).ToArray()); } } //case 3808 var hash = CheckSum(email.Body + NotifySummary); NotifySummary += "|hash:" + hash; if (!Hashes.Contains(hash)) { Hashes.Add(hash); } else { NotifyDeliveryLog.LogSMTPDeliveryMessage("Skipping duplicate: " + NotifySummary); ClientNotifyEvent.DeleteItem(n.ID); continue; } NotifyDeliveryLog.LogSMTPDeliveryMessage("Delivering: " + NotifySummary); // Send mail. bool success; success = mailman.SendEmail(email); #if(DEBUG) NotifyDeliveryLog.LogSMTPDeliveryMessage("POST TLS version: " + mailman.TlsVersion); #endif if (success) { NotifyDeliveryLog.LogClientDelivery(n.ClientID, true, ""); ClientNotifyEvent.DeleteItem(n.ID); } else { NotifyDeliveryLog.LogClientDelivery(n.ClientID, false, mailman.LastErrorText); //Added this late, I'm thinking if it fails they will get the log and //be able to fix the problem easily but if it stays in the queue there will be no way //for them to delete it //A better way would be to delete after x failed deliveries ClientNotifyEvent.DeleteItem(n.ID); } } catch (Exception ex) { //case 3829 //crack exception if necessary while (ex.InnerException != null) ex = ex.InnerException; //log and then continue if (string.IsNullOrEmpty(NotifySummary)) { NotifySummary = "UNKNOWN MESSAGE"; } NotifyDeliveryLog.LogSMTPDeliveryMessage("ClientNotify Exception during delivery: Full error is:\r\n" + ex.Message + "\r\nMessage: " + NotifySummary); continue; } } } public static string CheckSum(string input) { string hash = string.Empty; using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) { hash = BitConverter.ToString( md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(input)) ).Replace("-", String.Empty); } return hash; } //================================= } }