laatzen/Common/PendingEmails/Program.cs
2025-03-06 13:09:40 +01:00

274 lines
11 KiB
C#

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;
}
}
}