DeviationNotificationPlugin.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. using GreenTree.Nachtragsmanagement.Core.Plugins;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Web;
  6. using GreenTree.Nachtragsmanagement.Core.Domain.Misc;
  7. using GreenTree.Nachtragsmanagement.Services.User;
  8. using GreenTree.Nachtragsmanagement.Services.Configuration;
  9. using GreenTree.Nachtragsmanagement.Services.Appendix;
  10. using GreenTree.Nachtragsmanagement.Core.Domain.Appendix;
  11. using System.Net.Mail;
  12. using System.Net;
  13. using System.Globalization;
  14. using GreenTree.Nachtragsmanagement.Services.Deviation;
  15. using GreenTree.Nachtragsmanagement.Core.Domain.Deviation;
  16. using Quartz;
  17. using GreenTree.Nachtragsmanagement.Services.Logging;
  18. namespace GreenTree.Nachtragsmanagement.Web.Implementations
  19. {
  20. public class DeviationNotificationPlugin : INotificationPlugin, IJob
  21. {
  22. #region Services
  23. private readonly IUserService _userService;
  24. private readonly IConfigurationService _configurationService;
  25. private readonly IDeviationService _deviationService;
  26. private readonly IServiceLogger _logger;
  27. #endregion
  28. #region Properties
  29. /// <summary>
  30. /// Id
  31. /// </summary>
  32. public Guid Id
  33. {
  34. get
  35. {
  36. return Guid.Parse("77D662E0-F621-4567-9030-2A106533FE06");
  37. }
  38. }
  39. /// <summary>
  40. /// System name
  41. /// </summary>
  42. public string SystemName
  43. {
  44. get
  45. {
  46. return "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin";
  47. }
  48. }
  49. /// <summary>
  50. /// List of available notification jobs
  51. /// </summary>
  52. public List<NotificationJob> AvailableNotificationJobs
  53. {
  54. get
  55. {
  56. return new List<NotificationJob>
  57. {
  58. new NotificationJob
  59. (
  60. Guid.Parse("144DFF97-4EE4-4B32-967C-C0375D133DCF"),
  61. "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt",
  62. "Eingangsdatum überprüfen",
  63. "Erstellt automatisch Benachrichtigungen für Vertragsabweichungen, die 40 Tagen, bzw. 60 Tagen nach " +
  64. "Einreichung noch keinem Nachtrag zugeordnet sind."
  65. )
  66. };
  67. }
  68. }
  69. /// <summary>
  70. /// Displayed name
  71. /// </summary>
  72. public string Name
  73. {
  74. get
  75. {
  76. return "Vertragsabweichungsbenachrichtigung";
  77. }
  78. }
  79. /// <summary>
  80. /// Further description on how this plugin works
  81. /// </summary>
  82. public string Description
  83. {
  84. get
  85. {
  86. return
  87. "Erstellt automatisch Benachrichtigungen für Vertragsabweichungen, die 40 Tagen (Stufe 1), bzw. 60 Tagen (Stufe 2)" +
  88. "nach Einreichung noch keinem Nachtrag zugeordnet sind.";
  89. }
  90. }
  91. #endregion
  92. /// <summary>
  93. /// Initializes a new instance of the DeviationNotificationPlugin class
  94. /// </summary>
  95. public DeviationNotificationPlugin() { }
  96. /// <summary>
  97. /// Initializes a new instance of the DeviationNotificationPlugin class
  98. /// </summary>
  99. public DeviationNotificationPlugin(
  100. IUserService userService,
  101. IConfigurationService configurationService,
  102. IDeviationService deviationService,
  103. IServiceLogger logger)
  104. {
  105. _userService = userService;
  106. _configurationService = configurationService;
  107. _deviationService = deviationService;
  108. _logger = logger;
  109. }
  110. #region Quartz implmentation
  111. /// <summary>
  112. /// Executes the current job
  113. /// </summary>
  114. /// <param name="context"></param>
  115. public void Execute(IJobExecutionContext context)
  116. {
  117. if (!context.JobDetail.JobDataMap.ContainsKey("MailNotifications"))
  118. return;
  119. var mailNotifications = context.JobDetail.JobDataMap.Get("MailNotifications") as IEnumerable<MailNotification>;
  120. ProcessNotifications(mailNotifications);
  121. }
  122. #endregion
  123. #region Processing
  124. /// <summary>
  125. /// Process all mail notifications registered for that plugin
  126. /// </summary>
  127. /// <param name="mailNotifications">The notifications which shall be generated.</param>
  128. public void ProcessNotifications(IEnumerable<MailNotification> mailNotifications)
  129. {
  130. if (mailNotifications == null || (mailNotifications != null && !mailNotifications.Any())) return;
  131. _logger.Information(
  132. String.Format(
  133. "Starte Verarbeitung Mail-Benachrichtigung in \"{0}\" für \"{1} ...",
  134. SystemName, mailNotifications.First().NotificationJobSystemName));
  135. foreach (var notification in mailNotifications)
  136. {
  137. try
  138. {
  139. switch (notification.NotificationJobSystemName)
  140. {
  141. case "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt":
  142. {
  143. ProcessDeviationReceiptNotification(notification);
  144. }
  145. break;
  146. default:
  147. continue;
  148. }
  149. }
  150. catch (Exception ex)
  151. {
  152. _logger.Error(
  153. String.Format(
  154. "Fehler bei Mail-Benachrichtigung in \"{0}\" für \"{1}", SystemName, notification.NotificationJobSystemName), ex);
  155. }
  156. }
  157. _logger.Information(
  158. String.Format(
  159. "Verarbeitung Mail-Benachrichtigung in \"{0}\" für \"{1} erfolgreich abgeschlossen!",
  160. SystemName, mailNotifications.First().NotificationJobSystemName));
  161. }
  162. /// <summary>
  163. /// Notifies the corresponding recipients about all deviations whose receipt date is older than N days in two different groups
  164. /// </summary>
  165. /// <param name="mailNotification">The notification which shall be generated.</param>
  166. private void ProcessDeviationReceiptNotification(MailNotification mailNotification)
  167. {
  168. var ageDaysLevel1 = _configurationService.TryGetConfigItemValue<int>(
  169. "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel1", 40);
  170. var ageDaysLevel2 = _configurationService.TryGetConfigItemValue<int>(
  171. "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel2", 60);
  172. var deviationsLevel1 = _deviationService.GetAllDeviations()
  173. .Where(d => !d.AppendixId.HasValue &&
  174. (DateTime.Now - d.ReceiptDate).Value.Days >= ageDaysLevel1 &&
  175. (DateTime.Now - d.ReceiptDate).Value.Days < ageDaysLevel2)
  176. .ToList();
  177. var deviationsLevel2 = _deviationService.GetAllDeviations()
  178. .Where(d => !d.AppendixId.HasValue &&
  179. (DateTime.Now - d.ReceiptDate).Value.Days >= ageDaysLevel2)
  180. .OrderBy(d => d.Site == null
  181. ? String.Empty
  182. : d.Site.CustomNumber)
  183. .ThenBy(d => d.CustomNumber)
  184. .ToList();
  185. if (deviationsLevel1.Any() || deviationsLevel2.Any())
  186. {
  187. var mailBody = GenerateDeviationReceiptMailBody(deviationsLevel1, deviationsLevel2);
  188. SendNotification(mailNotification, "Autom. Übersicht nicht zugewiesene Vertragsabweichungen", mailBody);
  189. }
  190. }
  191. #endregion
  192. #region Mail body generation
  193. /// <summary>
  194. /// Generates a mail body with a list of all deviations whose receipt date is older than N days in two different groups
  195. /// </summary>
  196. /// <param name="deviationsLevel1">All deviations matching the level 1 criteria.</param>
  197. /// <param name="deviationsLevel2">All deviations matching the level 2 criteria.</param>
  198. public string GenerateDeviationReceiptMailBody(IEnumerable<Deviation> deviationsLevel1, IEnumerable<Deviation> deviationsLevel2)
  199. {
  200. var ageDaysLevel1 = _configurationService.TryGetConfigItemValue<int>(
  201. "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel1", 40);
  202. var ageDaysLevel2 = _configurationService.TryGetConfigItemValue<int>(
  203. "GreenTree.Nachtragsmanagement.DeviationNotificationPlugin.ProcessDeviationReceipt.AgeDaysLevel2", 60);
  204. var template =
  205. "<html>" +
  206. " <body>" +
  207. " {0}" +
  208. " {1}" +
  209. " </body>" +
  210. "</html>";
  211. var templateLevel1 =
  212. "<h3>Übersicht \"Offene Vertragsabweichungen älter als {0} Tage\"</h3>" +
  213. "<p>Folgende Vertragsabweichungen haben ein Einreichdatum älter als {0} Tage, sind aber noch keinen Nachtrag zugeordnet:</p>" +
  214. "<ul>" +
  215. " {1}" +
  216. "</ul>";
  217. var templateLevel1List = String.Empty;
  218. if (deviationsLevel1.Any())
  219. {
  220. foreach (var deviation in deviationsLevel1)
  221. {
  222. templateLevel1List += String.Format(
  223. "<li>Baustelle <b>\"{1}\"</b> - " +
  224. "Vertragsabweichung <b>\"{0}\"</b> - " +
  225. "Einreichdatum: <b>{2:dd.MM.yyyy} ({3} Tage)</b></i>",
  226. deviation.Site == null
  227. ? String.Empty
  228. : deviation.Site.CustomNumber,
  229. deviation.CustomNumber,
  230. deviation.ReceiptDate,
  231. (DateTime.Now - deviation.ReceiptDate).Value.Days);
  232. }
  233. }
  234. var resultLevel1List = String.Format(templateLevel1, ageDaysLevel1, templateLevel1List);
  235. var templateLevel2 =
  236. "<h3>Übersicht \"Offene Vertragsabweichungen älter als {0} Tage\"</h3>" +
  237. "<p>Folgende Vertragsabweichungen haben ein Einreichdatum älter als {0} Tage, sind aber noch keinen Nachtrag zugeordnet:</p>" +
  238. "<ul>" +
  239. " {1}" +
  240. "</ul>";
  241. var templateLevel2List = String.Empty;
  242. if (deviationsLevel2.Any())
  243. {
  244. foreach (var deviation in deviationsLevel2)
  245. {
  246. templateLevel2List += String.Format(
  247. "<li>Vertragsabweichung <b>\"{0}\"</b> " +
  248. "in Baustelle <b>\"{1}\"</b> - " +
  249. "Einreichdatum: <b>{2:dd.MM.yyyy} ({3} Tage)</b>",
  250. deviation.CustomNumber,
  251. deviation.Site == null
  252. ? String.Empty
  253. : deviation.Site.CustomNumber,
  254. deviation.ReceiptDate,
  255. (DateTime.Now - deviation.ReceiptDate).Value.Days);
  256. }
  257. }
  258. var resultLevel2List = String.Format(templateLevel2, ageDaysLevel2, templateLevel2List);
  259. return String.Format(template, resultLevel1List, resultLevel2List);
  260. }
  261. #endregion
  262. #region Mail sending
  263. /// <summary>
  264. /// Sends a generated mail body to the specified recipients in the mail notification
  265. /// </summary>
  266. /// <param name="mailNotification">The mail notification.</param>
  267. /// <param name="subject">The mail subject.</param>
  268. /// <param name="body">The mail body.</param>
  269. public void SendNotification(MailNotification mailNotification, string subject, string body)
  270. {
  271. if (mailNotification == null) return;
  272. var mailServerConfig = _configurationService.GetCurrentConfiguration().MailServerElement;
  273. var smptClient = new SmtpClient(mailServerConfig.SmtpServer, mailServerConfig.Port)
  274. {
  275. EnableSsl = mailServerConfig.UseSsl,
  276. Credentials = new NetworkCredential(
  277. mailServerConfig.Username,
  278. mailServerConfig.Password,
  279. mailServerConfig.Domain)
  280. };
  281. var recipients =
  282. mailNotification.Users
  283. .Select(u => u.MailAddress);
  284. var mailMessage = new MailMessage
  285. {
  286. IsBodyHtml = true,
  287. Subject = subject,
  288. Body = body,
  289. From = new MailAddress("Nachtragsbenachrichtigung@schweerbau.de")
  290. };
  291. foreach (var recipient in recipients)
  292. mailMessage.To.Add(recipient);
  293. smptClient.Send(mailMessage);
  294. }
  295. #endregion
  296. }
  297. }