This commit is contained in:
Stoyan Zlatev 2023-08-16 16:11:41 +02:00
parent bdb04b61f3
commit 0b9f899993
31 changed files with 1057 additions and 422 deletions

View File

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

View File

@ -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<Error>(responseContent);
}
else
{
this.bearer = JsonConvert.DeserializeObject<string>(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<Error>(responseContent);
}
else
{
var pendingInspections = JsonConvert.DeserializeObject<IEnumerable<Equipment>>(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;
}
}
}

View File

@ -0,0 +1,42 @@
namespace LaaProduction
{
using System.Collections.Generic;
using System.Runtime.InteropServices;
[ClassInterface(ClassInterfaceType.AutoDual)]
public class EquipmentsResult
{
private readonly Queue<Equipment> equipments = new Queue<Equipment>();
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<Equipment> equipments)
{
if (equipments is null)
{
return;
}
foreach (var e in equipments)
{
this.equipments.Enqueue(e);
}
}
}
}

View File

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

View File

@ -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<ValidationResult>();
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;
}
}
}

View File

@ -12,15 +12,17 @@
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\..\..\..\..\..\..\Temp\drueckpruefung\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RegisterForComInterop>false</RegisterForComInterop>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -30,27 +32,38 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>LaaProduction_SigningKey.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="LaaProductionHttp, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionHttp.1.0.0\lib\netstandard2.0\LaaProductionHttp.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Pruefstation.cs" />
<Compile Include="Equipment.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="LoginModel.cs" />
<Compile Include="EquipmentsResult.cs" />
<Compile Include="Programm.cs" />
<Compile Include="Equipments.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Error.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="LaaProduction_SigningKey.pfx" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

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

View File

@ -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);
// }
//}
}

View File

@ -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")]

View File

@ -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<Equipment> 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<string>();
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; }
}
}
}

View File

@ -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);

View File

@ -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<DisplayAttribute>()
?.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,
}
}

View File

@ -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<PruefmittelPruefung> 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<PruefmittelPruefung> SelectAll()
=> this.equipments.SelectAll();
public IEnumerable<PruefmittelPruefung> 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<int>();
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);
}
}

View File

@ -1,5 +1,7 @@
namespace LaaProduction.Personalization.Interfaces
{
using LaaProduction.Personalization.Models;
using System.Collections.Generic;
public interface IEquipmentsManager
@ -12,6 +14,10 @@
IEnumerable<PruefmittelPruefung> SelectAll();
IEnumerable<PruefmittelPruefung> SelectAll(int softwareId);
void SetInspected(int pruefmittelId);
int Update(PruefmittelPruefung model);
}
}

View File

@ -31,11 +31,17 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="LaaProductionDI, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionDI.1.0.2\lib\netstandard2.0\LaaProductionDI.dll</HintPath>
<Reference Include="LaaProductionDI, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionDI.1.0.4\lib\netstandard2.0\LaaProductionDI.dll</HintPath>
</Reference>
<Reference Include="LaaProductionSQL, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
<Reference Include="LaaProductionSMTP, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSMTP.1.0.4\lib\netstandard2.0\LaaProductionSMTP.dll</HintPath>
</Reference>
<Reference Include="LaaProductionSQL, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
</Reference>
<Reference Include="MailKit, Version=4.1.0.0, Culture=neutral, PublicKeyToken=4e064fe7c44a8f1b, processorArchitecture=MSIL">
<HintPath>..\packages\MailKit.4.1.0\lib\net48\MailKit.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
@ -46,18 +52,24 @@
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="MimeKit, Version=4.1.0.0, Culture=neutral, PublicKeyToken=bede1c8a46c66814, processorArchitecture=MSIL">
<HintPath>..\packages\MimeKit.4.1.0\lib\net48\MimeKit.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data.SqlClient, Version=4.6.1.5, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SqlClient.4.8.5\lib\net461\System.Data.SqlClient.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Security" />
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
@ -65,6 +77,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AccountManager.cs" />
<Compile Include="ComponentModel.DataAnnotations\DateTimeAttribute.cs" />
<Compile Include="EmployeesManager.cs" />
<Compile Include="EquipmentsManager.cs" />
<Compile Include="Interfaces\IEmployeesManager.cs" />
@ -82,6 +95,7 @@
<Compile Include="Interfaces\IAccountManager.cs" />
<Compile Include="Models\Employee.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Models\PruefmittelPruefung.cs" />
<Compile Include="Repositories\EmployeesRepository.cs" />
<Compile Include="Repositories\EquipmentsRepository.cs" />
<Compile Include="Repositories\FunctionsRepository.cs" />

View File

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

View File

@ -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]);

View File

@ -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<PruefmittelPruefung> 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<PruefmittelPruefung> 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();
}
}

View File

@ -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<PruefmittelPruefung> SelectAll();
IEnumerable<PruefmittelPruefung> SelectAll(int softwareId);
int Update(PruefmittelPruefung model);
}
}

View File

