PUNE protokol changes

This commit is contained in:
Stoyan Zlatev 2023-08-08 11:11:16 +02:00
parent f046924d4b
commit c44b7eef93
36 changed files with 412 additions and 788 deletions

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FD30EB7A-7809-4E62-9374-791D31877D6D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LaaProduction</RootNamespace>
<AssemblyName>LaaProduction</AssemblyName>
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</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.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="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,36 @@
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")]

View File

@ -0,0 +1,95 @@
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;
}
}
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

@ -13,7 +13,6 @@ using System.Data.SqlClient;
namespace ProductionService
{
public partial class CordonelMetersFinalCheck : ServiceBase
{
private Timer timer;
@ -47,7 +46,6 @@ namespace ProductionService
SqlCommand command = new SqlCommand("SELECT COUNT(*) FROM MyTable", sqlConnection);
int count = (int)command.ExecuteScalar();
// Do something with the count here
}
}
}

View File

@ -14,8 +14,8 @@
public class AccountManager : IAccountManager
{
private static IIdentity anonymous
=> new ClaimsIdentity(
private static readonly IIdentity anonymous
= new ClaimsIdentity(
claims: Array.Empty<Claim>(),
authenticationType: string.Empty,
nameType: string.Empty,
@ -30,26 +30,6 @@
this.softwareRepository = LaaServiceProvider.GetService<ISoftwareRepository>();
}
public string GetAuthToken(string username, string password, string software)
{
var userId = this.employeesRepository.EmployeeId(username, password);
var token = default(string);
if (userId > 0)
{
var appId = this.softwareRepository.AppId(software);
if (appId > 0)
{
this.employeesRepository.CreateToken(appId, userId);
token = this.employeesRepository.GetToken(appId, userId);
}
}
return token;
}
public IPrincipal GetClaimsPrincipal(string token)
{
var claimsIdentity = anonymous;
@ -137,9 +117,7 @@
return default(string);
}
this.employeesRepository.CreateToken(softwareId, employeeNr);
return this.employeesRepository.GetToken(softwareId, employeeNr);
return this.GetÓrCreateAuthToken(softwareId, employeeNr);
}
public string Login(UserLoginModel model)
@ -162,9 +140,7 @@
return default(string);
}
this.employeesRepository.CreateToken(softwareId, employeeNr);
return this.employeesRepository.GetToken(softwareId, employeeNr);
return this.GetÓrCreateAuthToken(softwareId, employeeNr);
}
public void ResetPassword(short employeeId)
@ -178,7 +154,7 @@
private short GetOrCreateSoftwareId(string assembly, int major, int minor, int build)
{
var softwareId = this.softwareRepository.SoftwareId(assembly, major, minor, build);
var softwareId = this.softwareRepository.SoftwareId(assembly);
if (softwareId <= 0)
{
@ -187,5 +163,19 @@
return softwareId;
}
public string GetÓrCreateAuthToken(short appId, short userId)
{
var token = default(string);
if (appId > 0 && userId > 0)
{
this.employeesRepository.CreateToken(appId, userId);
token = this.employeesRepository.GetToken(appId, userId);
}
return token;
}
}
}

View File

@ -1,4 +1,3 @@
namespace LaaProduction.Personalization
{
public enum EmployeesRoles

View File

@ -0,0 +1,8 @@
namespace LaaProduction.Personalization
{
using LaaProduction.Personalization.Interfaces;
public class EquipmentsManager : IEquipmentsManager
{
}
}

View File

@ -6,8 +6,6 @@
public interface IAccountManager
{
string GetAuthToken(string username, string password, string software);
IPrincipal GetClaimsPrincipal(string token);
string Login(ADLoginModel model);

View File

@ -0,0 +1,6 @@
namespace LaaProduction.Personalization.Interfaces
{
public interface IEquipmentsManager
{
}
}

View File

@ -47,7 +47,9 @@
<ItemGroup>
<Compile Include="AccountManager.cs" />
<Compile Include="EmployeesManager.cs" />
<Compile Include="EquipmentsManager.cs" />
<Compile Include="Interfaces\IEmployeesManager.cs" />
<Compile Include="Interfaces\IEquipmentsManager.cs" />
<Compile Include="Interfaces\ISoftwareManager.cs" />
<Compile Include="Models\EmployeeToken.cs" />
<Compile Include="Models\EmployeeFunction.cs" />
@ -62,8 +64,10 @@
<Compile Include="Models\Employee.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Repositories\EmployeesRepository.cs" />
<Compile Include="Repositories\EquipmentsRepository.cs" />
<Compile Include="Repositories\FunctionsRepository.cs" />
<Compile Include="Repositories\Interfaces\IEmployeesRepository.cs" />
<Compile Include="Repositories\Interfaces\IEquipmentsRepository.cs" />
<Compile Include="Repositories\Interfaces\IFunctionsRepository.cs" />
<Compile Include="Repositories\Interfaces\IRolesRepository.cs" />
<Compile Include="Repositories\Interfaces\ISoftwareRepository.cs" />

View File

@ -10,12 +10,13 @@
public static LaaServiceCollection AddAdministration(this LaaServiceCollection services)
=> services
.AddScoped<IEmployeesRepository, EmployeesRepository>()
.AddScoped<IEquipmentsRepository, EquipmentsRepository>()
.AddScoped<IFunctionsRepository, FunctionsRepository>()
.AddScoped<IRolesRepository, RolesRepository>()
.AddScoped<ISoftwareRepository, SoftwareRepository>()
.AddScoped<IAccountManager, AccountManager>()
.AddScoped<IEmployeesManager, EmployeesManager>()
.AddScoped<IEquipmentsManager, EquipmentsManager>()
.AddScoped<ISoftwareManager, SoftwareManager>();
}
}

View File

