/// <summary> /// Takes a report and a list of cost centres; it runs the report for each of the cost centres and emails the results to the address(es) /// associated with that cost centre. Used by Account Detail, Income Expense reports and HOSAs. /// </summary> /// <remarks>If ACostCentreFilter is an SQL clause selecting cost centres, the associated email address is the Primary E-Mail Address of /// every Partner linked to the cost centre. If ACostCentreFilter is "Foreign", the list is every cost centre in the a_email_destination /// table with a File Code of "HOSA".</remarks> /// <param name="FormUtils">The report selection form, to write to the status bar.</param> /// <param name="ReportEngine">FastReport wrapper object.</param> /// <param name="ACalc">The report parameters.</param> /// <param name="ALedgerNumber">The ledger number.</param> /// <param name="ACostCentreFilter">SQL clause to select the list of cost centres to run the report for, or "Foreign" </param> /// <returns>List of status strings that should be shown to the user.</returns> public static List <String> AutoEmailReports(TFrmPetraReportingUtils FormUtils, FastReportsWrapper ReportEngine, TRptCalculator ACalc, Int32 ALedgerNumber, String ACostCentreFilter) { TSmtpSender EmailSender; Int32 SuccessfulCount = 0; var NoEmailAddr = new List <String>(); var FailedAddresses = new List <String>(); var SendReport = new List <String>(); // FastReport will use a temporary folder to store HTML files. // I need to ensure that the CurrectDirectory is somewhere writable: String prevCurrentDir = Directory.GetCurrentDirectory(); //Get a path in the Public Documents folder String newDir = Path.Combine(Environment.GetFolderPath( Environment.SpecialFolder.CommonDocuments), "OpenPetraOrg"); //Check it exists, and if not create it if (!Directory.Exists(newDir)) { try { Directory.CreateDirectory(newDir); } catch (Exception ex) { //Could not create the path so return useful debugging information: SendReport.Add(Catalog.GetString("Error - could not create directory: ")); SendReport.Add(newDir); SendReport.Add(ex.Message); return(SendReport); } } Directory.SetCurrentDirectory(newDir); // This gets email defaults from the user settings table //TUC_EmailPreferences.LoadEmailDefaults(); try { EmailSender = new TSmtpSender(); EmailSender.SetSender(TUserDefaults.GetStringDefault("SmtpFromAccount"), TUserDefaults.GetStringDefault("SmtpDisplayName")); EmailSender.CcEverythingTo = TUserDefaults.GetStringDefault("SmtpCcTo"); EmailSender.ReplyTo = TUserDefaults.GetStringDefault("SmtpReplyTo"); } catch (ESmtpSenderInitializeException e) { if (e.InnerException != null) { // I'd write the full exception to the log file, but it still gets transferred to the client window status bar and is _really_ ugly. //TLogging.Log("AutoEmailReports: " + e.InnerException.ToString()); TLogging.Log("AutoEmailReports: " + e.InnerException.Message); } SendReport.Add(e.Message); if (e.ErrorClass == TSmtpErrorClassEnum.secClient) { SendReport.Add(Catalog.GetString("Check the Email tab in User Settings >> Preferences.")); } return(SendReport); } // I need to find the email addresses for the linked partners I'm sending to. DataTable LinkedPartners = null; LinkedPartners = TRemote.MFinance.Setup.WebConnectors.GetLinkedPartners(ALedgerNumber, ACostCentreFilter); LinkedPartners.DefaultView.Sort = "CostCentreCode"; String myLedgerName = ""; DataTable CostCentreList = null; if (ACostCentreFilter == "Foreign") { myLedgerName = TRemote.MFinance.Reporting.WebConnectors.GetLedgerName(ALedgerNumber); CostCentreList = TDataCache.TMFinance.GetCacheableFinanceTable(TCacheableFinanceTablesEnum.CostCentreList, ALedgerNumber); } foreach (DataRowView rv in LinkedPartners.DefaultView) { DataRow LinkedPartner = rv.Row; Boolean reportAsAttachment = TUserDefaults.GetBooleanDefault("SmtpSendAsAttachment", true); if (LinkedPartner["EmailAddress"].ToString() != "") { ACalc.AddStringParameter("param_linked_partner_cc", LinkedPartner["CostCentreCode"].ToString()); FormUtils.WriteToStatusBar("Generate " + ReportEngine.FReportName + " Report for " + LinkedPartner["PartnerShortName"]); MemoryStream ReportStream = ReportEngine.ExportToStream(ACalc, reportAsAttachment ? FastReportsWrapper.ReportExportType.Pdf : FastReportsWrapper.ReportExportType.Html); // in OpenSource OpenPetra, we do not have and use the FastReport dlls // if (ReportEngine.FfastReportInstance.ReportInfo.Description == "Empty") // { // continue; // Don't send an empty report // } ReportStream.Position = 0; String EmailBody = ""; if (reportAsAttachment) { EmailBody = TUserDefaults.GetStringDefault("SmtpEmailBody"); EmailSender.AttachFromStream(ReportStream, ReportEngine.FReportName + ".pdf"); } else { StreamReader sr = new StreamReader(ReportStream); EmailBody = sr.ReadToEnd(); } String subjectLine; if (ACostCentreFilter == "Foreign") { String recipientLedgerName = ""; CostCentreList.DefaultView.RowFilter = "a_cost_centre_code_c='" + LinkedPartner["CostCentreCode"].ToString() + "'"; if (CostCentreList.DefaultView.Count > 0) { recipientLedgerName = CostCentreList.DefaultView[0].Row["a_cost_centre_name_c"].ToString(); } subjectLine = "HOSA & RGS from " + myLedgerName + " to " + recipientLedgerName; } else { subjectLine = ReportEngine.FReportName + " Report for " + LinkedPartner["PartnerShortName"]; } Boolean SentOk = EmailSender.SendEmail( LinkedPartner["EmailAddress"].ToString(), subjectLine, EmailBody); if (SentOk) { SuccessfulCount++; } else // Email didn't send for some reason { SendReport.Add(String.Format( Catalog.GetString("Failed to send to {0}. Message returned: \"{1}\"."), LinkedPartner["EmailAddress"], EmailSender.ErrorStatus )); FailedAddresses.Add(" " + LinkedPartner["EmailAddress"]); } } else // No Email Address for this Partner { NoEmailAddr.Add(" " + String.Format("{0:D10}", LinkedPartner["PartnerKey"]) + " " + LinkedPartner["PartnerShortName"]); } } if (SuccessfulCount == 1) { SendReport.Add( String.Format(Catalog.GetString("{0} emailed to {1} partner."), ReportEngine.FReportName, SuccessfulCount)); } else if (SuccessfulCount > 1) { SendReport.Add( String.Format(Catalog.GetString("{0} emailed to {1} partners."), ReportEngine.FReportName, SuccessfulCount)); } else { SendReport.Add(Catalog.GetString( "Error – no cost centre in the report was linked to a Partner with a valid Primary E-mail Address.")); } if (NoEmailAddr.Count > 0) { SendReport.Add(Catalog.GetString("These Partners have no Primary E-mail Address:")); SendReport.AddRange(NoEmailAddr); } if (FailedAddresses.Count > 0) { SendReport.Add(Catalog.GetString("Failed to send email to these addresses:")); SendReport.AddRange(FailedAddresses); } FormUtils.WriteToStatusBar(""); Directory.SetCurrentDirectory(prevCurrentDir); EmailSender.Dispose(); return(SendReport); } // AutoEmailReports
/// <summary> /// send report as email /// </summary> public Boolean SendEmail(string AEmailAddresses, bool AAttachExcelFile, bool AAttachCSVFile, bool AAttachPDF, bool AWrapColumn, out TVerificationResultCollection AVerification) { TSmtpSender EmailSender = null; string EmailBody = ""; AVerification = new TVerificationResultCollection(); try { EmailSender = new TSmtpSender(); List <string> FilesToAttach = new List <string>(); if (AAttachExcelFile) { string ExcelFile = TFileHelper.GetTempFileName( FParameterList.Get("currentReport").ToString(), ".xlsx"); if (ExportToExcelFile(ExcelFile)) { FilesToAttach.Add(ExcelFile); } } if (AAttachCSVFile) { string CSVFile = TFileHelper.GetTempFileName( FParameterList.Get("currentReport").ToString(), ".csv"); if (ExportToCSVFile(CSVFile)) { FilesToAttach.Add(CSVFile); } } if (AAttachPDF) { string PDFFile = TFileHelper.GetTempFileName( FParameterList.Get("currentReport").ToString(), ".pdf"); if (PrintToPDF(PDFFile, AWrapColumn)) { FilesToAttach.Add(PDFFile); } } if (FilesToAttach.Count == 0) { AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), Catalog.GetString("Missing any attachments, not sending the email"), "Missing Attachments", TResultSeverity.Resv_Critical, new System.Guid())); return(false); } try { EmailSender.SetSender(TUserDefaults.GetStringDefault("SmtpFromAccount"), TUserDefaults.GetStringDefault("SmtpDisplayName")); EmailSender.CcEverythingTo = TUserDefaults.GetStringDefault("SmtpCcTo"); EmailSender.ReplyTo = TUserDefaults.GetStringDefault("SmtpReplyTo"); EmailBody = TUserDefaults.GetStringDefault("SmtpEmailBody"); } catch (ESmtpSenderInitializeException e) { AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), String.Format("{0}\n{1}", e.Message, Catalog.GetString("Check the Email tab in User Settings >> Preferences.")), CommonErrorCodes.ERR_MISSINGEMAILCONFIGURATION, TResultSeverity.Resv_Critical, new System.Guid())); if (e.InnerException != null) { TLogging.Log("Email XML Report: " + e.InnerException); } return(false); } if (EmailBody == "") { EmailBody = Catalog.GetString("OpenPetra report attached."); } if (EmailSender.SendEmail( AEmailAddresses, FParameterList.Get("currentReport").ToString(), EmailBody, FilesToAttach.ToArray())) { foreach (string file in FilesToAttach) { File.Delete(file); } return(true); } AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), Catalog.GetString("Problem sending email"), "Server problems", TResultSeverity.Resv_Critical, new System.Guid())); return(false); } // try catch (ESmtpSenderInitializeException e) { AVerification.Add(new TVerificationResult( Catalog.GetString("Sending Email"), e.Message, CommonErrorCodes.ERR_MISSINGEMAILCONFIGURATION, TResultSeverity.Resv_Critical, new System.Guid())); if (e.InnerException != null) { TLogging.Log("Email XML Report: " + e.InnerException); } return(false); } finally { if (EmailSender != null) { EmailSender.Dispose(); } } }
/// <summary> /// Gets called in regular intervals from a Timer in Class TTimedProcessing. /// </summary> /// <param name="ADataBaseObj">Already instatiated DB Access object with opened DB connection.</param> /// <param name="ARunManually">this is true if the process was called manually from the server admin console</param> public static void Process(TDataBase ADataBaseObj, bool ARunManually) { TDBTransaction ReadWriteTransaction; bool NewTransaction; bool LastReminderDateAcquired; DateTime LastReminderDate; DataSet ReminderResultsDS; SSystemDefaultsRow SystemDefaultsDR; PPartnerReminderTable PartnerReminderDT; int ReminderFreqency; TSmtpSender Sender = null; if (TLogging.DebugLevel >= 6) { TLogging.Log("Entering TProcessPartnerReminders.Process..."); } ReadWriteTransaction = ADataBaseObj.GetNewOrExistingTransaction(IsolationLevel.ReadCommitted, out NewTransaction); /* * This whole process must either succeed or fail, therefore the whole thing is in a try-catch. */ try { /* * Obtain date when PartnerReminders last ran. This is stored in a SystemDefault. If it doesn't exist already, * a new SystemDefault with an ancient date is created for us. */ LastReminderDateAcquired = GetLastReminderDate(out LastReminderDate, out SystemDefaultsDR, ReadWriteTransaction); if (!LastReminderDateAcquired) { TLogging.Log( TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Could not send Partner Reminders because Petra couldn't create the required SystemDefault setting for the Last Reminder Date!"); ADataBaseObj.RollbackTransaction(); return; } try { Sender = new TSmtpSender(); } catch (ESmtpSenderInitializeException e) { TLogging.Log( TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": " + e.Message); if (e.InnerException != null) { TLogging.Log(e.InnerException.ToString(), TLoggingType.ToLogfile); } return; } // Retrieve all PartnerReminders we need to process. ReminderResultsDS = GetRemindersToProcess(LastReminderDate, out PartnerReminderDT, ADataBaseObj, ReadWriteTransaction); /* * We now have a Typed DataTable with the PartnerReminders that we need to process. * Iterate through the PartnerReminders, update data, and send an email for each PartnerReminder. */ if (TLogging.DebugLevel >= 6) { TLogging.Log("_---------------------------------_"); TLogging.Log("PartnerReminders data before we start processing all PartnerReminders...."); TLogging.Log(ReminderResultsDS.GetXml().ToString()); } foreach (PPartnerReminderRow PartnerReminderDR in PartnerReminderDT.Rows) { if (TLogging.DebugLevel >= 4) { TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Processing Reminder ID {0} for Partner {1}.", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey)); } ReminderFreqency = (PartnerReminderDR.IsReminderFrequencyNull()) ? 0 : PartnerReminderDR.ReminderFrequency; PartnerReminderDR.BeginEdit(); PartnerReminderDR.LastReminderSent = DateTime.Now.Date; PartnerReminderDR.NextReminderDate = DateTime.Now.Date.AddDays(ReminderFreqency); if (!PartnerReminderDR.IsEventDateNull()) // Reminder has an Event Date { if (PartnerReminderDR.NextReminderDate > PartnerReminderDR.EventDate) { if (TLogging.DebugLevel >= 5) { TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Deactivating Reminder ID {0} for Partner {1} as its Event Date is in the past.", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey)); } PartnerReminderDR.ReminderActive = false; } } if (TLogging.DebugLevel >= 4) { TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Sending email for Reminder ID {0} for Partner {1}.", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey)); } Boolean emailSentOk = false; try { emailSentOk = SendReminderEmail(PartnerReminderDR, ReadWriteTransaction, Sender); } catch (ESmtpSenderInitializeException e) // if an exception was thrown, assume the email didn't go. { TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Reminder ID {0} for Partner {1}: {2}", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey, e.Message)); if (e.InnerException != null) { TLogging.Log(e.InnerException.Message); } } catch (ESmtpSenderSendException e) { TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Reminder ID {0} for Partner {1}: {2}", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey, e.Message)); if (e.InnerException != null) { TLogging.Log(e.InnerException.Message); } } catch (Exception e) { TLogging.Log(e.Message); } if (emailSentOk) { // Accept the edit if (TLogging.DebugLevel >= 4) { TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Reminder ID {0} for Partner {1} accepted by SMTP server.", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey)); } PartnerReminderDR.EndEdit(); } else { // Cancel the edit TLogging.Log(String.Format(TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + ": Reminder ID {0} for Partner {1} REJECTED by SMTP server.", PartnerReminderDR.ReminderId, PartnerReminderDR.PartnerKey)); PartnerReminderDR.CancelEdit(); } } if (TLogging.DebugLevel >= 6) { TLogging.Log("_---------------------------------_"); TLogging.Log("PartnerReminders data after processing all PartnerReminders, before writing it to DB...."); TLogging.Log(PartnerReminderDT.DataSet.GetXml().ToString()); } // Update all the changed PartnerReminder Rows PPartnerReminderAccess.SubmitChanges(PartnerReminderDT, ReadWriteTransaction); if (TLogging.DebugLevel >= 6) { TLogging.Log("_---------------------------------_"); } /* * Update the SystemDefault that keeps track of when Partner Reminders last ran. * (SystemDefaultsDR will point to the row we loaded earlier on, OR the row we added earlier on * if there wasn't already a SystemDefault row.) */ UpdateLastReminderDate(SystemDefaultsDR, ReadWriteTransaction); if (NewTransaction) { ADataBaseObj.CommitTransaction(); } TLogging.LogAtLevel(1, TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + " ran succesfully."); } catch (Exception Exc) { TLogging.Log( TTimedProcessing.StrAutomaticProcessing + StrRemindersProcessing + " encountered an Exception:" + Environment.NewLine + Exc.ToString()); if (NewTransaction) { ADataBaseObj.RollbackTransaction(); } throw; } finally { if (Sender != null) { Sender.Dispose(); } } }