@ -31,11 +31,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="LaaProductionDI, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionDI.1.0.2\lib\netstandard2.0\LaaProductionDI.dll</HintPath>
<Reference Include="LaaProductionDI, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionDI.1.0.4\lib\netstandard2.0\LaaProductionDI.dll</HintPath>
</Reference>
<Reference Include="LaaProductionSQL, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
<Reference Include="LaaProductionSQL, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
@ -52,8 +52,8 @@
<Reference Include="System.Data.SqlClient, Version=4.6.1.5, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SqlClient.4.8.5\lib\net461\System.Data.SqlClient.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>

View File

@ -34,8 +34,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="LaaProductionSQL, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
<Reference Include="LaaProductionSQL, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>

View File

@ -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<ISoftwareManager>();
{
this.softwareManager = LaaServiceProvider.GetService<ISoftwareManager>();
this.equipmentsManager = LaaServiceProvider.GetService<IEquipmentsManager>();
}
[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

View File

@ -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

View File

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

View File

@ -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<IAccountManager>();
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();
}

View File

@ -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<IEquipmentsManager>();
public EquipmentsController()
{
this.equipmentsManager = LaaServiceProvider.GetService<IEquipmentsManager>();
this.softwareManager = LaaServiceProvider.GetService<ISoftwareManager>();
}
[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<IEnumerable<Software>>(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<IEnumerable<SoftwareSelectListItem>>(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> Pruefmittel { get; set; }
}

View File

@ -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<IApprovalsService, ApprovalsService>()
.AddScoped<IOrdersService, OrdersService>()
.AddScoped<IProtocolService, ProtocolService>()
@ -42,7 +44,12 @@
private void SQLErrorHandler(string error)
{
// TODO: error logging.
}
private void SMTPErrorHandler(string error)
{
// TODO: error logging.
}
}
}

View File

@ -44,14 +44,17 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="LaaProductionDI, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionDI.1.0.2\lib\netstandard2.0\LaaProductionDI.dll</HintPath>
<Reference Include="LaaProductionDI, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionDI.1.0.4\lib\netstandard2.0\LaaProductionDI.dll</HintPath>
</Reference>
<Reference Include="LaaProductionHttp, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionHttp.1.0.2\lib\netstandard2.0\LaaProductionHttp.dll</HintPath>
<Reference Include="LaaProductionHttp, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionHttp.1.0.4\lib\netstandard2.0\LaaProductionHttp.dll</HintPath>
</Reference>
<Reference Include="LaaProductionSQL, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.3\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
<Reference Include="LaaProductionSMTP, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSMTP.1.0.4\lib\netstandard2.0\LaaProductionSMTP.dll</HintPath>
</Reference>
<Reference Include="LaaProductionSQL, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LaaProductionSQL.1.0.4\lib\netstandard2.0\LaaProductionSQL.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
@ -86,12 +89,9 @@
<HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Security.Principal.Windows, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
@ -212,7 +212,9 @@
<Content Include="favicon.ico" />
<Content Include="favicon.svg" />
<Content Include="Global.asax" />
<Content Include="web.config" />
<Content Include="web.config">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<ItemGroup />
<ItemGroup>
@ -267,6 +269,7 @@
<Content Include="Views\Equipments\Index.cshtml" />
<Content Include="Views\Equipments\Sidebar.cshtml" />
<Content Include="Views\Shared\_EmptyLayout.cshtml" />
<Content Include="Views\Equipments\Software.cshtml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LaaProduction.Personalization\LaaProduction.Personalization.csproj">

View File

@ -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)
<table class="table mt-1">
<tr>
<td class="w-auto white-space-nowrap opacity-50">@this.Html.LabelFor(x => x.Pruefstation)</td>
<td class="w-auto white-space-nowrap opacity-50">@this.Html.LabelFor(x => x.SoftwareId)</td>
<td class="w-100 py-1 position-relative">
@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)
</td>
</tr>
<tr>
@ -120,7 +121,7 @@
</table>
<div class="form-check my-3 ms-2">
@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" })
</div>
</div>
<div class="col-12">
@ -130,6 +131,9 @@
</button>
@if (exists)
{
<a class="btn btn-outline-primary px-5 me-3" href="~/Equipments/Set/@this.Model.PruefmittelId">
<i class="bi bi-check"></i> Geprüft setzen
</a>
<a class="btn btn-outline-danger px-5 me-3" href="~/Equipments/Remove/@this.Model.PruefmittelId">
<i class="bi bi-trash smaller"></i> Löschen
</a>

View File

@ -8,7 +8,7 @@
@foreach (var pruefstation in this.Model)
{
<li class="list-group-item pc">
@pruefstation.Name
@pruefstation.AssemblyName
<ul class="list-group list-group-sidebar ms-4">
@foreach (var pruefmittel in pruefstation.Pruefmittel)
{

View File

@ -0,0 +1,5 @@
@model IEnumerable<SoftwareSelectListItem>
@using LaaProduction.Web.Controllers
@this.Html.DropDownList("SoftwareId", this.Model, "Pruefsoftware auswählen", new { @class = "form-control" })