@ -7,4 +7,36 @@
[Auftrag].[dbo].[SoftwareFunctions]
[Auftrag].[dbo].[SoftwareFunctionsLog]
[Auftrag].[dbo].[UsersFunctions]
[Auftrag].[dbo].[VersionSoftwareAccess]
[Auftrag].[dbo].[VersionSoftwareAccess]
CREATE TABLE [PruefmittelPruefung] ( -- Automatisiert die pruefmittel pruefung benachrichtigung
[PruefmittelId] INT PRIMARY KEY NOT NULL IDENTITY(1, 1), -- Pruefmittel Id
[Pruefstation] VARCHAR(100) NOT NULL, -- Pruefstation bezeichnung
[Pruefmittel] VARCHAR(100) NOT NULL, -- Pruefmittel - anlage, referenzzähler, wage etc.
[PruefmittelNr] VARCHAR(30) NOT NULL, -- Eindeutige pruefmittel nummer
[Pruefabstand] INT NOT NULL, -- Die zeit (Tagen) nach die pruefmittel sollen wieder geprueft werden
[Erforderlich] BIT NOT NULL DEFAULT(0), -- Is die pruefung staatlich erforderlich
[PruefdatumIst] DATETIME NULL, -- Letzte pruefdatumg
[PruefdatumSoll] DATETIME NULL, -- Nexte pruefdatum - automatisch generiert aus letzte pruefdatum und die zeit bis nexte pruefung
[PruefdatumWird] DATETIME NULL, -- Geplanter Prüfungstermin. Wenn Gesetz, werden keine E-Mails mehr gesendet
[Geprueft] BIT NOT NULL DEFAULT(0), -- Die pruefergebniss geprueft oder nicht
[Bezeichnung] NVARCHAR(250) NULL
);
CREATE UNIQUE INDEX [UX_PruefmittelPruefung]
ON [PruefmittelPruefung] (
[Pruefstation]
, [PruefmittelNr]);
CREATE TABLE [PruefmittelPruefer] ( -- verantwortliche für prüfmittelprüfung
[PruefmittelId] INT NOT NULL, -- welche prüfmittel
[PrueferEmail] VARCHAR(250) NOT NULL, -- an welche prüefer/leiter/verantwortlicher email
[Subject] NVARCHAR(250) NOT NULL, -- nachricht bezeichnung
[Body] NVARCHAR(250) NOT NULL, -- nachricht inhalt
[Begin] INT NOT NULL DEFAULT (14) -- ab wann soll der E-Mail verschickt werden beispiel : 14-er tag than -> 7, 3, 1 vor dem prüfungs ablauf
);
CREATE UNIQUE INDEX [UX_PruefmittelPruefer]
ON [PruefmittelPruefer] (
[PruefmittelId]
, [PrueferEmail]);

View File

