PendingEmails bearbeited
This commit is contained in:
parent
1d7a67c365
commit
0d1b19bd31
@ -1,10 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="DefaultSender" value="stoyan.zlatev@xylem.com"/>
|
||||
<add key="LogFolder" value="C:\Temp\PendingEmails"/>
|
||||
<add key="Sender" value="stoyan.zlatev@xylem.com" />
|
||||
<add key="LogFolder" value="C:\Users\SZLATEV\Desktop" />
|
||||
<add key="Interval" value="300000" />
|
||||
<add key="SMTPHost" value="smtp.xylem.com" />
|
||||
<add key="SMTPPort" value="587" />
|
||||
<add key="MSSQLConnectionString" value="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=ServiceParingfile; Password=ServiceParingfile;" />
|
||||
<add key="ExcludeRecipients" value="bernd.raade@xylem.com" />
|
||||
</appSettings>
|
||||
<connectionStrings>
|
||||
<add name="Auftrag" connectionString="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=ServiceParingfile; Password=ServiceParingfile;"/>
|
||||
</connectionStrings>
|
||||
</configuration>
|
||||
138
Common/PendingEmails/AppSettings.cs
Normal file
138
Common/PendingEmails/AppSettings.cs
Normal file
@ -0,0 +1,138 @@
|
||||
namespace PendingEmails
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
public class AppSettings
|
||||
{
|
||||
public static string LogFolder { get; private set; }
|
||||
|
||||
public static string MSSQLConnectionString { get; private set; }
|
||||
|
||||
public static string Sender { get; private set; }
|
||||
|
||||
public static string ExcludeRecipients { get; private set; }
|
||||
|
||||
public static string SMTPHost { get; private set; }
|
||||
|
||||
public static int SMTPPort { get; private set; }
|
||||
|
||||
public static int Interval { get; private set; }
|
||||
|
||||
public static bool TryLoadExeConfiguration(out ICollection<string> errors)
|
||||
{
|
||||
errors = new HashSet<string>();
|
||||
|
||||
var exeFileInfo = new FileInfo(typeof(Program).Assembly.Location);
|
||||
var settings = ConfigurationManager
|
||||
.OpenExeConfiguration(exeFileInfo.FullName)
|
||||
?.AppSettings
|
||||
?.Settings;
|
||||
var loaded = true;
|
||||
|
||||
if (settings is null)
|
||||
{
|
||||
errors.Add($"{exeFileInfo.Name} nicht gefunden.");
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var keys = settings.AllKeys;
|
||||
|
||||
LogFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||
|
||||
if (!keys.Any(x => x == nameof(LogFolder)))
|
||||
{
|
||||
errors.Add($"{nameof(LogFolder)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFolder = settings[nameof(LogFolder)]?.Value;
|
||||
}
|
||||
|
||||
if (!keys.Any(x => x == nameof(MSSQLConnectionString)))
|
||||
{
|
||||
errors.Add($"{nameof(MSSQLConnectionString)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSSQLConnectionString = settings[nameof(MSSQLConnectionString)]?.Value;
|
||||
}
|
||||
|
||||
if (!keys.Any(x => x == nameof(Sender)))
|
||||
{
|
||||
errors.Add($"{nameof(Sender)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Sender = settings[nameof(Sender)]?.Value;
|
||||
}
|
||||
|
||||
if (!keys.Any(x => x == nameof(ExcludeRecipients)))
|
||||
{
|
||||
errors.Add($"{nameof(ExcludeRecipients)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExcludeRecipients = settings[nameof(ExcludeRecipients)]?.Value;
|
||||
}
|
||||
|
||||
if (!keys.Any(x => x == nameof(SMTPHost)))
|
||||
{
|
||||
errors.Add($"{nameof(SMTPHost)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SMTPHost = settings[nameof(SMTPHost)]?.Value;
|
||||
}
|
||||
|
||||
if (!keys.Any(x => x == nameof(SMTPPort)))
|
||||
{
|
||||
errors.Add($"{nameof(SMTPPort)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
else if (!int.TryParse($"{settings[nameof(SMTPPort)]?.Value}", out var smtpPort))
|
||||
{
|
||||
errors.Add($"{nameof(SMTPPort)} ist ungültig.");
|
||||
|
||||
loaded = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SMTPPort = smtpPort;
|
||||
}
|
||||
|
||||
Interval = 600_000;
|
||||
|
||||
if (!keys.Any(x => x == nameof(Interval)))
|
||||
{
|
||||
errors.Add($"{nameof(Interval)} nicht definiert in die {exeFileInfo.Name}.");
|
||||
}
|
||||
else if (!int.TryParse($"{settings[nameof(Interval)]?.Value}", out var interval))
|
||||
{
|
||||
errors.Add($"{nameof(Interval)} ist ungültig.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Interval = interval;
|
||||
}
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Common/PendingEmails/Message.cs
Normal file
32
Common/PendingEmails/Message.cs
Normal file
@ -0,0 +1,32 @@
|
||||
namespace PendingEmails
|
||||
{
|
||||
public static partial class Program
|
||||
{
|
||||
public class Message
|
||||
{
|
||||
public Message(int messageId, string sender, string subject, string body, string recipients, string recipientsCC)
|
||||
{
|
||||
this.Id = messageId;
|
||||
this.Sender = sender;
|
||||
this.Subject = subject;
|
||||
this.Body = body;
|
||||
this.Recipients = recipients;
|
||||
this.RecipientsCC = recipientsCC;
|
||||
}
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Sender { get; set; }
|
||||
|
||||
public string Subject { get; set; }
|
||||
|
||||
public string Body { get; set; }
|
||||
|
||||
public string Recipients { get; set; }
|
||||
|
||||
public string RecipientsCC { get; set; }
|
||||
|
||||
public bool IsValid => !string.IsNullOrWhiteSpace(this.Recipients);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,6 +37,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoWarn>IDE0003;IDE0049;</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -69,10 +70,18 @@
|
||||
<PropertyGroup>
|
||||
<NoWin32Manifest>true</NoWin32Manifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>sensus.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@ -80,6 +89,8 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AppSettings.cs" />
|
||||
<Compile Include="Message.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
@ -93,5 +104,8 @@
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="sensus.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@ -1,273 +1,269 @@
|
||||
namespace PendingEmails
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
|
||||
using SystemTimersTimer = System.Timers.Timer;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
private static readonly SystemTimersTimer timer = new SystemTimersTimer();
|
||||
|
||||
private static void Main()
|
||||
{
|
||||
Console.WriteLine("Pending emails ....");
|
||||
try
|
||||
{
|
||||
timer.AutoReset = true;
|
||||
timer.Interval = 600_000;
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Timer_Elapsed(null, null);
|
||||
timer.Start();
|
||||
var awaiter = new ManualResetEventSlim();
|
||||
awaiter.Wait();
|
||||
timer.Stop();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogToFile(e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Ready
|
||||
{
|
||||
public string Source { get; set; }
|
||||
|
||||
public string Subject { get; set; }
|
||||
|
||||
public string Body { get; set; }
|
||||
}
|
||||
|
||||
private static void Timer_Elapsed(Object _, ElapsedEventArgs _1)
|
||||
{
|
||||
LogToFile($"loading pending emails");
|
||||
|
||||
var connectionString = ConfigurationManager.ConnectionStrings["Auftrag"].ConnectionString;
|
||||
|
||||
using (var connection = new SqlConnection(connectionString))
|
||||
{
|
||||
connection.FireInfoMessageEventOnUserErrors = true;
|
||||
connection.InfoMessage += (_2, args) => LogToFile(args.Message);
|
||||
connection.Open();
|
||||
|
||||
var ready = new List<Ready>();
|
||||
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandTimeout = 60000;
|
||||
command.CommandText = @"
|
||||
INSERT INTO Messages
|
||||
( Source
|
||||
, InDate
|
||||
, StationNr
|
||||
, PCName
|
||||
, IPAddress
|
||||
, Trace
|
||||
, Sender
|
||||
, Subject
|
||||
, Body
|
||||
, Recipients
|
||||
, CC
|
||||
, State)
|
||||
SELECT ag.Fertigungsauftrag
|
||||
, CURRENT_TIMESTAMP
|
||||
, ag.Pruefstation
|
||||
, @@SERVERNAME
|
||||
, @@SERVICENAME
|
||||
, 'Xylem.Common.Service.PendingMails'
|
||||
, 'noreplay@xylem.com'
|
||||
, ISNULL(ag.Kundenort, 'Kundenort') + ' - ' + CAST(ag.Auftrag AS VARCHAR(15)) + '/' + CAST(ag.Position AS VARCHAR(10))
|
||||
+ ' erfolgreich geprüft - bitte Garantiescheine drucken und bereitlegen!'
|
||||
, 'Auftrag: ' + CAST(ag.Auftrag AS VARCHAR(15)) + '/' + CAST(ag.Position AS VARCHAR(10)) + CHAR(10)
+ 'FertigungsauftragNr: ' + CAST(ISNULL(ag.Fertigungsauftrag, 0) AS VARCHAR(15)) + CHAR(10)
|
||||
+ CHAR(10)
+ CAST(ISNULL(ag.Menge, 0) AS VARCHAR(10)) + ' Stück ' + ag.Bezeichnung + CHAR(10)
+ 'wurde an der Prüfstation: ' + CAST(ISNULL(ag.Pruefstation, 0) AS VARCHAR(5)) + CHAR(10)
+ 'am ' + CONVERT(VARCHAR(10), ag.Pruefdatum, 105) + ' um ' + CONVERT(VARCHAR(5), ag.Pruefdatum, 108) + ' Uhr' + CHAR(10)
+ 'von ' + ag.Mitarbaiter + ' vollständig geprüft.' + CHAR(10)
|
||||
+ CHAR(10)
+ 'Seriennummern: ' + CAST(ag.SerienNrVon AS VARCHAR(15)) + ' - ' + CAST(ag.SerienNrBis AS VARCHAR(15)) + '' + CHAR(10)
|
||||
+ CHAR(10)
|
||||
+ ag.Merkmal + CHAR(10)
|
||||
, 'uwe.kubon@xylem.com'
|
||||
, 'stoyan.zlatev@xylem.com'
|
||||
, 'Automatische fertigmeldung für garantiescheine.'
|
||||
FROM AlleGepruefteAuftraegeMitGarantieAusLetzte24Hours AS ag
|
||||
LEFT JOIN Messages AS msg
|
||||
ON ag.Fertigungsauftrag LIKE msg.Source
|
||||
WHERE msg.Id IS NULL";
|
||||
|
||||
LogToFile($"Inserted: {command.ExecuteNonQuery()}");
|
||||
}
|
||||
|
||||
var updated = new Dictionary<int, string>();
|
||||
var countAll = 0;
|
||||
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = @"
|
||||
SELECT [Sender]
|
||||
, [Subject]
|
||||
, [Body]
|
||||
, [Recipients]
|
||||
, [CC]
|
||||
, [Id]
|
||||
FROM [Messages]
|
||||
WHERE [OutDate] IS NULL
|
||||
ORDER BY [InDate] DESC";
|
||||
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var messageId = reader.GetValue<Int32>(5);
|
||||
|
||||
try
|
||||
{
|
||||
var email = new MailMessage();
|
||||
var from = ConfigurationManager.AppSettings["DefaultSender"];
|
||||
email.From = new MailAddress(from);
|
||||
email.Subject = $"{reader.GetValue<String>(1)}";
|
||||
email.Body = $"{reader.GetValue<String>(2)}";
|
||||
|
||||
$"{reader.GetValue<String>(3)}"
|
||||
.Split(new[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => new MailAddress(x))
|
||||
.ToList()
|
||||
.ForEach(email.To.Add);
|
||||
|
||||
$"{reader.GetValue<String>(4)}"
|
||||
.Split(new[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => new MailAddress(x))
|
||||
.ToList()
|
||||
.ForEach(email.CC.Add);
|
||||
|
||||
if (SendEmail(email))
|
||||
{
|
||||
updated[messageId] = "Sent";
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogToFile(e);
|
||||
|
||||
updated[messageId] = e.ToString();
|
||||
}
|
||||
|
||||
countAll++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var updatedCount = updated.Count;
|
||||
|
||||
if (updatedCount > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
LogToFile($"updating: {string.Join(", ", updated)}");
|
||||
|
||||
foreach (var kvp in updated)
|
||||
{
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = $@"
|
||||
UPDATE [Messages]
|
||||
SET [OutDate] = GETDATE()
|
||||
, [State] = ISNULL([State], '') + ISNULL(@{nameof(kvp.Value)}, '')
|
||||
WHERE [Id] = @{nameof(kvp.Key)}";
|
||||
command.Parameters.Add(new SqlParameter(nameof(kvp.Key), kvp.Key));
|
||||
command.Parameters.Add(new SqlParameter(nameof(kvp.Value), kvp.Value));
|
||||
command.ExecuteNonQuery();
|
||||
command.Parameters.Clear();
|
||||
}
|
||||
|
||||
updatedCount++;
|
||||
}
|
||||
|
||||
Console.WriteLine($"{updatedCount}/{countAll} email{(updatedCount == 1 ? null : "s")} sent.");
|
||||
LogToFile($"{updatedCount}/{countAll} emails sent.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogToFile(e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogToFile($"there are no pending emails to send");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean SendEmail(MailMessage email)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var smtpClient = new SmtpClient("smtp.xylem.com", 587))
|
||||
{
|
||||
smtpClient.UseDefaultCredentials = true;
|
||||
smtpClient.Send(email);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogToFile(e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void LogToFile(Object e)
|
||||
=> File.AppendAllText(GetOrCreateFile(), $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {e}{Environment.NewLine}");
|
||||
|
||||
private static String GetOrCreateFile()
|
||||
{
|
||||
var logFolder = ConfigurationManager.AppSettings["LogFolder"];
|
||||
var logPath = Directory.CreateDirectory(logFolder).FullName;
|
||||
|
||||
return Path.Combine(logPath, $"{DateTime.Now:yyyy-MM-dd}.txt");
|
||||
}
|
||||
|
||||
private static T GetValue<T>(this SqlDataReader sqlDataReader, Int32 index, T defaultValue = default(T))
|
||||
{
|
||||
var value = defaultValue;
|
||||
|
||||
if (0 <= index && index < sqlDataReader.FieldCount && !sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
var sqlValue = sqlDataReader.GetValue(index);
|
||||
var type = Nullable.GetUnderlyingType(typeof(T));
|
||||
|
||||
if (type is null)
|
||||
{
|
||||
type = typeof(T);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sqlValue = Convert.ChangeType(sqlValue, type);
|
||||
|
||||
if (sqlValue is T expectedValue)
|
||||
{
|
||||
value = expectedValue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogToFile(e);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace PendingEmails
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Threading;
|
||||
|
||||
public static partial class Program
|
||||
{
|
||||
private static void Main()
|
||||
{
|
||||
try
|
||||
{
|
||||
var awaiter = new ManualResetEventSlim();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!AppSettings.TryLoadExeConfiguration(out var errors))
|
||||
{
|
||||
WriteLine(new string('=', 50));
|
||||
|
||||
foreach (var error in errors)
|
||||
{
|
||||
WriteLine(error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine(new string('=', 50));
|
||||
|
||||
using (var connection = new SqlConnection(AppSettings.MSSQLConnectionString))
|
||||
{
|
||||
OpenConnection(connection);
|
||||
|
||||
FindWarantyEmails(connection);
|
||||
var messages = FindPendingEmails(connection);
|
||||
|
||||
if (messages.Count <= 0)
|
||||
{
|
||||
WriteLine($"Keine neue nachrichten gefunden.");
|
||||
}
|
||||
|
||||
var invalidMessages = messages.Where(x => !x.IsValid).ToList();
|
||||
|
||||
if (invalidMessages.Count > 0)
|
||||
{
|
||||
WriteLine($"{invalidMessages.Count} von {messages.Count} ungültige nachrichten gefunden.");
|
||||
var rowsAffected = SetOutDate(connection, invalidMessages.Select(x => x.Id));
|
||||
WriteLine($"{rowsAffected} von {invalidMessages.Count} wurden als gesended markiert.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"Keine neue ungültige nachrichten gefunden.");
|
||||
}
|
||||
|
||||
var validMessages = messages
|
||||
.Where(x => x.IsValid)
|
||||
.ToList();
|
||||
|
||||
if (validMessages.Count > 0)
|
||||
{
|
||||
WriteLine($"{validMessages.Count} von {messages.Count} gültige nachrichten gefunden.");
|
||||
SendEmails(connection, validMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
awaiter.Wait(AppSettings.Interval);
|
||||
awaiter.Reset();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void OpenConnection(SqlConnection connection)
|
||||
{
|
||||
connection.FireInfoMessageEventOnUserErrors = true;
|
||||
connection.InfoMessage += (_, args) => WriteLine(args.Message);
|
||||
connection.Open();
|
||||
}
|
||||
|
||||
private static void SendEmails(SqlConnection connection, List<Message> messages)
|
||||
{
|
||||
var sentEmails = new List<int>();
|
||||
var excludedRecipients = AppSettings
|
||||
.ExcludeRecipients
|
||||
.ToEmailList();
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
try
|
||||
{
|
||||
var recipients = message
|
||||
.Recipients
|
||||
.ToEmailList()
|
||||
.Except(excludedRecipients)
|
||||
.ToList();
|
||||
|
||||
if (recipients.Count <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var recipientsCC = message
|
||||
.RecipientsCC
|
||||
.ToEmailList()
|
||||
.Except(excludedRecipients)
|
||||
.ToList();
|
||||
|
||||
var emailMessage = new MailMessage
|
||||
{
|
||||
From = new MailAddress(AppSettings.Sender),
|
||||
Subject = message.Subject,
|
||||
Body = message.Body
|
||||
};
|
||||
|
||||
recipients.ForEach(emailMessage.To.Add);
|
||||
recipientsCC.ForEach(emailMessage.CC.Add);
|
||||
|
||||
using (var smtpClient = new SmtpClient(AppSettings.SMTPHost, AppSettings.SMTPPort))
|
||||
{
|
||||
smtpClient.UseDefaultCredentials = true;
|
||||
smtpClient.Send(emailMessage);
|
||||
}
|
||||
|
||||
sentEmails.Add(message.Id);
|
||||
WriteLine($"Nachricht: {message.Id} wurde gesendet.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (sentEmails.Count > 0)
|
||||
{
|
||||
WriteLine($"Gesendet {sentEmails.Count} von {messages.Count}");
|
||||
var rowsAffected = SetOutDate(connection, sentEmails);
|
||||
WriteLine($"{rowsAffected} von {messages.Count} wurden als gesended markiert.");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine($"Keine nachrichten gesendet.");
|
||||
}
|
||||
}
|
||||
|
||||
private static int SetOutDate(SqlConnection connection, IEnumerable<int> messageIds)
|
||||
{
|
||||
var rowsAffected = default(int);
|
||||
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = $@"
|
||||
UPDATE Messages
|
||||
SET OutDate = GETDATE()
|
||||
WHERE Id IN ({string.Join(", ", messageIds)})";
|
||||
rowsAffected = command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
return rowsAffected;
|
||||
}
|
||||
|
||||
private static List<Message> FindPendingEmails(SqlConnection connection)
|
||||
{
|
||||
var messages = new List<Message>();
|
||||
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandText = @"
|
||||
SELECT Id
|
||||
, Sender
|
||||
, Subject
|
||||
, Body
|
||||
, Recipients
|
||||
, CC
|
||||
FROM Messages
|
||||
WHERE OutDate IS NULL
|
||||
ORDER BY InDate DESC";
|
||||
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var messageId = reader.GetValue<int>(0);
|
||||
var sender = reader.GetValue<string>(1);
|
||||
var subject = reader.GetValue<string>(2);
|
||||
var body = reader.GetValue<string>(3);
|
||||
var recipients = reader.GetValue<string>(4);
|
||||
var recipientsCC = reader.GetValue<string>(5);
|
||||
|
||||
messages.Add(new Message(messageId, sender, subject, body, recipients, recipientsCC));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
private static void FindWarantyEmails(SqlConnection connection)
|
||||
{
|
||||
using (var command = connection.CreateCommand())
|
||||
{
|
||||
command.CommandTimeout = 60000;
|
||||
command.CommandType = CommandType.StoredProcedure;
|
||||
command.CommandText = @"SP_EMAILS_FUER_GARANTIESCHEINE_LADEN";
|
||||
|
||||
WriteLine($"E-Mails für Garantiescheine gefunden: {command.ExecuteNonQuery()}");
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteLine(object e)
|
||||
{
|
||||
var logFolder = AppSettings.LogFolder;
|
||||
var logPath = Directory.CreateDirectory(logFolder).FullName;
|
||||
var logFile = Path.Combine(logPath, $"{DateTime.Now:yyyy-MM-dd}.txt");
|
||||
var message = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {e}";
|
||||
|
||||
File.AppendAllText(logFile, message);
|
||||
Console.WriteLine(message.Trim());
|
||||
}
|
||||
|
||||
private static T GetValue<T>(this SqlDataReader sqlDataReader, int index, T defaultValue = default(T))
|
||||
{
|
||||
var value = defaultValue;
|
||||
|
||||
if (0 <= index && index < sqlDataReader.FieldCount && !sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
var sqlValue = sqlDataReader.GetValue(index);
|
||||
var type = Nullable.GetUnderlyingType(typeof(T));
|
||||
|
||||
if (type is null)
|
||||
{
|
||||
type = typeof(T);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sqlValue = Convert.ChangeType(sqlValue, type);
|
||||
|
||||
if (sqlValue is T expectedValue)
|
||||
{
|
||||
value = expectedValue;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static List<string> ToEmailList(this string value)
|
||||
=> value
|
||||
?.ToLower()
|
||||
?.Split(new[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
?.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
?.ToList()
|
||||
?? new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Common/PendingEmails/sensus.ico
Normal file
BIN
Common/PendingEmails/sensus.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Loading…
Reference in New Issue
Block a user