diff --git a/Common/LaaProduction/Equipment.cs b/Common/LaaProduction/Equipment.cs new file mode 100644 index 00000000..133242e0 --- /dev/null +++ b/Common/LaaProduction/Equipment.cs @@ -0,0 +1,27 @@ +namespace LaaProduction +{ + using System; + using System.Runtime.InteropServices; + + [ClassInterface(ClassInterfaceType.AutoDual)] + public class Equipment + { + public int PruefmittelId { get; set; } + + public string Pruefmittel { get; set; } + + public string PruefmittelNr { get; set; } + + public bool Erforderlich { get; set; } + + public DateTime PruefdatumIst { get; set; } + + public DateTime PruefdatumSoll { get; set; } + + public string Meldung { get; set; } + + public int DaysLeft { get; set; } + + public bool InSchedule { get; set; } + } +} diff --git a/Common/LaaProduction/Equipments.cs b/Common/LaaProduction/Equipments.cs new file mode 100644 index 00000000..f66d09ad --- /dev/null +++ b/Common/LaaProduction/Equipments.cs @@ -0,0 +1,178 @@ +namespace LaaProduction +{ + using Newtonsoft.Json; + + using System; + using System.Collections.Generic; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Runtime.InteropServices; + using System.Text; + + [ClassInterface(ClassInterfaceType.AutoDual)] + public partial class Equipments + { + private readonly HttpClient httpClient; + + private string bearer; + + public Equipments() + { + this.httpClient = new HttpClient() + { + BaseAddress = new Uri("http://sla12iis01.emea.sensus.net") + // BaseAddress = new Uri("http://localhost:59768") + }; + } + + public string Login(string assembly, int majorV, int minorV, int buildV, string username, string password) + { + var data = new LoginModel + { + Assembly = assembly, + MajorV = majorV, + MinorV = minorV, + BuildV = buildV, + Username = username, + Password = password.ComputeBase64Hash() + }; + + if (!data.TryValidate(out string errors)) + { + return errors; + } + + var error = default(Error); + + try + { + using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri("/LaaProductionWeb/api/Login/Local", UriKind.Relative))) + { + httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"); + + var httpResponseMessage = this.httpClient + .SendAsync(httpRequestMessage) + .ConfigureAwait(true) + .GetAwaiter() + .GetResult(); + + if (httpResponseMessage?.Content != null) + { + using (httpResponseMessage) + { + var responseContent = httpResponseMessage + .Content + .ReadAsStringAsync() + .ConfigureAwait(true) + .GetAwaiter() + .GetResult(); + + try + { + if (!httpResponseMessage.IsSuccessStatusCode) + { + error = JsonConvert.DeserializeObject(responseContent); + } + else + { + this.bearer = JsonConvert.DeserializeObject(responseContent); + } + } + catch (Exception e) + { + error.Message = e.Message; + error.MessageDetail = e.StackTrace; + } + } + } + } + } + catch (Exception e) + { + return $"{e.Message}{Environment.NewLine}{e.StackTrace}"; + } + + if (string.IsNullOrWhiteSpace(this.bearer)) + { + return "Invalid login attempt at '~/LaaProductionWeb/API/Login/Local'!"; + } + else if (error != null) + { + return error.ToString(); + } + + + return default(string); + } + + public EquipmentsResult PendingInspections() + { + var result = new EquipmentsResult(); + var uri = new Uri($"/LaaProductionWeb/api/Personalization/Software/PendingInspections", UriKind.Relative); + + try + { + using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)) + { + httpRequestMessage + .Headers + .Authorization = new AuthenticationHeaderValue("Bearer", this.bearer); + + var httpResponseMessage = this.httpClient + .SendAsync(httpRequestMessage) + .ConfigureAwait(true) + .GetAwaiter() + .GetResult(); + + if (httpResponseMessage?.Content != null) + { + using (httpResponseMessage) + { + var responseContent = httpResponseMessage + .Content + .ReadAsStringAsync() + .ConfigureAwait(true) + .GetAwaiter() + .GetResult(); + + try + { + if (!httpResponseMessage.IsSuccessStatusCode) + { + result.Error = JsonConvert.DeserializeObject(responseContent); + } + else + { + var pendingInspections = JsonConvert.DeserializeObject>(responseContent); + + result.AddRange(pendingInspections); + } + } + catch (Exception e) + { + httpResponseMessage.Dispose(); + httpRequestMessage.Dispose(); + + result.Error = new Error + { + Message = e.Message, + MessageDetail = e.StackTrace + }; + } + } + } + } + } + catch (Exception e) + { + result.Error = new Error + { + Message = e.Message, + MessageDetail = e.StackTrace + }; + } + + return result; + } + } +} diff --git a/Common/LaaProduction/EquipmentsResult.cs b/Common/LaaProduction/EquipmentsResult.cs new file mode 100644 index 00000000..f6e5dfdc --- /dev/null +++ b/Common/LaaProduction/EquipmentsResult.cs @@ -0,0 +1,42 @@ +namespace LaaProduction +{ + using System.Collections.Generic; + using System.Runtime.InteropServices; + + [ClassInterface(ClassInterfaceType.AutoDual)] + public class EquipmentsResult + { + private readonly Queue equipments = new Queue(); + + public bool Succeeded => this.Error is null; + + public int Count => this.equipments.Count; + + public Equipment Next + { + get + { + var next = this.equipments.Dequeue(); + + this.equipments.Enqueue(next); + + return next; + } + } + + public Error Error { get; set; } + + internal void AddRange(IEnumerable equipments) + { + if (equipments is null) + { + return; + } + + foreach (var e in equipments) + { + this.equipments.Enqueue(e); + } + } + } +} diff --git a/Common/LaaProduction/Error.cs b/Common/LaaProduction/Error.cs new file mode 100644 index 00000000..99750f82 --- /dev/null +++ b/Common/LaaProduction/Error.cs @@ -0,0 +1,16 @@ +namespace LaaProduction +{ + using System; + using System.Runtime.InteropServices; + + [ClassInterface(ClassInterfaceType.AutoDual)] + public class Error + { + public string Message { get; set; } + + public string MessageDetail { get; set; } + + public override string ToString() + => $"{this.Message}{Environment.NewLine}{this.MessageDetail}"; + } +} diff --git a/Common/LaaProduction/Extensions.cs b/Common/LaaProduction/Extensions.cs new file mode 100644 index 00000000..4a435cd4 --- /dev/null +++ b/Common/LaaProduction/Extensions.cs @@ -0,0 +1,65 @@ +namespace LaaProduction +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.Security.Cryptography; + using System.Text; + + internal static class Extensions + { + internal static string ComputeBase64Hash(this string value) + { + if (!string.IsNullOrWhiteSpace(value)) + { + var bytes = Encoding.UTF8.GetBytes(value); + var hash = SHA256.Create().ComputeHash(bytes); + var base64 = Convert.ToBase64String(hash); + + return base64; + } + + return value; + } + + internal static bool TryValidate(this object model, out string errors) + { + errors = default(string); + + var validationResults = new List(); + var validationContext = new ValidationContext(model); + + if (!Validator.TryValidateObject(model, validationContext, validationResults, true)) + { + var errorBuilder = new StringBuilder(); + + foreach (var error in validationResults) + { + var errorMessage = error.ErrorMessage; + + if (string.IsNullOrWhiteSpace(errorMessage)) + { + continue; + } + + var property = "Error"; + + foreach (var member in error.MemberNames) + { + property = member; + + break; + } + + errorBuilder.AppendLine($"[{property}] -> {errorMessage}"); + } + + errors = errorBuilder.ToString(); + + return false; + } + + return true; + } + } +} diff --git a/Common/LaaProduction/LaaProduction.csproj b/Common/LaaProduction/LaaProduction.csproj index 77173699..e9e033a9 100644 --- a/Common/LaaProduction/LaaProduction.csproj +++ b/Common/LaaProduction/LaaProduction.csproj @@ -12,15 +12,17 @@ v4.8.1 512 true + true full false - bin\Debug\ + ..\..\..\..\..\..\..\Temp\drueckpruefung\ DEBUG;TRACE prompt 4 + false pdbonly @@ -30,27 +32,38 @@ prompt 4 + + + + + true + + + LaaProduction_SigningKey.pfx + - - ..\packages\LaaProductionHttp.1.0.0\lib\netstandard2.0\LaaProductionHttp.dll - ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + - - - - - + + + + + + + + + diff --git a/Common/LaaProduction/LoginModel.cs b/Common/LaaProduction/LoginModel.cs new file mode 100644 index 00000000..74e2a741 --- /dev/null +++ b/Common/LaaProduction/LoginModel.cs @@ -0,0 +1,24 @@ +namespace LaaProduction +{ + using Newtonsoft.Json; + + using System.ComponentModel.DataAnnotations; + + internal class LoginModel + { + [Required] + public string Assembly { get; set; } + + public int MajorV { get; set; } + + public int MinorV { get; set; } + + public int BuildV { get; set; } + + [Required] + public string Username { get; set; } + + [Required] + public string Password { get; set; } + } +} diff --git a/Common/LaaProduction/Programm.cs b/Common/LaaProduction/Programm.cs new file mode 100644 index 00000000..dd44ef55 --- /dev/null +++ b/Common/LaaProduction/Programm.cs @@ -0,0 +1,14 @@ +namespace LaaProduction +{ + //class Programm + //{ + // static void Main() + // { + // var equipmentsManager = new Equipments(); + // var state = equipmentsManager.Login("Druckpruefung", 1, 0, 130, "zlatev", "rd"); + // var count = equipmentsManager.PendingInspections(); + + // System.Console.WriteLine(state); + // } + //} +} diff --git a/Common/LaaProduction/Properties/AssemblyInfo.cs b/Common/LaaProduction/Properties/AssemblyInfo.cs index 353c87ff..eaf5bea0 100644 --- a/Common/LaaProduction/Properties/AssemblyInfo.cs +++ b/Common/LaaProduction/Properties/AssemblyInfo.cs @@ -1,36 +1,8 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. [assembly: AssemblyTitle("LaaProduction")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LaaProduction")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("fd30eb7a-7809-4e62-9374-791d31877d6d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.0.1.0")] +[assembly: AssemblyFileVersion("1.0.1.0")] +[assembly: ComVisible(true)] +[assembly: Guid("80B87C7E-B79A-4594-8B7B-3A72F4894670")] diff --git a/Common/LaaProduction/Pruefstation.cs b/Common/LaaProduction/Pruefstation.cs deleted file mode 100644 index 5cc2d533..00000000 --- a/Common/LaaProduction/Pruefstation.cs +++ /dev/null @@ -1,98 +0,0 @@ -namespace LaaProduction -{ - using LaaProductionHttp; - using LaaProductionHttp.Interfaces; - - using System; - using System.Collections.Generic; - - public class Pruefstation - { - private readonly IHttpClient httpClient; - - private string bearer; - private int stationId; - private string stationName; - private IEnumerable equipments; - - - public Pruefstation() - => this.httpClient = HttpClient.CreateHttpClient("http://sla12iis01.emea.sensus.net", "/LaaProductionWeb/api"); - - public async void Initialize(string exe, string username, string password) - { - if (!this.TryGetAssemblyInfo(exe, out string assembly, out int majorV, out int minorV, out int buildV)) - { - return; - } - - var bearer = await this.httpClient - .Post("/Login/Local") - .WhitJsonBody(new - { - assembly, - majorV, - minorV, - buildV, - username, - password - }) - .SendAsync(); - - if (!bearer.Succeeded) - { - return; - } - - // TODO: load equipments state. - } - - private bool TryGetAssemblyInfo(string exe, out string assembly, out int majorV, out int minorV, out int buildV) - { - assembly = string.Empty; - majorV = default(int); - minorV = default(int); - buildV = default(int); - - if (string.IsNullOrWhiteSpace(exe)) - { - return false; - } - - var exeTokens = exe.Split(new[] { '.' }); - - if (exeTokens.Length != 4) - { - return false; - } - - var index = 0; - - assembly = exeTokens[index++]; - _ = int.TryParse(exeTokens[index++], out majorV); - _ = int.TryParse(exeTokens[index++], out minorV); - _ = int.TryParse(exeTokens[index++], out buildV); - - return true; - } - - internal class Equipment - { - public int Id { get; set; } - - public string Nr { get; set; } - - public string Name { get; set; } - - public bool Required { get; set; } - - public bool Inspected { get; set; } - - public int InspectionSpan { get; set; } - - public DateTime? LastInspection { get; set; } - - public DateTime? NextInspection { get; set; } - } - } -} diff --git a/LaaProductionWeb/LaaProduction.Personalization/AccountManager.cs b/LaaProductionWeb/LaaProduction.Personalization/AccountManager.cs index cf8920f1..50920478 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/AccountManager.cs +++ b/LaaProductionWeb/LaaProduction.Personalization/AccountManager.cs @@ -117,7 +117,7 @@ return default(string); } - return this.GetÓrCreateAuthToken(softwareId, employeeNr); + return this.GetOrCreateAuthToken(softwareId, employeeNr); } public string Login(UserLoginModel model) @@ -140,7 +140,7 @@ return default(string); } - return this.GetÓrCreateAuthToken(softwareId, employeeNr); + return this.GetOrCreateAuthToken(softwareId, employeeNr); } public void ResetPassword(short employeeId) @@ -164,7 +164,7 @@ return softwareId; } - public string GetÓrCreateAuthToken(short appId, short userId) + public string GetOrCreateAuthToken(short appId, short userId) { var token = default(string); diff --git a/LaaProductionWeb/LaaProduction.Personalization/ComponentModel.DataAnnotations/DateTimeAttribute.cs b/LaaProductionWeb/LaaProduction.Personalization/ComponentModel.DataAnnotations/DateTimeAttribute.cs new file mode 100644 index 00000000..158dbe73 --- /dev/null +++ b/LaaProductionWeb/LaaProduction.Personalization/ComponentModel.DataAnnotations/DateTimeAttribute.cs @@ -0,0 +1,76 @@ +namespace LaaProduction.Personalization.ComponentModel.DataAnnotations +{ + using System; + using System.ComponentModel.DataAnnotations; + using System.Reflection; + + public class DateTimeAttribute : ValidationAttribute + { + private readonly DateTimeOptions option; + private readonly string otherProperty; + + public DateTimeAttribute(DateTimeOptions option, string otherProperty) + { + this.option = option; + this.otherProperty = $"{otherProperty}"; + } + + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + var validationMessage = default(string); + + if (value is DateTime currentDate) + { + var property = validationContext + ?.ObjectType + ?.GetProperty(this.otherProperty, BindingFlags.Public | BindingFlags.Instance); + + if (property is null) + { + validationMessage = $"The '{this.otherProperty}' is invalid."; + } + else + { + var otherValue = property + .GetValue(validationContext?.ObjectInstance); + var otherDisplayName = property + .GetCustomAttribute() + ?.GetName() ?? this.otherProperty; + + if (otherValue is DateTime otherDate) + { + if (this.option == DateTimeOptions.GreaterThan && currentDate <= otherDate) + { + validationMessage = $"The '{validationContext.DisplayName}' should be greater than '{otherDisplayName}'"; + } + else if (this.option == DateTimeOptions.SmallerThan && currentDate >= otherDate) + { + validationMessage = $"The '{validationContext.DisplayName}' should be smaller than '{otherDisplayName}'"; + } + } + else + { + validationMessage = $"The '{otherDisplayName}' is invalid."; + } + } + } + else + { + validationMessage = $"The '{validationContext?.DisplayName}' is invalid."; + } + + if (string.IsNullOrWhiteSpace(validationMessage)) + { + return ValidationResult.Success; + } + + return new ValidationResult(validationMessage); + } + } + + public enum DateTimeOptions + { + GreaterThan, + SmallerThan, + } +} \ No newline at end of file diff --git a/LaaProductionWeb/LaaProduction.Personalization/EquipmentsManager.cs b/LaaProductionWeb/LaaProduction.Personalization/EquipmentsManager.cs index f0e7ca7b..4cebd148 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/EquipmentsManager.cs +++ b/LaaProductionWeb/LaaProduction.Personalization/EquipmentsManager.cs @@ -1,258 +1,103 @@ namespace LaaProduction.Personalization { using LaaProduction.Personalization.Interfaces; - using LaaProductionSQL.Interfaces; + using LaaProduction.Personalization.Models; + using LaaProduction.Personalization.Repositories.Interfaces; + using LaaProductionSMTP; using System; using System.Collections.Generic; - using System.ComponentModel.DataAnnotations; + using System.Linq; + using System.Text.RegularExpressions; public class EquipmentsManager : IEquipmentsManager { - private readonly ISQLConnection sqlConnection; + private readonly IEquipmentsRepository equipments; + private readonly SMTPClient smtpClient; - public EquipmentsManager(ISQLConnection sqlConnection) - => this.sqlConnection = sqlConnection; + public EquipmentsManager(IEquipmentsRepository equipments, SMTPClient smtpClient) + { + this.equipments = equipments; + this.smtpClient = smtpClient; + } - public int Add(PruefmittelPruefung model) - => this.sqlConnection - .CreateCommand($@" - INSERT - INTO [PruefmittelPruefung] - ( [Pruefstation] - , [Pruefmittel] - , [PruefmittelNr] - , [Pruefintervall] - , [Erforderlich] - , [PruefdatumIst] - , [PruefdatumSoll] - , [Bemerkung] - , [EmailAn] - , [InCcAn] - , [Betreff] - , [Nachricht] - , [Meldung] - , [Schedule]) - OUTPUT [inserted].[PruefmittelId] - VALUES (@{nameof(model.Pruefstation)} - , @{nameof(model.Pruefmittel)} - , @{nameof(model.PruefmittelNr)} - , @{nameof(model.Pruefintervall)} - , @{nameof(model.Erforderlich)} - , @{nameof(model.PruefdatumIst)} - , @{nameof(model.PruefdatumSoll)} - , @{nameof(model.Bemerkung)} - , @{nameof(model.EmailAn)} - , @{nameof(model.InCcAn)} - , @{nameof(model.Betreff)} - , @{nameof(model.Nachricht)} - , @{nameof(model.Meldung)} - , @{nameof(model.Schedule)})") - .SetParameter(nameof(model.Pruefstation), model.Pruefstation) - .SetParameter(nameof(model.Pruefmittel), model.Pruefmittel) - .SetParameter(nameof(model.PruefmittelNr), model.PruefmittelNr) - .SetParameter(nameof(model.Pruefintervall), model.Pruefintervall) - .SetParameter(nameof(model.Erforderlich), model.Erforderlich) - .SetParameter(nameof(model.PruefdatumIst), model.PruefdatumIst) - .SetParameter(nameof(model.PruefdatumSoll), model.PruefdatumSoll) - .SetParameter(nameof(model.Bemerkung), model.Bemerkung) - .SetParameter(nameof(model.EmailAn), model.EmailAn) - .SetParameter(nameof(model.InCcAn), model.InCcAn) - .SetParameter(nameof(model.Betreff), model.Betreff) - .SetParameter(nameof(model.Nachricht), model.Nachricht) - .SetParameter(nameof(model.Meldung), model.Meldung) - .SetParameter(nameof(model.Schedule), model.Schedule) - .ExecuteScalar(x => x.GetInt()); + public int Add(PruefmittelPruefung model) + => this.equipments.Add(model); - public PruefmittelPruefung FindById(int pruefmittelId) - => this.sqlConnection - .CreateCommand($@" - SELECT [PruefmittelId] - , [Pruefstation] - , [Pruefmittel] - , [PruefmittelNr] - , [Pruefintervall] - , [Erforderlich] - , [PruefdatumIst] - , [PruefdatumSoll] - , [Bemerkung] - , [EmailAn] - , [InCcAn] - , [Betreff] - , [Nachricht] - , [Meldung] - , [Schedule] - FROM [PruefmittelPruefung] - WHERE [PruefmittelId] = @{nameof(pruefmittelId)}") - .SetParameter(nameof(pruefmittelId), pruefmittelId) - .FirstOrDefault(x => new PruefmittelPruefung - { - PruefmittelId = x.GetInt(), - Pruefstation = x.GetString(), - Pruefmittel = x.GetString(), - PruefmittelNr = x.GetString(), - Pruefintervall = x.GetInt(), - Erforderlich = x.GetBool(), - PruefdatumIst = x.GetDate(), - PruefdatumSoll = x.GetDate(), - Bemerkung = x.GetString(), - EmailAn = x.GetString(), - InCcAn = x.GetString(), - Betreff = x.GetString(), - Nachricht = x.GetString(), - Meldung = x.GetString(), - Schedule = x.GetString() - }) ?? new PruefmittelPruefung(); + public PruefmittelPruefung FindById(int pruefmittelId) + => this.equipments.FindById(pruefmittelId) + ?? new PruefmittelPruefung(); public int Remove(int pruefmittelId) - => this.sqlConnection - .CreateCommand($@" - DELETE - FROM [PruefmittelPruefung] - WHERE [PruefmittelId] = @{nameof(pruefmittelId)}") - .SetParameter(nameof(pruefmittelId), pruefmittelId) - .ExecuteNonQuery(); + => this.equipments.Remove(pruefmittelId); - public IEnumerable SelectAll() - => this.sqlConnection - .CreateCommand(@" - SELECT [PruefmittelId] - , [Pruefstation] - , [Pruefmittel] - , [PruefmittelNr] - , [Pruefintervall] - , [Erforderlich] - , [PruefdatumIst] - , [PruefdatumSoll] - , [Bemerkung] - , [EmailAn] - , [InCcAn] - , [Betreff] - , [Nachricht] - , [Meldung] - , [Schedule] - FROM [PruefmittelPruefung]") - .ExecuteReader(x => new PruefmittelPruefung + public IEnumerable SelectAll() + => this.equipments.SelectAll(); + + public IEnumerable SelectAll(int softwareId) + { + var equipments = this.equipments + .SelectAll(softwareId) + .ToList(); + + foreach (var equipment in equipments) + { + var matches = Regex.Matches($"{equipment?.Schedule}", "\\d+", RegexOptions.Multiline); + var daysInSchedule = new List(); + + foreach (Match match in matches) { - PruefmittelId = x.GetInt(), - Pruefstation = x.GetString(), - Pruefmittel = x.GetString(), - PruefmittelNr = x.GetString(), - Pruefintervall = x.GetInt(), - Erforderlich = x.GetBool(), - PruefdatumIst = x.GetDate(), - PruefdatumSoll = x.GetDate(), - Bemerkung = x.GetString(), - EmailAn = x.GetString(), - InCcAn = x.GetString(), - Betreff = x.GetString(), - Nachricht = x.GetString(), - Meldung = x.GetString(), - Schedule = x.GetString() - }); + if (match.Success && int.TryParse(match.Value, out var day)) + { + daysInSchedule.Add(day); + } + } - public int Update(PruefmittelPruefung model) - => this.sqlConnection - .CreateCommand($@" - UPDATE [PruefmittelPruefung] - SET [Pruefstation] = @{nameof(model.Pruefstation)} - , [Pruefmittel] = @{nameof(model.Pruefmittel)} - , [PruefmittelNr] = @{nameof(model.PruefmittelNr)} - , [Pruefintervall] = @{nameof(model.Pruefintervall)} - , [Erforderlich] = @{nameof(model.Erforderlich)} - , [PruefdatumIst] = @{nameof(model.PruefdatumIst)} - , [PruefdatumSoll] = @{nameof(model.PruefdatumSoll)} - , [Bemerkung] = @{nameof(model.Bemerkung)} - , [EmailAn] = @{nameof(model.EmailAn)} - , [InCcAn] = @{nameof(model.InCcAn)} - , [Betreff] = @{nameof(model.Betreff)} - , [Nachricht] = @{nameof(model.Nachricht)} - , [Meldung] = @{nameof(model.Meldung)} - , [Schedule] = @{nameof(model.Schedule)} - WHERE [PruefmittelId] = @{nameof(model.PruefmittelId)}") - .SetParameter(nameof(model.PruefmittelId), model.PruefmittelId) - .SetParameter(nameof(model.Pruefstation), model.Pruefstation) - .SetParameter(nameof(model.Pruefmittel), model.Pruefmittel) - .SetParameter(nameof(model.PruefmittelNr), model.PruefmittelNr) - .SetParameter(nameof(model.Pruefintervall), model.Pruefintervall) - .SetParameter(nameof(model.Erforderlich), model.Erforderlich) - .SetParameter(nameof(model.PruefdatumIst), model.PruefdatumIst) - .SetParameter(nameof(model.PruefdatumSoll), model.PruefdatumSoll) - .SetParameter(nameof(model.Bemerkung), model.Bemerkung) - .SetParameter(nameof(model.EmailAn), model.EmailAn) - .SetParameter(nameof(model.InCcAn), model.InCcAn) - .SetParameter(nameof(model.Betreff), model.Betreff) - .SetParameter(nameof(model.Nachricht), model.Nachricht) - .SetParameter(nameof(model.Meldung), model.Meldung) - .SetParameter(nameof(model.Schedule), model.Schedule) - .ExecuteNonQuery(); - } + var scheduleBegin = daysInSchedule.Max(x => x); - public class PruefmittelPruefung - { - public int PruefmittelId { get; set; } + equipment.DaysLeft = equipment.PruefdatumSoll.Subtract(DateTime.Now).Days; + equipment.InSchedule = Math.Min(scheduleBegin, equipment.Pruefintervall) >= equipment.DaysLeft; - [Required] - [StringLength(100)] - [Display(Name = "Prüfstation Bezeichnung")] - public string Pruefstation { get; set; } + var pruefintervall = equipment.PruefdatumSoll.Subtract(equipment.PruefdatumIst).Days; - [Required] - [StringLength(100)] - [Display(Name = "Prüfmittel Bezeichnung")] - public string Pruefmittel { get; set; } + if (equipment.Erforderlich && pruefintervall == equipment.Pruefintervall && daysInSchedule.Contains(equipment.DaysLeft)) + { + var separator = new[] { ',', ';', ' ' }; + var options = StringSplitOptions.RemoveEmptyEntries; + var emailsTo = equipment.EmailAn.Split(separator, options); + var emailsCC = equipment.InCcAn.Split(separator, options); + var sender = $"{equipment.Pruefmittel}_{equipment.PruefmittelNr}@xylem.com".Replace(" ", "_"); - [Required] - [StringLength(30)] - [Display(Name = "Prüfmittelnummer")] - public string PruefmittelNr { get; set; } + this.smtpClient + .CreateMessage() + .Subject(equipment.Betreff) + .Body(equipment.Nachricht) + .From(sender) + .To(emailsTo) + .CC(emailsCC) + .Send(); + } + } - [Range(1, int.MaxValue)] - [Display(Name = "Prüfintervall in Tagen")] - public int Pruefintervall { get; set; } = 1; + return equipments; + } - [Display(Name = "Ist die Prüfung erforderlich?")] - public bool Erforderlich { get; set; } = true; + public void SetInspected(int pruefmittelId) + { + var existing = this.equipments.FindById(pruefmittelId); - [Display(Name = "Zuletzt geprüft am (yyyy-MM-dd)")] - public DateTime PruefdatumIst { get; set; } = DateTime.Now; + if (existing is null || existing.PruefdatumIst >= DateTime.Now) + { + return; + } - [Display(Name = "Nächste Prüfung am (yyyy-MM-dd)")] - public DateTime PruefdatumSoll { get; set; } = DateTime.Now; + existing.PruefdatumIst = existing.PruefdatumSoll; + existing.PruefdatumSoll = existing.PruefdatumIst.AddDays(existing.Pruefintervall); - [Required] - [StringLength(250)] - [Display(Name = "Bemerkung zu der Prüfmittelprüfung.")] - public string Bemerkung { get; set; } + this.equipments.Update(existing); + } - [Required] - [StringLength(500)] - [Display(Name = "E-Mail-An liste")] - public string EmailAn { get; set; } - - [Required] - [StringLength(500)] - [Display(Name = "E-Mail-CC liste")] - public string InCcAn { get; set; } - - [Required] - [StringLength(150)] - [Display(Name = "Betreff")] - public string Betreff { get; set; } - - [Required] - [StringLength(500)] - [Display(Name = "Nachrichtentext")] - public string Nachricht { get; set; } - - [Required] - [StringLength(500)] - [Display(Name = "Softwaremeldungstext")] - public string Meldung { get; set; } - - [Required] - [StringLength(50)] - [Display(Name = "E-Mailversand Zeitplan")] - public string Schedule { get; set; } = "14, 7, 3, 1"; + public int Update(PruefmittelPruefung model) + => this.equipments.Update(model); } } diff --git a/LaaProductionWeb/LaaProduction.Personalization/Interfaces/IEquipmentsManager.cs b/LaaProductionWeb/LaaProduction.Personalization/Interfaces/IEquipmentsManager.cs index a6a81993..2a201739 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/Interfaces/IEquipmentsManager.cs +++ b/LaaProductionWeb/LaaProduction.Personalization/Interfaces/IEquipmentsManager.cs @@ -1,5 +1,7 @@ namespace LaaProduction.Personalization.Interfaces { + using LaaProduction.Personalization.Models; + using System.Collections.Generic; public interface IEquipmentsManager @@ -12,6 +14,10 @@ IEnumerable SelectAll(); + IEnumerable SelectAll(int softwareId); + + void SetInspected(int pruefmittelId); + int Update(PruefmittelPruefung model); } } diff --git a/LaaProductionWeb/LaaProduction.Personalization/LaaProduction.Personalization.csproj b/LaaProductionWeb/LaaProduction.Personalization/LaaProduction.Personalization.csproj index c2c8257a..fe488d91 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/LaaProduction.Personalization.csproj +++ b/LaaProductionWeb/LaaProduction.Personalization/LaaProduction.Personalization.csproj @@ -31,11 +31,17 @@ 4 - - ..\packages\LaaProductionDI.1.0.2\lib\netstandard2.0\LaaProductionDI.dll + + ..\packages\LaaProductionDI.1.0.4\lib\netstandard2.0\LaaProductionDI.dll - - ..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll + + ..\packages\LaaProductionSMTP.1.0.4\lib\netstandard2.0\LaaProductionSMTP.dll + + + ..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll + + + ..\packages\MailKit.4.1.0\lib\net48\MailKit.dll ..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll @@ -46,18 +52,24 @@ ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + ..\packages\MimeKit.4.1.0\lib\net48\MimeKit.dll + + + ..\packages\System.Data.SqlClient.4.8.5\lib\net461\System.Data.SqlClient.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll @@ -65,6 +77,7 @@ + @@ -82,6 +95,7 @@ + diff --git a/LaaProductionWeb/LaaProduction.Personalization/Models/PruefmittelPruefung.cs b/LaaProductionWeb/LaaProduction.Personalization/Models/PruefmittelPruefung.cs new file mode 100644 index 00000000..dd01fb07 --- /dev/null +++ b/LaaProductionWeb/LaaProduction.Personalization/Models/PruefmittelPruefung.cs @@ -0,0 +1,82 @@ +namespace LaaProduction.Personalization.Models +{ + using LaaProduction.Personalization.ComponentModel.DataAnnotations; + + using System; + using System.ComponentModel.DataAnnotations; + + public class PruefmittelPruefung + { + public int PruefmittelId { get; set; } + + [Range(1, int.MaxValue)] + [Display(Name = "Prüfsoftware")] + public short SoftwareId { get; set; } + + [Required] + [StringLength(100)] + [Display(Name = "Prüfmittel Bezeichnung")] + public string Pruefmittel { get; set; } + + [Required] + [StringLength(30)] + [Display(Name = "Prüfmittelnummer")] + public string PruefmittelNr { get; set; } + + [Range(1, int.MaxValue)] + [Display(Name = "Prüfintervall in Tagen")] + public int Pruefintervall { get; set; } = 1; + + [Display(Name = "Ist die Prüfung erforderlich?")] + public bool Erforderlich { get; set; } = true; + + [Display(Name = "Zuletzt geprüft am (yyyy-MM-dd)")] + [DateTime(DateTimeOptions.SmallerThan, nameof(PruefdatumSoll))] + public DateTime PruefdatumIst { get; set; } = DateTime.Now; + + [Display(Name = "Nächste Prüfung am (yyyy-MM-dd)")] + [DateTime(DateTimeOptions.GreaterThan, nameof(PruefdatumIst))] + public DateTime PruefdatumSoll { get; set; } = DateTime.Now; + + [Required] + [StringLength(250)] + [Display(Name = "Bemerkung zu der Prüfmittelprüfung.")] + public string Bemerkung { get; set; } + + [Required] + [StringLength(500)] + [Display(Name = "E-Mail-An liste")] + public string EmailAn { get; set; } + + [Required] + [StringLength(500)] + [Display(Name = "E-Mail-CC liste")] + public string InCcAn { get; set; } + + [Required] + [StringLength(150)] + [Display(Name = "Betreff")] + public string Betreff { get; set; } + + [Required] + [StringLength(500)] + [Display(Name = "Nachrichtentext")] + public string Nachricht { get; set; } + + [Required] + [StringLength(500)] + [Display(Name = "Softwaremeldungstext")] + public string Meldung { get; set; } + + [Required] + [StringLength(50)] + [Display(Name = "E-Mailversand Zeitplan")] + public string Schedule { get; set; } = "14, 7, 3, 1"; + + public int DaysLeft { get; set; } + + public bool InSchedule { get; set; } + + public bool SendEmail { get; set; } + } +} diff --git a/LaaProductionWeb/LaaProduction.Personalization/README.md b/LaaProductionWeb/LaaProduction.Personalization/README.md index 12c37fd7..c7ca196b 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/README.md +++ b/LaaProductionWeb/LaaProduction.Personalization/README.md @@ -14,7 +14,7 @@ GO CREATE TABLE [PruefmittelPruefung] ( [PruefmittelId] INT PRIMARY KEY NOT NULL IDENTITY(1, 1), - [Pruefstation] VARCHAR(100) NOT NULL, + [SoftwareId] SMALLINT NOT NULL, [Pruefmittel] VARCHAR(100) NOT NULL, [PruefmittelNr] VARCHAR(30) NOT NULL, [Pruefintervall] INT NOT NULL, @@ -32,5 +32,5 @@ CREATE TABLE [PruefmittelPruefung] ( CREATE UNIQUE INDEX [UX_PruefmittelPruefung] ON [PruefmittelPruefung] ( - [Pruefstation] + [SoftwareId] , [PruefmittelNr]); \ No newline at end of file diff --git a/LaaProductionWeb/LaaProduction.Personalization/Repositories/EquipmentsRepository.cs b/LaaProductionWeb/LaaProduction.Personalization/Repositories/EquipmentsRepository.cs index 77a4aa4a..16513418 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/Repositories/EquipmentsRepository.cs +++ b/LaaProductionWeb/LaaProduction.Personalization/Repositories/EquipmentsRepository.cs @@ -1,8 +1,229 @@ namespace LaaProduction.Personalization.Repositories { + using LaaProduction.Personalization.Models; using LaaProduction.Personalization.Repositories.Interfaces; + using LaaProductionSQL.Interfaces; + + using System.Collections.Generic; internal class EquipmentsRepository : IEquipmentsRepository { + private readonly ISQLConnection sqlConnection; + + public EquipmentsRepository(ISQLConnection sqlConnection) + => this.sqlConnection = sqlConnection; + + public int Add(PruefmittelPruefung model) + => this.sqlConnection + .CreateCommand($@" + INSERT + INTO [PruefmittelPruefung] + ( [SoftwareId] + , [Pruefmittel] + , [PruefmittelNr] + , [Pruefintervall] + , [Erforderlich] + , [PruefdatumIst] + , [PruefdatumSoll] + , [Bemerkung] + , [EmailAn] + , [InCcAn] + , [Betreff] + , [Nachricht] + , [Meldung] + , [Schedule]) + OUTPUT [inserted].[PruefmittelId] + VALUES (@{nameof(model.SoftwareId)} + , @{nameof(model.Pruefmittel)} + , @{nameof(model.PruefmittelNr)} + , @{nameof(model.Pruefintervall)} + , @{nameof(model.Erforderlich)} + , @{nameof(model.PruefdatumIst)} + , @{nameof(model.PruefdatumSoll)} + , @{nameof(model.Bemerkung)} + , @{nameof(model.EmailAn)} + , @{nameof(model.InCcAn)} + , @{nameof(model.Betreff)} + , @{nameof(model.Nachricht)} + , @{nameof(model.Meldung)} + , @{nameof(model.Schedule)})") + .SetParameter(nameof(model.SoftwareId), model.SoftwareId) + .SetParameter(nameof(model.Pruefmittel), model.Pruefmittel) + .SetParameter(nameof(model.PruefmittelNr), model.PruefmittelNr) + .SetParameter(nameof(model.Pruefintervall), model.Pruefintervall) + .SetParameter(nameof(model.Erforderlich), model.Erforderlich) + .SetParameter(nameof(model.PruefdatumIst), model.PruefdatumIst) + .SetParameter(nameof(model.PruefdatumSoll), model.PruefdatumSoll) + .SetParameter(nameof(model.Bemerkung), model.Bemerkung) + .SetParameter(nameof(model.EmailAn), model.EmailAn) + .SetParameter(nameof(model.InCcAn), model.InCcAn) + .SetParameter(nameof(model.Betreff), model.Betreff) + .SetParameter(nameof(model.Nachricht), model.Nachricht) + .SetParameter(nameof(model.Meldung), model.Meldung) + .SetParameter(nameof(model.Schedule), model.Schedule) + .ExecuteScalar(x => x.GetInt()); + + public PruefmittelPruefung FindById(int pruefmittelId) + => this.sqlConnection + .CreateCommand($@" + SELECT [PruefmittelId] + , [SoftwareId] + , [Pruefmittel] + , [PruefmittelNr] + , [Pruefintervall] + , [Erforderlich] + , [PruefdatumIst] + , [PruefdatumSoll] + , [Bemerkung] + , [EmailAn] + , [InCcAn] + , [Betreff] + , [Nachricht] + , [Meldung] + , [Schedule] + FROM [PruefmittelPruefung] + WHERE [PruefmittelId] = @{nameof(pruefmittelId)}") + .SetParameter(nameof(pruefmittelId), pruefmittelId) + .FirstOrDefault(x => new PruefmittelPruefung + { + PruefmittelId = x.GetInt(), + SoftwareId = x.GetSmallint(), + Pruefmittel = x.GetString(), + PruefmittelNr = x.GetString(), + Pruefintervall = x.GetInt(), + Erforderlich = x.GetBool(), + PruefdatumIst = x.GetDate(), + PruefdatumSoll = x.GetDate(), + Bemerkung = x.GetString(), + EmailAn = x.GetString(), + InCcAn = x.GetString(), + Betreff = x.GetString(), + Nachricht = x.GetString(), + Meldung = x.GetString(), + Schedule = x.GetString() + }); + + public IEnumerable SelectAll(int softwareId) + => this.sqlConnection + .CreateCommand($@" + SELECT [PruefmittelId] + , [SoftwareId] + , [Pruefmittel] + , [PruefmittelNr] + , [Pruefintervall] + , [Erforderlich] + , [PruefdatumIst] + , [PruefdatumSoll] + , [Bemerkung] + , [EmailAn] + , [InCcAn] + , [Betreff] + , [Nachricht] + , [Meldung] + , [Schedule] + FROM [PruefmittelPruefung] + WHERE [SoftwareId] = @{nameof(softwareId)}") + .SetParameter(nameof(softwareId), softwareId) + .ExecuteReader(x => new PruefmittelPruefung + { + PruefmittelId = x.GetInt(), + SoftwareId = x.GetSmallint(), + Pruefmittel = x.GetString(), + PruefmittelNr = x.GetString(), + Pruefintervall = x.GetInt(), + Erforderlich = x.GetBool(), + PruefdatumIst = x.GetDate(), + PruefdatumSoll = x.GetDate(), + Bemerkung = x.GetString(), + EmailAn = x.GetString(), + InCcAn = x.GetString(), + Betreff = x.GetString(), + Nachricht = x.GetString(), + Meldung = x.GetString(), + Schedule = x.GetString() + }); + + public int Remove(int pruefmittelId) + => this.sqlConnection + .CreateCommand($@" + DELETE + FROM [PruefmittelPruefung] + WHERE [PruefmittelId] = @{nameof(pruefmittelId)}") + .SetParameter(nameof(pruefmittelId), pruefmittelId) + .ExecuteNonQuery(); + + public IEnumerable SelectAll() + => this.sqlConnection + .CreateCommand(@" + SELECT [PruefmittelId] + , [SoftwareId] + , [Pruefmittel] + , [PruefmittelNr] + , [Pruefintervall] + , [Erforderlich] + , [PruefdatumIst] + , [PruefdatumSoll] + , [Bemerkung] + , [EmailAn] + , [InCcAn] + , [Betreff] + , [Nachricht] + , [Meldung] + , [Schedule] + FROM [PruefmittelPruefung]") + .ExecuteReader(x => new PruefmittelPruefung + { + PruefmittelId = x.GetInt(), + SoftwareId = x.GetSmallint(), + Pruefmittel = x.GetString(), + PruefmittelNr = x.GetString(), + Pruefintervall = x.GetInt(), + Erforderlich = x.GetBool(), + PruefdatumIst = x.GetDate(), + PruefdatumSoll = x.GetDate(), + Bemerkung = x.GetString(), + EmailAn = x.GetString(), + InCcAn = x.GetString(), + Betreff = x.GetString(), + Nachricht = x.GetString(), + Meldung = x.GetString(), + Schedule = x.GetString() + }); + + public int Update(PruefmittelPruefung model) + => this.sqlConnection + .CreateCommand($@" + UPDATE [PruefmittelPruefung] + SET [SoftwareId] = @{nameof(model.SoftwareId)} + , [Pruefmittel] = @{nameof(model.Pruefmittel)} + , [PruefmittelNr] = @{nameof(model.PruefmittelNr)} + , [Pruefintervall] = @{nameof(model.Pruefintervall)} + , [Erforderlich] = @{nameof(model.Erforderlich)} + , [PruefdatumIst] = @{nameof(model.PruefdatumIst)} + , [PruefdatumSoll] = @{nameof(model.PruefdatumSoll)} + , [Bemerkung] = @{nameof(model.Bemerkung)} + , [EmailAn] = @{nameof(model.EmailAn)} + , [InCcAn] = @{nameof(model.InCcAn)} + , [Betreff] = @{nameof(model.Betreff)} + , [Nachricht] = @{nameof(model.Nachricht)} + , [Meldung] = @{nameof(model.Meldung)} + , [Schedule] = @{nameof(model.Schedule)} + WHERE [PruefmittelId] = @{nameof(model.PruefmittelId)}") + .SetParameter(nameof(model.SoftwareId), model.SoftwareId) + .SetParameter(nameof(model.PruefmittelId), model.PruefmittelId) + .SetParameter(nameof(model.Pruefmittel), model.Pruefmittel) + .SetParameter(nameof(model.PruefmittelNr), model.PruefmittelNr) + .SetParameter(nameof(model.Pruefintervall), model.Pruefintervall) + .SetParameter(nameof(model.Erforderlich), model.Erforderlich) + .SetParameter(nameof(model.PruefdatumIst), model.PruefdatumIst) + .SetParameter(nameof(model.PruefdatumSoll), model.PruefdatumSoll) + .SetParameter(nameof(model.Bemerkung), model.Bemerkung) + .SetParameter(nameof(model.EmailAn), model.EmailAn) + .SetParameter(nameof(model.InCcAn), model.InCcAn) + .SetParameter(nameof(model.Betreff), model.Betreff) + .SetParameter(nameof(model.Nachricht), model.Nachricht) + .SetParameter(nameof(model.Meldung), model.Meldung) + .SetParameter(nameof(model.Schedule), model.Schedule) + .ExecuteNonQuery(); } } diff --git a/LaaProductionWeb/LaaProduction.Personalization/Repositories/Interfaces/IEquipmentsRepository.cs b/LaaProductionWeb/LaaProduction.Personalization/Repositories/Interfaces/IEquipmentsRepository.cs index 87518374..ce13a5fd 100644 --- a/LaaProductionWeb/LaaProduction.Personalization/Repositories/Interfaces/IEquipmentsRepository.cs +++ b/LaaProductionWeb/LaaProduction.Personalization/Repositories/Interfaces/IEquipmentsRepository.cs @@ -1,12 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LaaProduction.Personalization.Repositories.Interfaces +namespace LaaProduction.Personalization.Repositories.Interfaces { - internal interface IEquipmentsRepository + using LaaProduction.Personalization.Models; + + using System.Collections.Generic; + + public interface IEquipmentsRepository { + int Add(PruefmittelPruefung model); + + PruefmittelPruefung FindById(int pruefmittelId); + + int Remove(int pruefmittelId); + + IEnumerable SelectAll(); + + IEnumerable SelectAll(int softwareId); + + int Update(PruefmittelPruefung model); } } diff --git a/LaaProductionWeb/LaaProduction.Search/LaaProduction.Search.csproj b/LaaProductionWeb/LaaProduction.Search/LaaProduction.Search.csproj index fbae139a..5728f8e6 100644 --- a/LaaProductionWeb/LaaProduction.Search/LaaProduction.Search.csproj +++ b/LaaProductionWeb/LaaProduction.Search/LaaProduction.Search.csproj @@ -31,11 +31,11 @@ 4 - - ..\packages\LaaProductionDI.1.0.2\lib\netstandard2.0\LaaProductionDI.dll + + ..\packages\LaaProductionDI.1.0.4\lib\netstandard2.0\LaaProductionDI.dll - - ..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll + + ..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll ..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll @@ -52,8 +52,8 @@ ..\packages\System.Data.SqlClient.4.8.5\lib\net461\System.Data.SqlClient.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll diff --git a/LaaProductionWeb/LaaProduction.Services/LaaProduction.Services.csproj b/LaaProductionWeb/LaaProduction.Services/LaaProduction.Services.csproj index d420eeb9..1a936fe3 100644 --- a/LaaProductionWeb/LaaProduction.Services/LaaProduction.Services.csproj +++ b/LaaProductionWeb/LaaProduction.Services/LaaProduction.Services.csproj @@ -34,8 +34,8 @@ 4 - - ..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll + + ..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll False diff --git a/LaaProductionWeb/LaaProduction.Web/API/Personalization/SoftwareController.cs b/LaaProductionWeb/LaaProduction.Web/API/Personalization/SoftwareController.cs index 12c4d0d2..3c4ccb0c 100644 --- a/LaaProductionWeb/LaaProduction.Web/API/Personalization/SoftwareController.cs +++ b/LaaProductionWeb/LaaProduction.Web/API/Personalization/SoftwareController.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; + using System.Linq; using System.Web.Http; [AuthorizeBearer] @@ -14,9 +15,13 @@ public class SoftwareController : ApiController { private readonly ISoftwareManager softwareManager; + private readonly IEquipmentsManager equipmentsManager; public SoftwareController() - => this.softwareManager = LaaServiceProvider.GetService(); + { + this.softwareManager = LaaServiceProvider.GetService(); + this.equipmentsManager = LaaServiceProvider.GetService(); + } [HttpGet] [Route(nameof(Functions))] @@ -116,6 +121,17 @@ return this.Json(true); } + + [HttpGet] + public IHttpActionResult PendingInspections() + { + var softwareId = this.User.GetAppId(); + var pendingInspections = this.equipmentsManager + .SelectAll(softwareId) + .ToList(); + + return this.Json(pendingInspections); + } } public class EditFunctionModel diff --git a/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AllowedRolesAttribute.cs b/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AllowedRolesAttribute.cs index 6f331d8f..8411d5b9 100644 --- a/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AllowedRolesAttribute.cs +++ b/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AllowedRolesAttribute.cs @@ -22,6 +22,7 @@ controller.TempData["Unauthorized"] = $"Access denied: {filterContext.HttpContext.Request.Url}"; filterContext.Result = new RedirectResult("~/"); + filterContext.HttpContext.SetUrlReferer(); filterContext.Result.ExecuteResult(controller.ControllerContext); } else diff --git a/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/Appsettings.cs b/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/Appsettings.cs index 3f7a4eee..ffe2051f 100644 --- a/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/Appsettings.cs +++ b/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/Appsettings.cs @@ -16,5 +16,9 @@ public static string ConnectionString => ConfigurationManager.AppSettings.Get(nameof(ConnectionString)); public static int LoginTimeout => int.TryParse(ConfigurationManager.AppSettings.Get(nameof(LoginTimeout)), out int time) ? time : 0; + + public static string SMTPHost => ConfigurationManager.AppSettings.Get(nameof(SMTPHost)); + + public static int SMTPPort => int.TryParse(ConfigurationManager.AppSettings.Get(nameof(SMTPPort)), out int port) ? port : 587; } } \ No newline at end of file diff --git a/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AuthorizationFilter.cs b/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AuthorizationFilter.cs index 5a7bdbe1..363ec48c 100644 --- a/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AuthorizationFilter.cs +++ b/LaaProductionWeb/LaaProduction.Web/App_Infrastructure/AuthorizationFilter.cs @@ -1,9 +1,10 @@ namespace LaaProduction.Web.App_Infrastructure { using LaaProduction.Personalization.Interfaces; - using LaaProduction.Web.Controllers; using LaaProductionDI; + using System.Linq; + using IAuthorizationFilter = System.Web.Mvc.IAuthorizationFilter; using AuthorizationContext = System.Web.Mvc.AuthorizationContext; @@ -16,7 +17,24 @@ var accountManagement = LaaServiceProvider.GetService(); httpContext.User = accountManagement.GetClaimsPrincipal(sessionUser); - if (httpContext.User.Identity.IsAuthenticated && !httpContext.Request.Url.ToString().Contains(nameof(HomeController.Logout))) + var currentUrl = httpContext + .Request + .Url + .AbsolutePath + .Trim('/'); + var exludeUrl = new[] + { + string.Empty, + "Home", + "Home/Index", + "Home/Logout", + "LaaProductionWeb", + "LaaProductionWeb/Home", + "LaaProductionWeb/Home/Index", + "LaaProductionWeb/Home/Logout", + }; + + if (exludeUrl.All(x => x != currentUrl)) { httpContext.SetUrlReferer(); } diff --git a/LaaProductionWeb/LaaProduction.Web/Controllers/EquipmentsController.cs b/LaaProductionWeb/LaaProduction.Web/Controllers/EquipmentsController.cs index 6066517e..ed4011c4 100644 --- a/LaaProductionWeb/LaaProduction.Web/Controllers/EquipmentsController.cs +++ b/LaaProductionWeb/LaaProduction.Web/Controllers/EquipmentsController.cs @@ -2,9 +2,12 @@ { using LaaProduction.Personalization; using LaaProduction.Personalization.Interfaces; + using LaaProduction.Personalization.Models; using LaaProduction.Web.App_Infrastructure; using LaaProductionDI; + using Newtonsoft.Json; + using System.Collections.Generic; using System.Linq; using System.Web.Mvc; @@ -13,9 +16,13 @@ public class EquipmentsController : Controller { private readonly IEquipmentsManager equipmentsManager; + private readonly ISoftwareManager softwareManager; - public EquipmentsController() - => this.equipmentsManager = LaaServiceProvider.GetService(); + public EquipmentsController() + { + this.equipmentsManager = LaaServiceProvider.GetService(); + this.softwareManager = LaaServiceProvider.GetService(); + } [HttpGet] public ActionResult Index(int id = 0) @@ -60,16 +67,29 @@ return this.RedirectToAction(nameof(Index)); } + [HttpGet] + public ActionResult Set(int id = 0) + { + this.equipmentsManager.SetInspected(id); + + if (id == 0) + { + return this.RedirectToAction(nameof(Index)); + } + + return this.RedirectToAction(nameof(Index), new { id }); + } + public ActionResult Sidebar() { var model = this.equipmentsManager .SelectAll() - .OrderBy(x => x.Pruefstation) + .OrderBy(x => x.SoftwareId) .ThenBy(x => x.Pruefmittel) - .GroupBy(x => x.Pruefstation) + .GroupBy(x => x.SoftwareId) .Select(x => new Pruefstation { - Name = x.Key, + SoftwareId = x.Key, Pruefmittel = x .Select(y => new Pruefmittel { @@ -77,15 +97,66 @@ Nr = y.PruefmittelNr, Name = y.Pruefmittel, }) - }); + }) + .ToList(); + + var result = JsonConvert.SerializeObject(this.softwareManager.ListSoftwares()); + var softwareItems = JsonConvert + .DeserializeObject>(result) + .ToDictionary(x => x.SoftwareId, x => x.AssemblyName); + + foreach (var item in model) + { + if (softwareItems.ContainsKey(item.SoftwareId)) + { + item.AssemblyName = softwareItems[item.SoftwareId]; + } + } return this.PartialView(model); } + + public ActionResult Software(int selected) + { + var result = JsonConvert.SerializeObject(this.softwareManager.ListSoftwares()); + var softwareItems = JsonConvert.DeserializeObject>(result); + + foreach (var softwareItem in softwareItems) + { + softwareItem.Selected = softwareItem.Value == $"{selected}"; + } + + return this.PartialView(softwareItems); + } + } + + public class Software + { + public short SoftwareId { get; set; } + + public string AssemblyName { get; set; } + } + + public class SoftwareSelectListItem : SelectListItem + { + public short SoftwareId + { + get => short.TryParse(this.Value, out var value) ? value : (short)0; + set => this.Value = value.ToString(); + } + + public string AssemblyName + { + get => this.Text; + set => this.Text = value; + } } public class Pruefstation { - public string Name { get; set; } + public short SoftwareId { get; set; } + + public string AssemblyName { get; set; } public IEnumerable Pruefmittel { get; set; } } diff --git a/LaaProductionWeb/LaaProduction.Web/Global.asax.cs b/LaaProductionWeb/LaaProduction.Web/Global.asax.cs index 001bf54d..4947c04d 100644 --- a/LaaProductionWeb/LaaProduction.Web/Global.asax.cs +++ b/LaaProductionWeb/LaaProduction.Web/Global.asax.cs @@ -7,6 +7,7 @@ using LaaProduction.Web.App_Infrastructure; using LaaProductionDI; using LaaProductionHttp; + using LaaProductionSMTP; using LaaProductionSQL; using System.Web; @@ -32,6 +33,7 @@ => services .AddSingleton(SQLConnection.CreateSQLConnection(Appsettings.ConnectionString, this.SQLErrorHandler)) .AddSingleton(HttpClient.CreateHttpClient(Appsettings.APIURL, Appsettings.APIPrefix)) + .AddSingleton(SMTPClient.CreateSMTPClient(Appsettings.SMTPHost, Appsettings.SMTPPort, this.SMTPErrorHandler)) .AddScoped() .AddScoped() .AddScoped() @@ -42,7 +44,12 @@ private void SQLErrorHandler(string error) { + // TODO: error logging. + } + private void SMTPErrorHandler(string error) + { + // TODO: error logging. } } } diff --git a/LaaProductionWeb/LaaProduction.Web/LaaProduction.Web.csproj b/LaaProductionWeb/LaaProduction.Web/LaaProduction.Web.csproj index 97ffb3bd..8de6e337 100644 --- a/LaaProductionWeb/LaaProduction.Web/LaaProduction.Web.csproj +++ b/LaaProductionWeb/LaaProduction.Web/LaaProduction.Web.csproj @@ -44,14 +44,17 @@ 4 - - ..\packages\LaaProductionDI.1.0.2\lib\netstandard2.0\LaaProductionDI.dll + + ..\packages\LaaProductionDI.1.0.4\lib\netstandard2.0\LaaProductionDI.dll - - ..\packages\LaaProductionHttp.1.0.2\lib\netstandard2.0\LaaProductionHttp.dll + + ..\packages\LaaProductionHttp.1.0.4\lib\netstandard2.0\LaaProductionHttp.dll - - ..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll + + ..\packages\LaaProductionSMTP.1.0.4\lib\netstandard2.0\LaaProductionSMTP.dll + + + ..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll ..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll @@ -86,12 +89,9 @@ ..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll True - - ..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll - ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll @@ -212,7 +212,9 @@ - + + Designer + @@ -267,6 +269,7 @@ + diff --git a/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Index.cshtml b/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Index.cshtml index 94ab6dfb..e79d1d3d 100644 --- a/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Index.cshtml +++ b/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Index.cshtml @@ -1,9 +1,10 @@ @model PruefmittelPruefung @using LaaProduction.Personalization +@using LaaProduction.Personalization.Models @using LaaProduction.Web.Controllers -@{ +@{ var @class = "form-control"; var dateFormat = "{0:yyyy-MM-dd}"; var exists = this.Model.PruefmittelId > 0; @@ -24,10 +25,10 @@ @this.Html.HiddenFor(x => x.PruefmittelId) - + @@ -120,7 +121,7 @@
@this.Html.LabelFor(x => x.Pruefstation)@this.Html.LabelFor(x => x.SoftwareId) - @this.Html.TextBoxFor(x => x.Pruefstation, new { @class }) - @this.Html.ValidationMessageFor(x => x.Pruefstation, string.Empty) + @{this.Html.RenderAction(nameof(EquipmentsController.Software), new { selected = this.Model.SoftwareId });} + @this.Html.ValidationMessageFor(x => x.SoftwareId, string.Empty)
@this.Html.CheckBoxFor(x => x.Erforderlich, new { @class = "form-check-input" }) - @this.Html.LabelFor(x => x.Erforderlich, new { @class= "form-check-label" }) + @this.Html.LabelFor(x => x.Erforderlich, new { @class = "form-check-label" })
@@ -130,6 +131,9 @@ @if (exists) { + + Geprüft setzen + Löschen diff --git a/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Sidebar.cshtml b/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Sidebar.cshtml index 26d45448..432c5602 100644 --- a/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Sidebar.cshtml +++ b/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Sidebar.cshtml @@ -8,7 +8,7 @@ @foreach (var pruefstation in this.Model) {
  • - @pruefstation.Name + @pruefstation.AssemblyName
      @foreach (var pruefmittel in pruefstation.Pruefmittel) { diff --git a/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Software.cshtml b/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Software.cshtml new file mode 100644 index 00000000..a7d97039 --- /dev/null +++ b/LaaProductionWeb/LaaProduction.Web/Views/Equipments/Software.cshtml @@ -0,0 +1,5 @@ +@model IEnumerable + +@using LaaProduction.Web.Controllers + +@this.Html.DropDownList("SoftwareId", this.Model, "Pruefsoftware auswählen", new { @class = "form-control" })