@ -0,0 +1,8 @@
namespace LaaProduction.Personalization.Repositories
{
using LaaProduction.Personalization.Repositories.Interfaces;
internal class EquipmentsRepository : IEquipmentsRepository
{
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LaaProduction.Personalization.Repositories.Interfaces
{
internal interface IEquipmentsRepository
{
}
}

View File

@ -25,7 +25,7 @@
IEnumerable<SoftwareItem> List();
short SoftwareId(string assembly, int major, int minor, int build);
short SoftwareId(string assembly);
IEnumerable<SoftwareVersion> Versions(short softwareId);
}

View File

@ -182,20 +182,13 @@
Description = x.GetString(),
});
public short SoftwareId(string assembly, int major, int minor, int build)
public short SoftwareId(string assembly)
=> this.sqlConnection
.CreateCommand($@"
SELECT [AppId]
FROM [VersionSoftwareAccess]
WHERE [SoftwareAccess_Program] = @{nameof(assembly)}
AND [SoftwareAccess_MajorVersion] = @{nameof(major)}
AND [SoftwareAccess_MinorVersion] = @{nameof(minor)}
AND [SoftwareAccess_BuildVersion] = @{nameof(build)}
AND [SoftwareAccess_VaildTo] > GETDATE()")
WHERE [SoftwareAccess_Program] = @{nameof(assembly)}")
.SetParameter(nameof(assembly), assembly)
.SetParameter(nameof(major), major)
.SetParameter(nameof(minor), minor)
.SetParameter(nameof(build), build)
.FirstOrDefault(x => x.GetSmallint());
public IEnumerable<SoftwareVersion> Versions(short softwareId)

View File

@ -1,9 +0,0 @@
namespace LaaProduction.Services.Interfaces
{
using System;
public interface ILoggerService
{
void Log(Action<LoggerService.LogModel> logModel);
}
}

View File

@ -1,13 +0,0 @@
namespace LaaProduction.Services.Interfaces
{
using LaaProduction.Services.Models;
using System.Collections.Generic;
public interface ISearchService
{
IEnumerable<WildcardResult> Find(WildcardInputModel model);
IEnumerable<string> Options();
}
}

View File

@ -1,42 +0,0 @@
namespace LaaProduction.Services.Interfaces
{
using LaaProduction.Services.Models.Software;
using System;
using System.Collections.Generic;
public interface ISoftwareService
{
void AddFunction(short appId, string name);
void DeleteFunction(int funcId);
short FindAndUpdateSoftware(string windowsUser, string software, IEnumerable<string> functions);
IEnumerable<SoftwareFunction> GetAllSoftwareFunctions();
IEnumerable<SoftwareFunction> GetSoftwareFunctions(short appId);
IEnumerable<string> GetSoftwareFunctions(short appId, short userId);
SoftwareOverview GetSoftwareOverview(short appId);
IEnumerable<Software> GetSoftwareVersions(short appId);
IEnumerable<SoftwareOverview> GetSoftwares();
IEnumerable<SoftwareUser> GetUsers(string username = null);
IEnumerable<SoftwareUser> GetUsersWithFunctions(int id = -1, string username = null);
int ResetPassword(short userId);
int ResetPassword(short userId, string password);
void UpdateFunction(int funcId, string name);
void UpdateUsersFunctions(Action<UserFunctions> mapper);
void UpdateUsersFunctions(Action<FunctionUsers> mapper);
void UpdatePasswordHashes();
}
}

View File

@ -55,14 +55,10 @@
<Compile Include="Interfaces\IAccountService.cs" />
<Compile Include="Interfaces\IApprovalsService.cs" />
<Compile Include="Interfaces\IHttpService.cs" />
<Compile Include="Interfaces\ILoggerService.cs" />
<Compile Include="Interfaces\IOrdersService.cs" />
<Compile Include="Interfaces\IProtocolService.cs" />
<Compile Include="Interfaces\IReportService.cs" />
<Compile Include="Interfaces\ISearchService.cs" />
<Compile Include="Interfaces\IShipmentsService.cs" />
<Compile Include="Interfaces\ISoftwareService.cs" />
<Compile Include="LoggerService.cs" />
<Compile Include="Models\Employee.cs" />
<Compile Include="Models\HttpResponseModel.cs" />
<Compile Include="Models\MissingItem.cs" />
@ -110,9 +106,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProtocolService.cs" />
<Compile Include="ReportService.cs" />
<Compile Include="SearchService.cs" />
<Compile Include="ShipmentsService.cs" />
<Compile Include="SoftwareService.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

View File

@ -1,54 +0,0 @@
namespace LaaProduction.Services
{
using LaaProductionSQL.Interfaces;
using LaaProduction.Services.Interfaces;
using System;
public class LoggerService : ILoggerService
{
private readonly ISQLConnection sqlConnection;
public LoggerService(ISQLConnection sqlConnection)
=> this.sqlConnection = sqlConnection;
public class Actions
{
public const string RUN = nameof(RUN);
}
public class LogModel
{
public long Id { get; internal set; }
public DateTime Date { get; internal set; }
= DateTime.Now;
public string User { get; set; }
public string Action { get; set; }
public string Data { get; set; }
}
public void Log(Action<LogModel> logModel)
{
var model = new LogModel();
logModel?.Invoke(model);
this.sqlConnection
.CreateCommand($@"
INSERT INTO [SoftwareFunctionsLog] (
[User]
, [Action]
, [Data])
VALUES (@{nameof(model.User)}
, @{nameof(model.Action)}
, @{nameof(model.Data)})")
.SetParameter(nameof(model.User), model.User)
.SetParameter(nameof(model.Action), model.Action)
.SetParameter(nameof(model.Data), model.Data)
.ExecuteNonQuery();
}
}
}

View File

@ -1,129 +0,0 @@
namespace LaaProduction.Services
{
using LaaProductionSQL.Interfaces;
using LaaProduction.Services.Models;
using LaaProduction.Services.Interfaces;
using System.Collections.Generic;
public class SearchService : ISearchService
{
private readonly ISQLConnection sqlConnection;
public SearchService(ISQLConnection sqlConnection)
=> this.sqlConnection = sqlConnection;
public IEnumerable<WildcardResult> Find(WildcardInputModel model)
{
var requiredFields = model.GetRequiredFields(this.Options());
var ordersFound = sqlConnection
.CreateCommand($@"
DECLARE @serienNr TABLE([Nr] VARCHAR(50));
-----------------------------------------------------------------------------
-- 1. LOOK FOR SERIAL NUMBER ------------------------------------------------
-----------------------------------------------------------------------------
INSERT INTO @serienNr
SELECT [APS].[SerienNr]
FROM [AuftragPositionSerienNr] AS [APS]
WHERE [APS].[SerienNr] LIKE @{nameof(model.Token)}
OR REPLACE([APS].[KundeneigeneSerienNr], ' ', '') LIKE @{nameof(model.Token)};
-----------------------------------------------------------------------------
-- 2. LOOK FOR PCB NUMBER ---------------------------------------------------
-----------------------------------------------------------------------------
INSERT INTO @serienNr
SELECT [PCBS].[MapPcbIdToSerialNumber_SerialNumber]
FROM [MapPcbIdToSerialNumber] AS [PCBS]
WHERE [PCBS].[MapPcbIdToSerialNumber_PcbId] LIKE @{nameof(model.Token)};
-----------------------------------------------------------------------------
-- 3. LOOK FOR FUNK ADDRESS E-REGISTER --------------------------------------
-----------------------------------------------------------------------------
INSERT INTO @serienNr
SELECT [ER].[Seriennummer]
FROM [eRegister] AS [ER]
WHERE [ER].[Adresse] LIKE @{nameof(model.Token)};
-----------------------------------------------------------------------------
-- 4. LOOK FOR FUNK ADDRESS GENESIS -----------------------------------------
-----------------------------------------------------------------------------
INSERT INTO @serienNr
SELECT [GM].[Seriennummer]
FROM [Genesis_Meter] AS [GM]
WHERE [GM].[Adresse] LIKE @{nameof(model.Token)};
-----------------------------------------------------------------------------
-- 5. TAKE ORDERS INFO ------------------------------------------------------
-----------------------------------------------------------------------------
SELECT DISTINCT
[KN].[KundenNr] AS [CustomerNo]
, [KN].[Name] AS [Customer]
, [AP].[FertigungsauftragNr] AS [ProductionOrderNo]
, [APS].[AuftragNr] AS [CustomerOrderNo]
, [APS].[PositionNr] AS [PosNo]
, [APS].[SerienNr] AS [SerialNo]
, [APS].[KundeneigeneSerienNr] AS [CustomerSerialNo]
, [IDN].[KurzBez] AS [KurzBez]
, [IDN].[Typ] AS [Typ]
, [IDN].[Nennweite] AS [Nennweite]
, [IDN].[Baulaenge] AS [Baulaenge]
, [AP].[Menge] AS [Quantity]
, [APS].[FabNr] AS [FabricNo]
, [IDN].[IdentNr] AS [IdentNr]
, [PCBS].[MapPcbIdToSerialNumber_PcbId] AS [PcbId]
, [ER].[Adresse] AS [ErRadioAddress]
, [GM].[Adresse] AS [GmRadioAddress]
FROM [AuftragPositionSerienNr] AS [APS]
LEFT JOIN [AuftragPosition_Gesamt] AS [AP]
ON [AP].[AuftragNr] = [APS].[AuftragNr]
AND [AP].[PositionNr] = [APS].[PositionNr]
LEFT JOIN [Auftrag_Gesamt] AS [AG]
ON [AG].[AuftragNr] = [APS].[AuftragNr]
LEFT JOIN [Kunde] AS [KN]
ON [KN].[KundenNr] = [AG].[KundenNr]
LEFT JOIN [Identnr] AS [IDN]
ON [IDN].[IdentNr] = [AP].[Identnr]
LEFT JOIN [MapPcbIdToSerialNumber] AS [PCBS]
ON [PCBS].[MapPcbIdToSerialNumber_SerialNumber] = [APS].[SerienNr]
LEFT JOIN [eRegister] AS [ER]
ON [ER].[Seriennummer] = [APS].[SerienNr]
LEFT JOIN [Genesis_Meter] AS [GM]
ON [GM].[Seriennummer] = [APS].[SerienNr]
WHERE [APS].[SerienNr] IN (SELECT [Nr] FROM @serienNr)")
.SetParameter(nameof(model.Token), $"%{model.Token}%")
.ExecuteReader(reader => this.ToWildcardResult(reader, requiredFields));
return ordersFound;
}
public IEnumerable<string> Options()
=> new string[]
{
"CustomerNo",
"Customer",
"ProductionOrderNo",
"CustomerOrderNo",
"PosNo",
"SerialNo",
"CustomerSerialNo",
"KurzBez",
"Typ",
"Nennweite",
"Baulaenge",
"Quantity",
"FabricNo",
"IdentNr",
"PcbId",
"ErRadioAddress",
"GmRadioAddress",
};
internal WildcardResult ToWildcardResult(ISQLReader reader, IEnumerable<string> fields)
{
var wildcardResult = new WildcardResult();
foreach (var field in fields)
{
wildcardResult[field] = reader.GetValue(field);
}
return wildcardResult;
}
}
}

View File

@ -1,393 +0,0 @@
namespace LaaProduction.Services
{
using LaaProductionSQL.Interfaces;
using LaaProduction.Services.Interfaces;
using LaaProduction.Services.Models.Software;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
public class SoftwareService : ISoftwareService
{
private readonly ISQLConnection sqlConnection;
public SoftwareService(ISQLConnection sqlConnection)
=> this.sqlConnection = sqlConnection;
public void AddFunction(short appId, string name)
=> this.sqlConnection
.CreateCommand($@"
INSERT INTO [SoftwareFunctions] (
[AppId]
, [Function])
VALUES (@{nameof(appId)}
, @{nameof(name)})")
.SetParameter(nameof(appId), appId)
.SetParameter(nameof(name), name)
.ExecuteNonQuery();
public int ApplicationId(string name)
=> this.sqlConnection
.CreateCommand($@"
SELECT TOP 1 [AppId]
FROM [VersionSoftwareAccess]
WHERE [SoftwareAccess_Program] = @{nameof(name)}")
.SetParameter(nameof(name), name)
.FirstOrDefault(x => x.GetSmallint());
public void DeleteFunction(int funcId)
{
this.sqlConnection
.CreateCommand($@"
DELETE FROM [SoftwareFunctions]
WHERE [Id] = @{nameof(funcId)}")
.SetParameter(nameof(funcId), funcId)
.ExecuteNonQuery();
this.sqlConnection
.CreateCommand($@"
DELETE FROM [UsersFunctions]
WHERE [SoftwareFunctionId] = @{nameof(funcId)}")
.SetParameter(nameof(funcId), funcId)
.ExecuteNonQuery();
}
public short FindAndUpdateSoftware(string windowsUser, string name, IEnumerable<string> functions)
{
var appId = this.sqlConnection
.CreateCommand($@"
SELECT TOP 1 [AppId]
, MAX([SoftwareAccess_VaildTo]) OVER (PARTITION BY [AppId])
FROM [VersionSoftwareAccess]
WHERE [SoftwareAccess_Program] = @{nameof(name)}
AND [SoftwareAccess_VaildTo] > GETDATE()")
.SetParameter(nameof(name), name)
.FirstOrDefault(x => x.GetSmallint());
if (appId > 0)
{
if (functions != null && functions.Any())
{
foreach (var function in functions)
{
if (Regex.IsMatch(function, "[a-zA-Z_]+"))
{
this.AddFunction(appId, function);
}
}
}
}
return appId;
}
public IEnumerable<SoftwareFunction> GetAllSoftwareFunctions()
=> this.sqlConnection
.CreateCommand($@"
SELECT [Id]
, [AppId]
, [Function]
FROM [SoftwareFunctions]")
.ExecuteReader(f => new SoftwareFunction
{
Id = f.GetInt(),
AppId = f.GetSmallint(),
Function = f.GetString()
});
public IEnumerable<SoftwareFunction> GetSoftwareFunctions(short appId)
=> this.sqlConnection
.CreateCommand($@"
SELECT [Id]
, [AppId]
, [Function]
FROM [SoftwareFunctions]
WHERE [AppId] = @{nameof(appId)}")
.SetParameter(nameof(appId), appId)
.ExecuteReader(f => new SoftwareFunction
{
Id = f.GetInt(),
AppId = f.GetSmallint(),
Function = f.GetString()
});
public IEnumerable<string> GetSoftwareFunctions(short appId, short userId)
=> this.sqlConnection
.CreateCommand($@"
SELECT [SF].[Function] AS [Function]
FROM [UsersFunctions] AS [UF]
JOIN [SoftwareFunctions] AS [SF]
ON [SF].[Id] = [UF].[SoftwareFunctionId]
WHERE [UF].[UserId] = @{nameof(userId)}
AND [SF].[AppId] = @{nameof(appId)}")
.SetParameter(nameof(appId), appId)
.SetParameter(nameof(userId), userId)
.ExecuteReader(x => x.GetString());
public SoftwareOverview GetSoftwareOverview(short appId)
=> this.sqlConnection
.CreateCommand($@"
SELECT [vsa].[AppID]
, [vsa].[SoftwareAccess_Program]
, COUNT([vsa].[AppID])
, (SELECT COUNT(1)
FROM [SoftwareFunctions]
WHERE [AppId] = [vsa].[AppID]) AS [CountF]
FROM [VersionSoftwareAccess] AS [vsa]
WHERE [vsa].[AppID] = @{nameof(appId)}
GROUP BY [vsa].[AppID]
, [vsa].[SoftwareAccess_Program]")
.SetParameter(nameof(appId), appId)
.FirstOrDefault(x => new SoftwareOverview
{
AppId = x.GetSmallint(),
Name = x.GetString(),
Versions = x.GetInt(),
Functions = x.GetInt()
});
public IEnumerable<Software> GetSoftwareVersions(short appId)
=> this.sqlConnection
.CreateCommand($@"
SELECT [SoftwareAccess_ID]
, [AppID]
, [SoftwareAccess_Program]
, [SoftwareAccess_MajorVersion]
, [SoftwareAccess_MinorVersion]
, [SoftwareAccess_BuildVersion]
, [SoftwareAccess_VaildTo]
, [SoftwareAccess_Desc]
FROM [VersionSoftwareAccess]
WHERE [AppId] = @{nameof(appId)}
ORDER BY [SoftwareAccess_VaildTo] DESC
, [SoftwareAccess_MajorVersion] DESC
, [SoftwareAccess_MinorVersion] DESC
, [SoftwareAccess_BuildVersion] DESC")
.SetParameter(nameof(appId), appId)
.ExecuteReader(x => new Software
{
Id = x.GetInt(),
AppId = x.GetSmallint(),
FullName = x.GetString(),
MajorV = x.GetInt(),
MinorV = x.GetInt(),
BuildV = x.GetInt(),
ValidTo = x.GetDate(),
Description = x.GetString()
});
public IEnumerable<SoftwareOverview> GetSoftwares()
=> this.sqlConnection
.CreateCommand(@"
SELECT [VSA].[AppId] AS [AppId]
, [VSA].[SoftwareAccess_Program] AS [Program]
, COUNT([VSA].[AppId]) AS [Versions]
, (SELECT COUNT(1)
FROM [SoftwareFunctions]
WHERE [AppId] = [VSA].[AppID]) AS [Functions]
FROM [VersionSoftwareAccess] AS [VSA]
GROUP BY [VSA].[AppId]
, [VSA].[SoftwareAccess_Program]")
.ExecuteReader(x => new SoftwareOverview
{
AppId = x.GetSmallint(),
Name = x.GetString(),
Versions = x.GetInt(),
Functions = x.GetInt(),
});
public IEnumerable<SoftwareUser> GetUsers(string username = null)
=> this.sqlConnection
.CreateCommand($@"
SELECT [U].[MitarbeiterNr]
, [U].[Vorname]
, [U].[Name]
, [U].[Benutzername]
, COUNT([UF].[UserId])
, CAST(CASE WHEN [U].[PasswordHash] IS NULL THEN 0 ELSE 1 END AS BIT)
FROM [Mitarbeiter] AS [U]
LEFT JOIN [UsersFunctions] AS [UF]
ON [UF].[UserId] = [U].[MitarbeiterNr]
WHERE [U].[Vorname] LIKE @{nameof(username)}
OR [U].[Name] LIKE @{nameof(username)}
OR [U].[Benutzername] LIKE @{nameof(username)}
GROUP BY [U].[MitarbeiterNr]
, [U].[Vorname]
, [U].[Name]
, [U].[Benutzername]
, [U].[PasswordHash]
ORDER BY [U].[Vorname]
, [U].[Name]
, [U].[Benutzername]")
.SetParameter(nameof(username), $"%{username}%")
.ExecuteReader(x => new SoftwareUser
{
Id = x.GetSmallint(),
FirstName = x.GetString(),
LastName = x.GetString(),
Username = x.GetString(),
FunctionsCount = x.GetInt(),
HasPassword = x.GetBool()
});
public IEnumerable<SoftwareUser> GetUsersWithFunctions(int userId = -1, string username = null)
=> this.sqlConnection
.CreateCommand($@"
SELECT [U].[MitarbeiterNr]
, [U].[Vorname]
, [U].[Name]
, [U].[Benutzername]
, COUNT([UF].[UserId])
, CAST(CASE WHEN [U].[PasswordHash] IS NULL THEN 0 ELSE 1 END AS BIT)
, (SELECT CAST([SoftwareFunctionId] * -1 AS VARCHAR(MAX))
FROM [UsersFunctions]
WHERE [UserId] = [UF].[UserId]
ORDER BY [SoftwareFunctionId]
FOR XML PATH (''))
FROM [Mitarbeiter] AS [U]
LEFT JOIN [UsersFunctions] AS [UF]
ON [UF].[UserId] = [U].[MitarbeiterNr]
WHERE [U].[Vorname] LIKE @{nameof(username)}
OR [U].[Name] LIKE @{nameof(username)}
OR [U].[Benutzername] LIKE @{nameof(username)}
OR [U].[MitarbeiterNr] = @{nameof(userId)}
GROUP BY [U].[MitarbeiterNr]
, [U].[Vorname]
, [U].[Name]
, [U].[Benutzername]
, [U].[PasswordHash]
, [UF].[UserId]
ORDER BY [U].[Vorname]
, [U].[Name]
, [U].[Benutzername]")
.SetParameter(nameof(username), $"%{username}%")
.SetParameter(nameof(userId), userId)
.ExecuteReader(x => new SoftwareUser
{
Id = x.GetSmallint(),
FirstName = x.GetString(),
LastName = x.GetString(),
Username = x.GetString(),
FunctionsCount = x.GetInt(),
HasPassword = x.GetBool(),
Functions = x.GetString()
});
public void UpdateFunction(int funcId, string name)
=> this.sqlConnection
.CreateCommand($@"
UPDATE [SoftwareFunctions]
SET [Function] = @{nameof(name)}
WHERE [Id] = @{nameof(funcId)}")
.SetParameter(nameof(funcId), funcId)
.SetParameter(nameof(name), name)
.ExecuteNonQuery();
public void UpdatePasswordHashes()
{
var pwdUsers = this.sqlConnection
.CreateCommand($@"
SELECT [MitarbeiterNr]
, [Kennwort]
FROM [Mitarbeiter]
WHERE [Kennwort] IS NOT NULL
AND [PasswordHash] IS NULL")
.ExecuteReader(x => new KeyValuePair<short, string>(
key: x.GetSmallint(),
value: x.GetString()));
var sha256 = SHA256.Create();
foreach (var kvp in pwdUsers)
{
var userId = kvp.Key;
var password = sha256.ComputeHash(kvp.Value);
this.sqlConnection
.CreateCommand($@"
UPDATE [Mitarbeiter]
SET [PasswordHash] = @{nameof(password)}
WHERE [MitarbeiterNr] = @{nameof(userId)}")
.SetParameter(nameof(userId), userId)
.SetParameter(nameof(password), password)
.ExecuteNonQuery();
}
}
public int ResetPassword(short userId)
=> this.sqlConnection
.CreateCommand($@"
UPDATE [Mitarbeiter]
SET [PasswordHash] = NULL
WHERE [MitarbeiterNr] = @{nameof(userId)}")
.SetParameter(nameof(userId), userId)
.ExecuteNonQuery();
public int ResetPassword(short userId, string password)
{
password = SHA256.Create().ComputeHash(password);
return this.sqlConnection
.CreateCommand($@"
UPDATE [Mitarbeiter]
SET [PasswordHash] = @{nameof(password)}
WHERE [MitarbeiterNr] = @{nameof(userId)}")
.SetParameter(nameof(userId), userId)
.SetParameter(nameof(password), password)
.ExecuteNonQuery();
}
public void UpdateUsersFunctions(Action<UserFunctions> mapper)
{
var model = new UserFunctions();
mapper(model);
var userId = model.UserId;
this.sqlConnection
.CreateCommand($@"DELETE FROM [UsersFunctions] WHERE [UserId] = @{nameof(userId)}")
.SetParameter(nameof(userId), userId)
.ExecuteNonQuery();
foreach (var funcId in model.Functions ?? Array.Empty<int>())
{
this.sqlConnection
.CreateCommand($@"
INSERT
INTO [UsersFunctions] ([UserId] ,[SoftwareFunctionId])
VALUES (@{nameof(userId)}, @{nameof(funcId)})")
.SetParameter(nameof(userId), userId)
.SetParameter(nameof(funcId), funcId)
.ExecuteNonQuery();
}
}
public void UpdateUsersFunctions(Action<FunctionUsers> mapper)
{
var model = new FunctionUsers();
mapper(model);
var funcId = model.FunctionId;
this.sqlConnection
.CreateCommand($@"DELETE FROM [UsersFunctions] WHERE [SoftwareFunctionId] = @{nameof(funcId)}")
.SetParameter(nameof(funcId), funcId)
.ExecuteNonQuery();
foreach (var userId in model.Users ?? Array.Empty<short>())
{
this.sqlConnection
.CreateCommand($@"
INSERT
INTO [UsersFunctions] ([UserId] ,[SoftwareFunctionId])
VALUES (@{nameof(userId)}, @{nameof(funcId)})")
.SetParameter(nameof(userId), userId)
.SetParameter(nameof(funcId), funcId)
.ExecuteNonQuery();
}
}
}
}

View File

@ -8,7 +8,7 @@
using System.Net;
using System.Web.Http;
[RoutePrefix("API/Login")]
[RoutePrefix("api/Login")]
public class LoginController : ApiController
{
private readonly IAccountManager accountManager;

View File

@ -116,16 +116,6 @@
return this.Json(true);
}
[HttpPost]
[Route(nameof(Login))]
public IHttpActionResult Login([FromBody] SoftwareLoginModel model)
{
// TODO: Implement
//var softwareId = this.softwareManager.Login(model.Software, model.Functions);
return this.Json(0);
}
}
public class EditFunctionModel

View File

@ -0,0 +1,17 @@
namespace LaaProduction.Web.API.Production
{
using System.Web.Http;
[RoutePrefix("api/Personalization/Pruefstation")]
public class PruefstationController : ApiController
{
[HttpGet]
[Route("{station}/Pruefmittel")]
public IHttpActionResult Pruefmittel(string station)
{
return this.Json("");
}
}
}

View File

@ -119,6 +119,12 @@ table.table table.table {
color: var(--bs-teal);
}
.text-consolas {
font-family: Consolas;
font-size: 1rem;
font-weight: 500;
}
.btn.btn-link:hover {
text-decoration: underline !important;
}

View File

@ -79,7 +79,7 @@
.Request
.Cookies
.Get(URL_REFERER)
?.Value ?? "~/LaaProductionWeb";
?.Value ?? "~/";
public static void SetUrlReferer(this HttpContextBase httpContext)
=> httpContext

View File

@ -2,7 +2,6 @@
{
using LaaProductionHttp.Interfaces;
using LaaProduction.Web.App_Infrastructure;
using LaaProduction.Services.Interfaces;
using LaaProductionDI;
using System.Threading.Tasks;
@ -11,12 +10,10 @@
[AllowAnonymous]
public class HomeController : Controller
{
private readonly IAccountService accountService;
private readonly IHttpClient httpClient;
public HomeController()
{
this.accountService = LaaServiceProvider.GetService<IAccountService>();
this.httpClient = LaaServiceProvider.GetService<IHttpClient>();
}
@ -78,7 +75,7 @@
{
this.HttpContext.SignOut();
return this.Redirect("/");
return this.Redirect("~/");
}
}
}

View File

@ -44,7 +44,9 @@
if (file.ContentType == "application/pdf")
{
if (this.protocolService.OrderCompleted(model.OrderId.Value))
var completed = this.protocolService.OrderCompleted(model.OrderId.Value);
if (completed)
{
model.FileId = this.protocolService.SaveFile(file.InputStream, model.ClientId.Value, model.OrderId.Value);
@ -54,7 +56,7 @@
}
else
{
this.TempData[FilePDF] = $"Der PDF Datei wurde nicht hochgeladen.";
this.TempData[FilePDF] = $"Der PDF Datei könte nicht hochgeladen werden.";
}
}
else
@ -110,7 +112,6 @@
return this.PartialView(clientsOrders);
}
[HttpGet]
public ActionResult Body(int orderId = 0)
{
var testStatus = this.protocolService.LoadTestStatus(orderId);

View File

@ -32,15 +32,11 @@
=> services
.AddSingleton(SQLConnection.CreateConnection(Appsettings.ConnectionString))
.AddSingleton(HttpClient.CreateHttpClient(Appsettings.APIURL, Appsettings.APIPrefix))
.AddScoped<IAccountService, AccountService>()
.AddScoped<IApprovalsService, ApprovalsService>()
.AddScoped<ILoggerService, LoggerService>()
.AddScoped<IOrdersService, OrdersService>()
.AddScoped<IProtocolService, ProtocolService>()
.AddScoped<IReportService, ReportService>()
.AddScoped<ISearchService, SearchService>()
.AddScoped<IShipmentsService, ShipmentsService>()
.AddScoped<ISoftwareService, SoftwareService>()
.AddAdministration()
.AddSearching();
}

View File

@ -155,6 +155,7 @@
<Compile Include="API\Personalization\EmployeesController.cs" />
<Compile Include="API\Personalization\RolesController.cs" />
<Compile Include="API\Personalization\SoftwareController.cs" />
<Compile Include="API\Production\PruefstationController.cs" />
<Compile Include="API\Search\WildcardController.cs" />
<Compile Include="App_Infrastructure\AllowedRolesAttribute.cs" />
<Compile Include="App_Infrastructure\Appsettings.cs" />
@ -216,7 +217,7 @@
<Content Include="favicon.ico" />
<Content Include="favicon.svg" />
<Content Include="Global.asax" />
<Content Include="Web.config" />
<Content Include="web.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
@ -235,7 +236,6 @@
</Content>
<Content Include="Areas\Personalization\Views\Software\Details.cshtml" />
<Content Include="API\README.md" />
<None Include="packages.config" />
<Content Include="Views\_ViewStart.cshtml" />
<Content Include="Views\Approvals\Add.cshtml" />
<Content Include="Views\Home\Index.cshtml" />
@ -263,9 +263,10 @@
<Content Include="Views\Shipments\Missing.cshtml" />
<Content Include="Views\Shipments\Print.cshtml" />
<Content Include="Views\Shipments\Scan.cshtml" />
<Content Include="Views\Web.config">
<Content Include="Views\web.config">
<SubType>Designer</SubType>
</Content>
<None Include="packages.config" />
<None Include="Properties\PublishProfiles\FolderProfile.pubxml" />
<Content Include="Views\Shipments\Default.cshtml" />
</ItemGroup>
@ -309,9 +310,9 @@
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>59768</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:59768/LaaProductionWeb</IISUrl>
<IISUrl>http://localhost:59768/</IISUrl>
<OverrideIISAppRootUrl>True</OverrideIISAppRootUrl>
<IISAppRootUrl>http://localhost:59768/LaaProductionWeb</IISAppRootUrl>
<IISAppRootUrl>http://localhost:59768/</IISAppRootUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>

View File

@ -13,7 +13,7 @@
}
else if (testStatus == false)
{
return new MvcHtmlString("<td class=\"text-center text-danger\">X</td>");
return new MvcHtmlString("<td class=\"text-center text-danger\">x</td>");
}
else
{
@ -26,7 +26,7 @@
<tr>
<td colspan="2" class="p-0">
<table class="table table-bordered">
<tr>
<tr class="small">
<th class="white-space-nowrap">Pos.</th>
<th class="white-space-nowrap">Serial No.</th>
<th class="text-center">T1</th>
@ -39,13 +39,13 @@
</tr>
@foreach (var item in this.Model)
{
<tr>
<tr class="text-consolas">
<td class="va-middle">@item.PosNr</td>
<td class="va-middle white-space-nowrap">@item.SerialNr</td>
@testPassed(null, true)
@testPassed(null, true)
@testPassed(item.PressureTest, false)
@testPassed(item.HeliumTest, false)
@testPassed(null, true)
@testPassed(item.MetroTest, false)
@testPassed(item.RadioTest, false)
@testPassed(null, true)
@ -55,53 +55,73 @@
</td>
</tr>
<tr>
<td colspan="2" class="pt-5 pb-0 px-0 small">
<td colspan="2" class="pt-5 pb-0 px-0 small" >
<table class="table table-sm table-bordered border-top">
<tr>
<th>Legend:</th>
<th>Component & Operation</th>
<th>Quantum of Check</th>
<th>Acceptance Norms</th>
<th>Quantum of check</th>
<th>Acceptance norms</th>
</tr>
<tr>
<th class="va-middle py-0">T1</th>
<th class="va-middle py-0">Powder coating</th>
<td class="py-0">
1 piece per quarter<br />
1 piece per h
<th class="va-middle py-1">T1</th>
<th class="va-middle py-1">Powder coating</th>
<td class="p-0">
<table class="table table-sm">
<tr>
<td class="py-1">1 piece per quarter</td>
</tr>
<tr>
<td class="py-1 border-bottom-0">1 piece per h</td>
</tr>
</table>
</td>
<td class="va-middle py-0">
Adhesion according to DIN 53151,coating faultless & corrosion free<br />
According drawing
<td class="p-0">
<table class="table table-sm">
<tr>
<td class="py-1">Adhesion according to DIN 53151, coating faultless & corrosion free</td>
</tr>
<tr>
<td class="py-1 border-bottom-0">According drawing</td>
</tr>
</table>
</td>
@*<td class="py-1">
1 piece per quarter<br /><br />
1 piece per h
</td>
<td class="va-middle py-1">
Adhesion according to DIN 53151, coating faultless & corrosion free<br /><br />
According drawing
</td>*@
</tr>
<tr>
<th class="va-middle py-0">T2</th>
<th class="va-middle py-0">Pressure and burst test composit transducer</th>
<td class="py-0">
<th class="va-middle py-1">T2</th>
<th class="va-middle py-1">Pressure and burst test composite transducer</th>
<td class="py-1">
First part / batch<br />
500 th part / batch<br />
Last part / batch
</td>
<td class="va-middle">Rejected in case of leakage or breakage</td>
<td class="va-middle py-1">Rejected in case of leakage or breakage</td>
</tr>
<tr>
<th class="va-middle py-0">T3</th>
<th class="va-middle py-0">Tightness Test</th>
<td class="py-0">100%</td>
<td class="va-middle">Rejected in case of leakage</td>
<th class="va-middle py-1">T3</th>
<th class="va-middle py-1">Tightness (Helium) test</th>
<td class="py-1">100%</td>
<td class="va-middle py-1">Rejected in case of leakage</td>
</tr>
<tr>
<th class="va-middle py-0">T4</th>
<th class="va-middle py-0">Pressure and tightness test</th>
<td class="py-0">100% at start of production</td>
<td class="va-middle py-0">Rejected in case of leakage or breakage</td>
<th class="va-middle py-1">T4</th>
<th class="va-middle py-1">Pressure and tightness test</th>
<td class="py-1">100% - Statistical test according test plan</td>
<td class="va-middle py-1">Rejected in case of leakage or breakage</td>
</tr>
<tr>
<th class="va-middle py-0">T5</th>
<th class="va-middle py-0">Metrological testing</th>
<td class="py-0">100%</td>
<td class="va-middle py-0">
<th class="va-middle py-1">T5</th>
<th class="va-middle py-1">Metrological testing</th>
<td class="py-1">100%</td>
<td class="va-middle py-1">
Maximum Permissible Error at<br />
Q1 < ± 5%<br />
Q2 < ± 2%<br />
@ -109,35 +129,35 @@
</td>
</tr>
<tr>
<th class="va-middle py-0">T6</th>
<th class="va-middle py-0">Config comparison and radio test</th>
<td class="py-0">100%</td>
<td class="va-middle py-0">
<th class="va-middle py-1">T6</th>
<th class="va-middle py-1">Config comparison and radio test</th>
<td class="py-1">100%</td>
<td class="va-middle py-1">
Main functions, LCD display, LED, Radio functions according to specs<br />
Parameter readable and according to customer specification
</td>
</tr>
<tr>
<th class="va-middle py-0">T7</th>
<th class="py-0">100%</th>
<td class="va-middle py-0">Packaging of meter</td>
<td class="va-middle py-0">SENSUS-1-924</td>
<th class="va-middle py-1">T7</th>
<th class="py-1">Packaging of meter</th>
<td class="va-middle py-1">100% - Final check and visual inspection</td>
<td class="va-middle py-1">SENSUS-1-924</td>
</tr>
<tr>
<th class="va-middle py-0">n/a</th>
<td class="va-middle py-0" colspan="3">Not applicable</td>
<th class="va-middle text-secondary py-1">n/a</th>
<td class="va-middle py-1" colspan="3">Not applicable</td>
</tr>
<tr>
<th class="va-middle py-0">Ok</th>
<td class="va-middle py-0" colspan="3">Test passed</td>
<th class="va-middle text-success py-1">OK</th>
<td class="va-middle py-1" colspan="3">Test passed</td>
</tr>
<tr>
<th class="va-middle py-0">Ok*</th>
<td class="va-middle py-0" colspan="3">Test passed according to the Quantum of Check</td>
<th class="va-middle text-success py-1">OK*</th>
<td class="va-middle py-1" colspan="3">Test passed according to the Quantum of Check</td>
</tr>
<tr>
<th class="va-middle py-0">X</th>
<td class="va-middle py-0" colspan="3">Test not passed</td>
<th class="va-middle text-danger py-1">x</th>
<td class="va-middle py-1" colspan="3">Test not passed</td>
</tr>
</table>
</td>

View File

@ -12,25 +12,25 @@
<td colspan="2" class="py-1 fs-5 white-space-nowrap text-center text-smallcaps">Test Protocol</td>
</tr>
<tr>
<td class="py-1 white-space-nowrap va-middle"><label for="client_name">Client</label></td>
<td class="py-1 white-space-nowrap va-middle small"><label for="client_name">Client</label></td>
<td class="p-1 dropdown w-75">
<input id="client_name" class="form-control border-0 rounded-0" value="@this.Model.ClientName" />
<ul class="dropdown-menu mt-2 w-100" id="client_name_options">
<input id="client_name" class="form-control border-0 rounded-0 text-consolas" value="@this.Model.ClientName" />
<ul class="dropdown-menu mt-2 w-100 text-consolas" id="client_name_options">
<li class="text-secondary bg-light text-normal">Search by client name</li>
</ul>
</td>
</tr>
<tr>
<td class="py-1 white-space-nowrap va-middle"><label for="order_no">Order No.</label></td>
<td class="py-1 white-space-nowrap va-middle small"><label for="order_no">Order No.</label></td>
<td class="p-1 w-75">
<input id="order_no" class="form-control border-0 rounded-0" value="@this.Model.OrderId" />
<ul class="dropdown-menu mt-2 w-100" id="order_no_options">
<input id="order_no" class="form-control border-0 rounded-0 text-consolas" value="@this.Model.OrderId" />
<ul class="dropdown-menu mt-2 w-100 text-consolas" id="order_no_options">
<li class="text-secondary bg-light text-normal">Search by order no.</li>
</ul>
</td>
</tr>
<tr class="border-bottom-0">
<td class="py-1 white-space-nowrap va-middle">Positions</td>
<td class="py-1 white-space-nowrap va-middle small">Positions</td>
<td class="p-1 w-75">
<div class="form-control border-0 rounded-0">
@if (string.IsNullOrWhiteSpace(this.Model.Positions))
@ -39,7 +39,7 @@
}
else
{
<span>@this.Model.Positions</span>
<span class="text-consolas">@this.Model.Positions</span>
}
</div>
</td>
@ -74,7 +74,7 @@
</thead>
@if (this.Model.OrderId > 0)
{
this.Html.RenderAction("Body", "Protocol", new { orderId = this.Model.OrderId });
this.Html.RenderAction(nameof(ProtocolController.Body), new { orderId = this.Model.OrderId });
}
</table>

View File

@ -1,4 +1,4 @@
s@model OrderClientModel
@model OrderClientModel
@using LaaProduction.Web.Controllers
@using LaaProduction.Services.Models
@ -16,7 +16,7 @@
<td colspan="2" class="py-1 fs-5 white-space-nowrap text-center text-smallcaps">Test Protocol</td>
</tr>
<tr>
<td class="py-1 white-space-nowrap va-middle"><label for="client_name">Client</label></td>
<td class="py-1 white-space-nowrap va-middle small"><label for="client_name">Client</label></td>
<td class="p-1 w-75">
<div class="form-control border-0 rounded-0">
@if (string.IsNullOrWhiteSpace(this.Model.ClientName))
@ -31,7 +31,7 @@
</td>
</tr>
<tr>
<td class="py-1 white-space-nowrap va-middle"><label for="order_no">Order No.</label></td>
<td class="py-1 white-space-nowrap va-middle small"><label for="order_no">Order No.</label></td>
<td class="p-1 w-75">
<div class="form-control border-0 rounded-0">
@if (this.Model.OrderId is null)
@ -40,13 +40,13 @@
}
else
{
<span>@this.Model.OrderId</span>
<span class="text-consolas">@this.Model.OrderId</span>
}
</div>
</td>
</tr>
<tr class="border-bottom-0">
<td class="py-1 white-space-nowrap va-middle">Positions</td>
<td class="py-1 white-space-nowrap va-middle small">Positions</td>
<td class="p-1 w-75">
<div class="form-control border-0 rounded-0">
@if (string.IsNullOrWhiteSpace(this.Model.Positions))
@ -55,7 +55,7 @@
}
else
{
<span>@this.Model.Positions</span>
<span class="text-consolas">@this.Model.Positions</span>
}
</div>
</td>
@ -74,20 +74,22 @@
</table>
<div class="container-fluid">
<div class="row py-5">
<div class="row py-2">
<div class="col-4 d-flex flex-column justify-content-end">
<label class="small">Date: @($"{DateTime.Now:dd.MM.yyyy}")</label>
<div>
<label class="small fw-bold">Date:</label> <span class="text-consolas">@($"{DateTime.Now:dd.MM.yyyy}")</span>
</div>
<hr class="mt-2" />
</div>
<div class="col-4 d-flex flex-column justify-content-end">
<div class="input-group align-items-end">
<label class="small">Name: </label>
<label class="small fw-bold">Name: </label>
<input class="form-control border-0 rounded-0" />
</div>
<hr class="mt-2" />
</div>
<div class="col-4 d-flex flex-column justify-content-end">
<label class="small">Sign: </label>
<label class="small fw-bold">Sign: </label>
<hr class="mt-2" />
</div>
</div>

View File

@ -70,8 +70,11 @@
}
else
{
<li class="nav-item">
<span class="nav-link text-smallcaps">Benutzer: @this.User.FullName()</span>
<li class="nav-item dropdown">
<a class="nav-link text-smallcaps dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" href="#">@this.User.FullName()</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="~/Home/Logout">Abmelden</a></li>
</ul>
</li>
}
</ul>