Merge branch 'main' into Dev_MagFlux
This commit is contained in:
commit
b667b5d55f
@ -155,7 +155,7 @@
|
||||
</site>
|
||||
<site name="MeterProcessState" id="2">
|
||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||
<virtualDirectory path="/" physicalPath="D:\Projekte\SENSUS_GitLab\laa_production\Common\Service\MeterProcessState" />
|
||||
<virtualDirectory path="/" physicalPath="C:\Users\SZLATEV\source\repos\laa_production\Common\Service\MeterProcessState" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:56011:localhost" />
|
||||
|
||||
@ -187,8 +187,54 @@ namespace Xylem.Common.CommonCore.Configuration
|
||||
// "http://localhost:56011/api/SoftwareAccess/GetVersionIsValid";
|
||||
|
||||
|
||||
private const String PressureSensorTestURL_GetTestSpec
|
||||
= "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestSpec";
|
||||
|
||||
|
||||
private const String PressureSensorTestURL_PostTestResults
|
||||
= "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/PostTestResults";
|
||||
|
||||
/// <summary>
|
||||
/// usage: string.Format(CordonelPressureSensorTestURL_GetTestResults, pcbId);
|
||||
/// </summary>
|
||||
private const String PressureSensorTestURL_GetTestResults
|
||||
= "http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestResults/{0}";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// GET: test specification for water meter with pressure sensor.
|
||||
/// </summary>
|
||||
public static string GetPressureSensorSpecificationURL
|
||||
#if DEBUG
|
||||
=> "http://localhost:56011/api/CordonelPressureSensorTest/GetTestSpec";
|
||||
#else
|
||||
=> ConfigurationManager.AppSettings[nameof(GetPressureSensorSpecificationURL)]
|
||||
?? PressureSensorTestURL_GetTestSpec;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// POST: test result for water meter with pressure sensor.
|
||||
/// </summary>
|
||||
public static string PostPressureSensorResultURL
|
||||
#if DEBUG
|
||||
=> "http://localhost:56011/api/CordonelPressureSensorTest/PostTestResults";
|
||||
#else
|
||||
=> ConfigurationManager.AppSettings[nameof(PostPressureSensorResultURL)]
|
||||
?? PressureSensorTestURL_PostTestResults;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// GET: a list of test results for the water meter with specified pcbId.
|
||||
/// </summary>
|
||||
public static string PressureSensorResultsURL<T>(this T pcbId)
|
||||
{
|
||||
#if DEBUG
|
||||
var url = "http://localhost:56011/api/CordonelPressureSensorTest/GetTestResults/{0}";
|
||||
#else
|
||||
var url = ConfigurationManager.AppSettings[nameof(PressureSensorResultsURL)] ?? PressureSensorTestURL_GetTestResults;
|
||||
#endif
|
||||
|
||||
return string.Format(url, pcbId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all Cordonel FW packages.
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{D0C8D887-ED52-40AB-A069-90BCE0E801E2}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Xylem.Common.Ui.CordonelPreadjustmentUi</RootNamespace>
|
||||
<AssemblyName>Xylem.Common.Ui.CordonelPreadjustmentUi</AssemblyName>
|
||||
@ -103,6 +103,9 @@
|
||||
<PropertyGroup />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup>
|
||||
<NoWin32Manifest>true</NoWin32Manifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
@ -116,6 +119,9 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http">
|
||||
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Net.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -153,6 +159,7 @@
|
||||
<DependentUpon>PreAdjustmentControl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="PreAdjustmentSettingsContainer.cs" />
|
||||
<Compile Include="Processes\Actions\PressureTestProcess.cs" />
|
||||
<Compile Include="Processes\Actions\FlushProcess.cs" />
|
||||
<Compile Include="Processes\Actions\PrepareTestProcess.cs" />
|
||||
<Compile Include="Processes\Actions\AmplitudeTestProcess.cs" />
|
||||
|
||||
@ -393,6 +393,7 @@ namespace CordonelPreadjustmentUi
|
||||
{
|
||||
this.l_ZeroFlowCal_TempCal.ForeColor = color;
|
||||
}
|
||||
|
||||
public enum StatusPanelItems
|
||||
{
|
||||
None = 0,
|
||||
@ -1681,9 +1682,13 @@ namespace CordonelPreadjustmentUi
|
||||
|
||||
listOfProgrammParts.Add(new FlushProcess("First Flush", StatusPanelItems.Detect, PredefinedMessages.WaitUntilFlushFinished(pp.Setting.Culture), string.Empty, 2 * 60));
|
||||
|
||||
listOfProgrammParts.Add(new PressureTestProcess("PreussureTest", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
|
||||
|
||||
|
||||
listOfProgrammParts.Add(new PreparationProcess("Preparation", StatusPanelItems.Prepare, PredefinedMessages.WaitUntilPreparationFinished(pp.Setting.Culture), PredefinedMessages.PreparationFailed(pp.Setting.Culture), 1 * 60));
|
||||
|
||||
|
||||
|
||||
if (!pp.Setting.TempOnly)
|
||||
{
|
||||
listOfProgrammParts.Add(new AmplitudeTestProcess("Amplitude Test", StatusPanelItems.Amplitude, PredefinedMessages.WaitUntilAmplitudeTestFinished(pp.Setting.Culture), PredefinedMessages.AmplitudeFailed(pp.Setting.Culture), 4 * 60));
|
||||
|
||||
@ -16,8 +16,6 @@ namespace CordonelPreadjustmentUi.Processes.Actions
|
||||
{
|
||||
public class PreparationProcess : BaseProcess
|
||||
{
|
||||
|
||||
|
||||
public PreparationProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS) : base(processName, panelState, performMessage, failedMessage, expectedTimeS)
|
||||
{
|
||||
}
|
||||
|
||||
@ -0,0 +1,256 @@
|
||||
namespace CordonelPreadjustmentUi.Processes.Actions
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xylem.Common.CommonCore.Configuration;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
||||
using Xylem.Common.Logic.SoftwareAccessHelper;
|
||||
|
||||
using static CordonelPreadjustmentUi.PreAdjustmentControl;
|
||||
|
||||
/// <summary>
|
||||
/// Process for cordonel water meters with pressure sensor.
|
||||
/// </summary>
|
||||
/// <remarks date="2023-05-23" author="Stoyan Zlatev">
|
||||
/// Just started implementing pressure test for water meters with pressure sensor.
|
||||
/// </remarks>
|
||||
public class PressureTestProcess : BaseProcess
|
||||
{
|
||||
/// <summary>
|
||||
/// Read / Write is pressure present for the water meter.
|
||||
/// </summary>
|
||||
/// <remarks date="2023-05-23" author="Stoyan Zlatev">
|
||||
/// Just started implementing pressure test for water meters with pressure sensor.
|
||||
/// </remarks>
|
||||
private const string PRESSURE_PRESENT = "METROLOGYASST_PressurePresent";
|
||||
/// <summary>
|
||||
/// Read / Write pressure measurements for the water meter.
|
||||
/// </summary>
|
||||
/// <remarks date="2023-05-23" author="Stoyan Zlatev">
|
||||
/// Just started implementing pressure test for water meters with pressure sensor.
|
||||
/// </remarks>
|
||||
private const string PRESSURE_MEASURE = "METROLOGYASST_PressureMeasure";
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for passing parameters to the base constructor of the derived class.
|
||||
/// </summary>
|
||||
/// <param name="processName">The name used to show into the GUI.</param>
|
||||
/// <param name="panelState">TODO: Get the right description. Probably the state for the box into the GUI. ???</param>
|
||||
/// <param name="performMessage">TODO: Get the right description. Probably the success message to show into the GUI. ???</param>
|
||||
/// <param name="failedMessage">TODO: Get the right description. Probably the error message to show into the GUI. ???</param>
|
||||
/// <param name="expectedTimeS">TODO: Get the right description. Probably the expected time for process the pressure tests. ???</param>
|
||||
/// <remarks date="2023-05-23" author="Stoyan Zlatev">
|
||||
/// Just started implementing pressure test for water meters with pressure sensor.
|
||||
/// </remarks>
|
||||
public PressureTestProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS)
|
||||
: base(processName, panelState, performMessage, failedMessage, expectedTimeS)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determinates and initializes a list of pressure measure tests processes on the logedin cordonels with pressure sensor.
|
||||
/// Programm workflow for Cordonels with pressure sensor.
|
||||
/// When any of the water meters has presure sensor - load the test specification.
|
||||
/// Acording to the test specification process all meters, also the referenz on workplaces 11 and 12.
|
||||
/// <list type="number">
|
||||
/// <listheader>Measurement as follow.</listheader>
|
||||
/// <item>Measure starts with <see cref="PRESSURE_MEASURE"/> = 1</item>
|
||||
/// <item>Then registry is readeded and comaired to the referenz meters acording to the specification.</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
/// <returns>Returns a <see cref="List{Task}"/> for processing the pressure tests on the goggedin cordonels.</returns>
|
||||
/// <remarks date="2023-05-23" author="Stoyan Zlatev">
|
||||
/// Just started implementing pressure test for water meters with pressure sensor.
|
||||
/// </remarks>
|
||||
public override List<Task> StartWork()
|
||||
{
|
||||
/// List of the processes to start.
|
||||
var listOfPresureTestTasks = new List<Task>();
|
||||
var pressureTestSpecification = default(PressureTestSpecification);
|
||||
var pressureTestSpecificationLoaded = false;
|
||||
/// Just to not lose from focus the process progrss object.
|
||||
var processProgress = base.CurrentProcessProgress;
|
||||
var minPressureReferenzValue = default(int?);
|
||||
var maxPressureReferenzValue = default(int?);
|
||||
|
||||
/// Looping trough all <see cref="MeterStateControl"/>s to determinate whitch are with pressure sensor.
|
||||
foreach (var meterStateControl in base.MeterStateCtls)
|
||||
{
|
||||
/// If the meter is enabled and pressure sensor is present a new pressure mesure task should be initialized and added to the processes list.
|
||||
if (meterStateControl.IsEnabled)
|
||||
{
|
||||
/// Getting the meter object from the state control.
|
||||
var meter = meterStateControl.Meter;
|
||||
/// Reads the buffer for determinating if the pressure sensor is present.
|
||||
var isPressurePresentBuffer = meter.ReadRegister(PRESSURE_PRESENT);
|
||||
/// Converted value for determinating if the pressure sensor is present.
|
||||
var isPressurePresent = RegisterConverter.ConvertTo<bool>(isPressurePresentBuffer);
|
||||
|
||||
if (!isPressurePresent)
|
||||
{
|
||||
processProgress.DebugMessage($"Watermeter has no pressure sensor!", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/// Loads the pressure test specification from the defined web service if not yet loaded.
|
||||
if (pressureTestSpecification is null && !pressureTestSpecificationLoaded)
|
||||
{
|
||||
pressureTestSpecificationLoaded = true;
|
||||
pressureTestSpecification = this.LoadPressureTestSpecification();
|
||||
|
||||
/// if loading fails
|
||||
if (pressureTestSpecification is null)
|
||||
{
|
||||
processProgress.DebugMessage($"Test specification could not be loaded properly!", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
|
||||
// TODO: Handle possible exceptions by making http request.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize min and max referenz values ones for all meters
|
||||
if (minPressureReferenzValue is null)
|
||||
{
|
||||
/// setting the min and max values on their oposit values.
|
||||
/// checking the equality later will set up a value by 1 or more referenz meters.
|
||||
minPressureReferenzValue = int.MaxValue;
|
||||
maxPressureReferenzValue = int.MinValue;
|
||||
|
||||
if (processProgress.Setting.GetTempUseTempFlansh() || TempMeterStateCtls.Any(a => a.IsEnabled))
|
||||
{
|
||||
/// Determinates the min and max values aus temperatur meters list.
|
||||
foreach (var referenzMeterState in base.TempMeterStateCtls)
|
||||
{
|
||||
if (referenzMeterState.IsEnabled)
|
||||
{
|
||||
var referenzMeter = referenzMeterState.Meter;
|
||||
/// Reset meter pressure
|
||||
referenzMeter.WriteRegister(PRESSURE_MEASURE, 1);
|
||||
|
||||
if (!referenzMeter.IsLoggedOn)
|
||||
{
|
||||
referenzMeter.Login();
|
||||
}
|
||||
|
||||
var referenzPressureBuffer = referenzMeter.ReadRegister(PRESSURE_MEASURE);
|
||||
var referenzPressure = RegisterConverter.ConvertTo<int>(referenzPressureBuffer);
|
||||
|
||||
if (referenzPressure < minPressureReferenzValue)
|
||||
{
|
||||
minPressureReferenzValue = referenzPressure;
|
||||
}
|
||||
|
||||
if (referenzPressure > maxPressureReferenzValue)
|
||||
{
|
||||
maxPressureReferenzValue = referenzPressure;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Continue if min pressure value is still its oposit for the type. There was no referenz zehler found.
|
||||
if (minPressureReferenzValue == int.MaxValue)
|
||||
{
|
||||
processProgress.DebugMessage($"No referenz watermeter found!", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
listOfPresureTestTasks.Add(new Task<bool>(() =>
|
||||
{
|
||||
var measuredTestValues = new int[pressureTestSpecification.NumberOfMeasurements];
|
||||
var measurementDelyInS = pressureTestSpecification.TimeMeasurementsInS * 1000;
|
||||
var numberOfMeasurements = pressureTestSpecification.NumberOfMeasurements;
|
||||
var testDate = DateTime.Now;
|
||||
|
||||
for (int measurement = 0; measurement < numberOfMeasurements; measurement++)
|
||||
{
|
||||
/// Reset meter pressure
|
||||
meter.WriteRegister(PRESSURE_MEASURE, 1);
|
||||
|
||||
/// Read the new meter pressure
|
||||
var pressureMeasureBuffer = meter.ReadRegister(PRESSURE_MEASURE);
|
||||
var pressureInPascals = RegisterConverter.ConvertTo<int>(pressureMeasureBuffer);
|
||||
|
||||
measuredTestValues[measurement] = pressureInPascals;
|
||||
processProgress.DebugMessage($"Measure {measurement + 1}: {pressureInPascals}Pa", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
|
||||
/// Dely only for first n - 1 measurements
|
||||
if (measurement < numberOfMeasurements - 1)
|
||||
{
|
||||
Thread.Sleep(measurementDelyInS);
|
||||
}
|
||||
}
|
||||
|
||||
var avgPressure = (int)measuredTestValues.Average();
|
||||
var testPassed = minPressureReferenzValue <= avgPressure && avgPressure <= maxPressureReferenzValue;
|
||||
var avgPressureInBars = avgPressure / 100_000F;
|
||||
|
||||
processProgress.DebugMessage($"Average pressure: {avgPressure}Pa", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
processProgress.DebugMessage($"Average pressure: {avgPressureInBars}Bar", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
|
||||
if (!this.PostPressureTestResult(meter.PcbId, avgPressureInBars, testPassed, testDate))
|
||||
{
|
||||
processProgress.DebugMessage($"Test result was not posted!", meterStateControl.Slot, "DC", meter.PcbId);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return testPassed;
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return listOfPresureTestTasks;
|
||||
}
|
||||
|
||||
private PressureTestSpecification LoadPressureTestSpecification()
|
||||
{
|
||||
try
|
||||
{
|
||||
var responseContent = LocalWebRequest.GetRequest(ServiceUrls.GetPressureSensorSpecificationURL);
|
||||
|
||||
return JsonConvert.DeserializeObject<PressureTestSpecification>(responseContent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool PostPressureTestResult(string pcbIdText, float avgPressure, bool passed, DateTime testDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
return LocalWebRequest.PostRequestAsync(ServiceUrls.PostPressureSensorResultURL, json: new
|
||||
{
|
||||
PcbId = int.TryParse(pcbIdText, out int pcbId) ? pcbId : default(int?),
|
||||
AvgPressureInBar = avgPressure,
|
||||
TestPassed = passed,
|
||||
TestDate = testDate,
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class PressureTestSpecification
|
||||
{
|
||||
public int NumberOfMeasurements { get; set; }
|
||||
|
||||
public int TimeMeasurementsInS { get; set; }
|
||||
|
||||
public float MaxDeviationInBar { get; set; }
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,7 @@ namespace CordonelPreadjustmentUi.Processes
|
||||
public readonly string PerformMessage;
|
||||
public readonly int ExpectedTimeS;
|
||||
public DateTimeOffset StartTime;
|
||||
|
||||
public BaseProcess(string processName, StatusPanelItems panelState, string performMessage, string failedMessage, int? expectedTimeS = null)
|
||||
{
|
||||
ProcessName = processName;
|
||||
@ -30,6 +31,7 @@ namespace CordonelPreadjustmentUi.Processes
|
||||
|
||||
ExpectedTimeS = expectedTimeS.HasValue ? expectedTimeS.Value : 0;
|
||||
}
|
||||
|
||||
internal List<MeterStateControl> AllMeterStateCtrls()
|
||||
{
|
||||
var r = new List<MeterStateControl>();
|
||||
@ -75,29 +77,29 @@ namespace CordonelPreadjustmentUi.Processes
|
||||
|
||||
|
||||
var completTasks = new Task(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!listOfProcessTasks.All(t => t.IsCompleted))
|
||||
{
|
||||
try
|
||||
if (pp.CancellationSource != null && pp.CancellationSource.IsCancellationRequested)
|
||||
{
|
||||
while (!listOfProcessTasks.All(t => t.IsCompleted))
|
||||
{
|
||||
if (pp.CancellationSource != null && pp.CancellationSource.IsCancellationRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
|
||||
GetSequenceResult($"{ProcessName} sequence");
|
||||
pp.IsBusy = false;
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
|
||||
throw new ApplicationException("Error on waiting for completition", ex);
|
||||
}
|
||||
GetSequenceResult($"{ProcessName} sequence");
|
||||
pp.IsBusy = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw new ApplicationException("Error on waiting for completition", ex);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
completTasks.Start();
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="GetPressureSensorSpecificationURL" value="http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestSpec"/>
|
||||
<add key="PostPressureSensorResultURL" value="http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/PostTestResults"/>
|
||||
<add key="PressureSensorResultsURL" value="http://sla12iis01.emea.sensus.net/MeterProcessState/api/CordonelPressureSensorTest/GetTestResults/{0}"/>
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\..\..\ServiceFwUpdate\packages\Newtonsoft.Json.12.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>..\..\..\..\Logic.PrdoctionToProductMapper\bin\Debug\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@ -1 +1 @@
|
||||
1a3d4919c9c702245832d925951f2b7cb72fc333
|
||||
2060865c94a192d7a90bef853b7068b66f669cb3
|
||||
|
||||
@ -97,7 +97,7 @@ namespace Xylem.Common.Service.MeterProcessState
|
||||
// those comments into the generated docs and UI. You can enable this by providing the path to one or
|
||||
// more Xml comment files.
|
||||
//
|
||||
//c.IncludeXmlComments(GetXmlCommentsPath());
|
||||
// c.IncludeXmlComments(GetXmlCommentsPath());
|
||||
|
||||
// Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types
|
||||
// exposed in your API. However, there may be occasions when more control of the output is needed.
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
using System.Web.Http;
|
||||
using Microsoft.Owin.Security.OAuth;
|
||||
|
||||
namespace Service.MeterProcessState
|
||||
namespace Service.MeterProcessState
|
||||
{
|
||||
using System.Web.Http;
|
||||
using Microsoft.Owin.Security.OAuth;
|
||||
|
||||
public static class WebApiConfig
|
||||
{
|
||||
public static void Register(HttpConfiguration config)
|
||||
|
||||
14
Common/Service/MeterProcessState/Appsettings.cs
Normal file
14
Common/Service/MeterProcessState/Appsettings.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace Xylem.Common.Service.MeterProcessState
|
||||
{
|
||||
using System.Configuration;
|
||||
|
||||
public class Appsettings
|
||||
{
|
||||
public static string CordonelTestSpecJson => ConfigurationManager.AppSettings[nameof(CordonelTestSpecJson)];
|
||||
|
||||
public class ConnectionStrings
|
||||
{
|
||||
public static string Default => ConfigurationManager.ConnectionStrings[nameof(Default)].ConnectionString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"NumberOfMeasurements": 3,
|
||||
"TimeMeasurementsInS": 1,
|
||||
"MaxDeviationInBar": 0.5
|
||||
}
|
||||
|
||||
@ -0,0 +1,173 @@
|
||||
namespace Xylem.Common.Service.MeterProcessState.Controllers
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
|
||||
using Xylem.Common.Service.MeterProcessState.Extensions;
|
||||
using Xylem.Common.Service.MeterProcessState.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Controller for tests on cordonel pressure sensor.
|
||||
/// </summary>
|
||||
[RoutePrefix("api/CordonelPressureSensorTest")]
|
||||
public class CordonelPressureSensorTestController : ApiController
|
||||
{
|
||||
[HttpGet]
|
||||
[Route(nameof(GetTestSpec))]
|
||||
public IHttpActionResult GetTestSpec()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cordonelTestSpecJson = HttpContext
|
||||
.Current
|
||||
.Server
|
||||
.MapPath(Appsettings.CordonelTestSpecJson);
|
||||
var cordonelTestSpecContent = File.ReadAllText(cordonelTestSpecJson);
|
||||
var cordonelTestSpec = JsonConvert.DeserializeObject<CordonelTestSpec>(cordonelTestSpecContent);
|
||||
|
||||
return this.Json(cordonelTestSpec);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return this.BadRequest(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route(nameof(PostTestResults))]
|
||||
public async Task<IHttpActionResult> PostTestResults([FromBody] CordonelTestResult cordonelTestResult)
|
||||
{
|
||||
var httpActionResult = default(IHttpActionResult);
|
||||
|
||||
if (!this.ModelState.IsValid)
|
||||
{
|
||||
return this.BadRequest(this.ModelState);
|
||||
}
|
||||
else
|
||||
{
|
||||
var insertedId = default(object);
|
||||
|
||||
using (var sqlConnection = new SqlConnection(Appsettings.ConnectionStrings.Default))
|
||||
{
|
||||
sqlConnection.FireInfoMessageEventOnUserErrors = true;
|
||||
sqlConnection.InfoMessage += (sender, args) =>
|
||||
{
|
||||
var messages = args
|
||||
.Errors
|
||||
.Cast<SqlError>()
|
||||
.Select(x => x.Message);
|
||||
|
||||
// TODO: Switch to expected error messages list.
|
||||
httpActionResult = this.Json(args.Errors);
|
||||
};
|
||||
|
||||
await sqlConnection.OpenAsync();
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
INSERT INTO [Cordonel_PressureSensor_TestResults] (
|
||||
[PcbId]
|
||||
, [AvgPressureInBar]
|
||||
, [TestPassed]
|
||||
, [TestDate])
|
||||
OUTPUT [inserted].[Id]
|
||||
VALUES (@{nameof(cordonelTestResult.PcbId)}
|
||||
, @{nameof(cordonelTestResult.AvgPressureInBar)}
|
||||
, @{nameof(cordonelTestResult.TestPassed)}
|
||||
, @{nameof(cordonelTestResult.TestDate)})";
|
||||
sqlCommand.Parameters.AddWithValue(nameof(cordonelTestResult.PcbId), cordonelTestResult.PcbId);
|
||||
sqlCommand.Parameters.AddWithValue(nameof(cordonelTestResult.TestDate), cordonelTestResult.TestDate);
|
||||
sqlCommand.Parameters.AddWithValue(nameof(cordonelTestResult.AvgPressureInBar), cordonelTestResult.AvgPressureInBar);
|
||||
sqlCommand.Parameters.AddWithValue(nameof(cordonelTestResult.TestPassed), cordonelTestResult.TestPassed);
|
||||
|
||||
insertedId = await sqlCommand.ExecuteScalarAsync();
|
||||
}
|
||||
}
|
||||
|
||||
if (insertedId is null)
|
||||
{
|
||||
if (httpActionResult is null)
|
||||
{
|
||||
// TODO: Custom error message.
|
||||
httpActionResult = this.BadRequest();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
httpActionResult = this.Ok(insertedId);
|
||||
}
|
||||
}
|
||||
|
||||
return httpActionResult;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route(nameof(GetTestResults) + "/{pcbId}")]
|
||||
public async Task<IHttpActionResult> GetTestResults(int pcbId)
|
||||
{
|
||||
var actionResult = default(IHttpActionResult);
|
||||
var testResults = new List<CordonelTestResult>();
|
||||
|
||||
using (var sqlConnection = new SqlConnection(Appsettings.ConnectionStrings.Default))
|
||||
{
|
||||
sqlConnection.FireInfoMessageEventOnUserErrors = true;
|
||||
sqlConnection.InfoMessage += (sender, args) =>
|
||||
{
|
||||
var messages = args
|
||||
.Errors
|
||||
.Cast<SqlError>()
|
||||
.Select(x => x.Message);
|
||||
|
||||
// TODO: Switch to expected error messages list.
|
||||
actionResult = this.Json(args.Errors);
|
||||
};
|
||||
await sqlConnection.OpenAsync();
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT [Id]
|
||||
, [PcbId]
|
||||
, [AvgPressureInBar]
|
||||
, [TestPassed]
|
||||
, [TestDate]
|
||||
FROM [Cordonel_PressureSensor_TestResults]
|
||||
WHERE [PcbId] = {nameof(pcbId)}
|
||||
ORDER BY [Id]";
|
||||
sqlCommand.Parameters.AddWithValue(nameof(pcbId), pcbId);
|
||||
|
||||
using (var sqlDataReader = await sqlCommand.ExecuteReaderAsync())
|
||||
{
|
||||
while (await sqlDataReader.ReadAsync())
|
||||
{
|
||||
testResults.Add(new CordonelTestResult
|
||||
{
|
||||
Id = await sqlDataReader.GetIntAsync(0),
|
||||
PcbId = await sqlDataReader.GetIntAsync(1),
|
||||
AvgPressureInBar = await sqlDataReader.GetFloatAsync(2),
|
||||
TestPassed = await sqlDataReader.GetBoolAsync(3),
|
||||
TestDate = await sqlDataReader.GetDateTimeAsync(4),
|
||||
});
|
||||
}
|
||||
|
||||
if (actionResult is null)
|
||||
{
|
||||
actionResult = this.Json(testResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return actionResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
namespace Xylem.Common.Service.MeterProcessState.Extensions
|
||||
{
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public static class SqlDataReaderExtensions
|
||||
{
|
||||
public static async Task<int> GetIntAsync(this SqlDataReader sqlDataReader, int index)
|
||||
{
|
||||
if (await sqlDataReader.IsDBNullAsync(index))
|
||||
{
|
||||
return default(int);
|
||||
}
|
||||
|
||||
return sqlDataReader.GetInt32(index);
|
||||
}
|
||||
|
||||
public static async Task<long> GetLongAsync(this SqlDataReader sqlDataReader, int index)
|
||||
{
|
||||
if (await sqlDataReader.IsDBNullAsync(index))
|
||||
{
|
||||
return default(long);
|
||||
}
|
||||
|
||||
return sqlDataReader.GetInt64(index);
|
||||
}
|
||||
|
||||
public static async Task<DateTime> GetDateTimeAsync(this SqlDataReader sqlDataReader, int index)
|
||||
{
|
||||
if (await sqlDataReader.IsDBNullAsync(index))
|
||||
{
|
||||
return default(DateTime);
|
||||
}
|
||||
|
||||
return sqlDataReader.GetSqlDateTime(index).Value;
|
||||
}
|
||||
|
||||
public static async Task<float> GetFloatAsync(this SqlDataReader sqlDataReader, int index)
|
||||
{
|
||||
if (await sqlDataReader.IsDBNullAsync(index))
|
||||
{
|
||||
return default(float);
|
||||
}
|
||||
|
||||
return sqlDataReader.GetFloat(index);
|
||||
}
|
||||
|
||||
public static async Task<double> GetDoubleAsync(this SqlDataReader sqlDataReader, int index)
|
||||
{
|
||||
if (await sqlDataReader.IsDBNullAsync(index))
|
||||
{
|
||||
return default(double);
|
||||
}
|
||||
|
||||
return sqlDataReader.GetDouble(index);
|
||||
}
|
||||
|
||||
public static async Task<bool> GetBoolAsync(this SqlDataReader sqlDataReader, int index)
|
||||
{
|
||||
if (await sqlDataReader.IsDBNullAsync(index))
|
||||
{
|
||||
return default(bool);
|
||||
}
|
||||
|
||||
return sqlDataReader.GetBoolean(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Optimization;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Service.MeterProcessState
|
||||
namespace Service.MeterProcessState
|
||||
{
|
||||
public class WebApiApplication : System.Web.HttpApplication
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Optimization;
|
||||
using System.Web.Routing;
|
||||
|
||||
public class WebApiApplication : HttpApplication
|
||||
{
|
||||
protected void Application_Start()
|
||||
{
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.Net.Compilers.3.2.1\build\Microsoft.Net.Compilers.props" Condition="Exists('..\..\packages\Microsoft.Net.Compilers.3.2.1\build\Microsoft.Net.Compilers.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@ -38,6 +37,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<LangVersion>7</LangVersion>
|
||||
<DocumentationFile>bin\Xylem.Common.Service.MeterProcessState.xml</DocumentationFile>
|
||||
<NoWarn>0049;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@ -49,8 +49,8 @@
|
||||
<LangVersion>7</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
|
||||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\lib\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
@ -186,6 +186,7 @@
|
||||
<Compile Include="..\..\.shared\SharedAssemblyInfo.cs">
|
||||
<Link>Properties\SharedAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Appsettings.cs" />
|
||||
<Compile Include="App_Start\BundleConfig.cs" />
|
||||
<Compile Include="App_Start\FilterConfig.cs" />
|
||||
<Compile Include="App_Start\IdentityConfig.cs" />
|
||||
@ -221,12 +222,14 @@
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\SampleDirection.cs" />
|
||||
<Compile Include="Areas\HelpPage\SampleGeneration\TextSample.cs" />
|
||||
<Compile Include="Areas\HelpPage\XmlDocumentationProvider.cs" />
|
||||
<Compile Include="Controllers\CordonelPressureSensorTestController.cs" />
|
||||
<Compile Include="Controllers\PushControler.cs" />
|
||||
<Compile Include="Controllers\FinalCheckController.cs" />
|
||||
<Compile Include="Controllers\FileUpToDateController.cs" />
|
||||
<Compile Include="Controllers\LUTController.cs" />
|
||||
<Compile Include="Controllers\FwUpdateController.cs" />
|
||||
<Compile Include="Controllers\EasyAccessControler.cs" />
|
||||
<Compile Include="Extensions\SqlDataReaderExtensions.cs" />
|
||||
<Compile Include="Controllers\TestBenchController.cs" />
|
||||
<Compile Include="Controllers\MarriageController.cs" />
|
||||
<Compile Include="Controllers\OrderController.cs" />
|
||||
@ -278,6 +281,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Models\AccountBindingModels.cs" />
|
||||
<Compile Include="Models\AccountViewModels.cs" />
|
||||
<Compile Include="Models\Cordonel.cs" />
|
||||
<Compile Include="Models\IdentityModels.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Providers\ApplicationOAuthProvider.cs" />
|
||||
@ -312,6 +316,9 @@
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\CollectionModelDescription.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\DisplayTemplates\ApiGroup.cshtml" />
|
||||
<Content Include="Areas\HelpPage\Views\Help\Api.cshtml" />
|
||||
<Content Include="Content\JSON\CordonelTestSpec.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="Properties\PublishProfiles\a.pubxml" />
|
||||
<None Include="Scripts\jquery-1.10.2.intellisense.js" />
|
||||
<Content Include="Scripts\jquery-1.10.2.js" />
|
||||
@ -343,7 +350,7 @@
|
||||
<Content Include="Views\Shared\_Layout.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
<Folder Include="Views\CordonelPressureSensorTest\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="fonts\glyphicons-halflings-regular.woff" />
|
||||
@ -482,9 +489,10 @@
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Net.Compilers.3.2.1\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Net.Compilers.3.2.1\build\Microsoft.Net.Compilers.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets" Condition="Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\build\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.targets')" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@ -10,6 +10,14 @@
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
|
||||
<Controller_SelectedScaffolderCategoryPath>root/Controller</Controller_SelectedScaffolderCategoryPath>
|
||||
<WebStackScaffolding_ControllerDialogWidth>600</WebStackScaffolding_ControllerDialogWidth>
|
||||
<WebStackScaffolding_IsLayoutPageSelected>True</WebStackScaffolding_IsLayoutPageSelected>
|
||||
<WebStackScaffolding_IsPartialViewSelected>False</WebStackScaffolding_IsPartialViewSelected>
|
||||
<WebStackScaffolding_IsReferencingScriptLibrariesSelected>True</WebStackScaffolding_IsReferencingScriptLibrariesSelected>
|
||||
<WebStackScaffolding_LayoutPageFile />
|
||||
<WebStackScaffolding_IsAsyncSelected>False</WebStackScaffolding_IsAsyncSelected>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
|
||||
31
Common/Service/MeterProcessState/Models/Cordonel.cs
Normal file
31
Common/Service/MeterProcessState/Models/Cordonel.cs
Normal file
@ -0,0 +1,31 @@
|
||||
namespace Xylem.Common.Service.MeterProcessState.Models
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
public class CordonelTestSpec
|
||||
{
|
||||
public int NumberOfMeasurements { get; set; }
|
||||
|
||||
public int TimeMeasurementsInS { get; set; }
|
||||
|
||||
public float MaxDeviationInBar { get; set; }
|
||||
}
|
||||
|
||||
public class CordonelTestResult
|
||||
{
|
||||
public int? Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int? PcbId { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime? TestDate { get; set; }
|
||||
|
||||
[Required]
|
||||
public float? AvgPressureInBar { get; set; }
|
||||
|
||||
[Required]
|
||||
public bool? TestPassed { get; set; }
|
||||
}
|
||||
}
|
||||
@ -4,15 +4,17 @@
|
||||
http://go.microsoft.com/fwlink/?LinkId=301879
|
||||
-->
|
||||
<configuration>
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<appSettings />
|
||||
<connectionStrings>
|
||||
<add name="Default" connectionString="Data Source=SLASQL01.emea.sensus.net;;Initial Catalog=Auftrag;Persist Security Info=False;User ID=GenesisPasswordService;Password=PcbID;Connection Timeout=120" providerName="System.Data.SqlClient" />
|
||||
</connectionStrings>
|
||||
<!--
|
||||
<configSections>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<appSettings>
|
||||
<add key="CordonelTestSpecJson" value="~/Content/JSON/CordonelTestSpec.json" />
|
||||
</appSettings>
|
||||
<connectionStrings>
|
||||
<add name="Default" connectionString="Data Source=SLASQL01.emea.sensus.net;;Initial Catalog=Auftrag;Persist Security Info=False;User ID=GenesisPasswordService;Password=PcbID;Connection Timeout=120" providerName="System.Data.SqlClient" />
|
||||
</connectionStrings>
|
||||
<!--
|
||||
For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.
|
||||
|
||||
The following attributes can be set on the <httpRuntime> tag.
|
||||
@ -20,84 +22,84 @@
|
||||
<httpRuntime targetFramework="4.7.2" />
|
||||
</system.Web>
|
||||
-->
|
||||
<system.web>
|
||||
<authentication mode="None" />
|
||||
<compilation debug="true" targetFramework="4.7.2" />
|
||||
<httpRuntime targetFramework="4.6" />
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<modules>
|
||||
<remove name="FormsAuthentication" />
|
||||
</modules>
|
||||
<handlers>
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
|
||||
<remove name="OPTIONSVerbHandler" />
|
||||
<remove name="TRACEVerbHandler" />
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<entityFramework>
|
||||
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" />
|
||||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" />
|
||||
</compilers>
|
||||
</system.codedom>
|
||||
<system.web>
|
||||
<authentication mode="None" />
|
||||
<compilation debug="true" targetFramework="4.7.2" />
|
||||
<httpRuntime targetFramework="4.6" />
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<modules>
|
||||
<remove name="FormsAuthentication" />
|
||||
</modules>
|
||||
<handlers>
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
|
||||
<remove name="OPTIONSVerbHandler" />
|
||||
<remove name="TRACEVerbHandler" />
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<entityFramework>
|
||||
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701;612;618" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008,40000,40008 /define:_MYTYPE=\"Web\" /optionInfer+" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
</compilers>
|
||||
</system.codedom>
|
||||
</configuration>
|
||||
@ -19,7 +19,7 @@
|
||||
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net46" />
|
||||
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net46" />
|
||||
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net46" />
|
||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net46" />
|
||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="4.1.0" targetFramework="net472" />
|
||||
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net46" />
|
||||
<package id="Microsoft.Net.Compilers" version="3.2.1" targetFramework="net46" developmentDependency="true" />
|
||||
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net46" />
|
||||
|
||||
@ -1 +1 @@
|
||||
f64d563def603c89cafafa61a3219ba97e1e344c
|
||||
ac0776a643239630cd5909e36516a0bfa05cb113
|
||||
|
||||
@ -16,4 +16,12 @@ namespace XylemCommonUiLegacyGenCtl.DataPackage
|
||||
public bool PreAdjustment { get; set; }
|
||||
public bool FlowTesting { get; set; }
|
||||
}
|
||||
|
||||
public class MeterTestResults
|
||||
{
|
||||
public MeterTypes meterType { get; set; }
|
||||
public int Slot { get; set; }
|
||||
public string SerialNr { get; set; }
|
||||
public List<MagfluxDiviations> Results { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,5 +18,9 @@ namespace XylemCommonUiLegacyGenCtl.DataPackage
|
||||
public bool ProductionMode { get; set; }
|
||||
|
||||
public MeterTestSettings[] meterTestSettings { get; set; }
|
||||
|
||||
public MeterTestResults[] meterTestResults { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1612,6 +1612,7 @@ namespace XylemCommonUiLegacyGenCtl
|
||||
updateCellToInput("Zielwert Justage [%]", baseMeter.Slot, false);
|
||||
updateCell("Zielwert Justage [%]", baseMeter.Slot, (Double)settings.FlowAdjustmentTarget, 2, Color.Beige);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
namespace LaaProductionWeb.API.Controllers
|
||||
{
|
||||
using LaaProductionWeb.API.Models.SMTP;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class EmailController : ControllerBase
|
||||
{
|
||||
private readonly SMTPClient smtp;
|
||||
|
||||
public EmailController(SMTPClient smtp)
|
||||
=> this.smtp = smtp;
|
||||
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
await this.smtp.SendAsync("Test", "It works!!!", "stoyan.zlatev@xylem.com", new[] { "roland.drabesch@xylem.com", "stoyan.zlatev@xylem.com" });
|
||||
|
||||
return this.Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.2" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.9" />
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
namespace LaaProductionWeb.API.Models.SMTP
|
||||
{
|
||||
using MailKit.Net.Smtp;
|
||||
using MimeKit;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mail;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class SMTPClient
|
||||
@ -20,26 +17,26 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = new SmtpClient())
|
||||
using (var client = new SmtpClient(settings.Host, settings.Port))
|
||||
{
|
||||
await client.AuthenticateAsync(this.settings.Username, this.settings.Password);
|
||||
await client.ConnectAsync(this.settings.Host, this.settings.Port);
|
||||
client.Host = this.settings.Host;
|
||||
client.Port = this.settings.Port;
|
||||
client.UseDefaultCredentials = true;
|
||||
|
||||
var message = new MimeMessage
|
||||
var message = new MailMessage
|
||||
{
|
||||
From = new MailAddress(from),
|
||||
Subject = subject,
|
||||
Body = new BodyBuilder
|
||||
{
|
||||
HtmlBody = body
|
||||
}.ToMessageBody(),
|
||||
Body = body,
|
||||
IsBodyHtml = true,
|
||||
};
|
||||
message.From.Add(MailboxAddress.Parse(from));
|
||||
message.To.Add(MailboxAddress.Parse(to.FirstOrDefault()));
|
||||
message.Cc.AddRange(to.Skip(1).Select(x => MailboxAddress.Parse(x)));
|
||||
|
||||
var response = await client.SendAsync(message);
|
||||
|
||||
File.AppendAllLines("smtp.log", new[] { $"[SMTP_RESPONSE] {response}" });
|
||||
foreach (var email in to)
|
||||
{
|
||||
message.To.Add(email);
|
||||
}
|
||||
|
||||
await client.SendMailAsync(message);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
{
|
||||
options.SuppressModelStateInvalidFilter = true;
|
||||
});
|
||||
services.Configure<SMTPSettings>(this.configuration);
|
||||
services.Configure<SMTPSettings>(this.configuration.GetSection(nameof(SMTPSettings)));
|
||||
services
|
||||
.AddMvc()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
namespace LaaProductionWeb.Data.Interfaces
|
||||
using System;
|
||||
|
||||
namespace LaaProductionWeb.Data.Interfaces
|
||||
{
|
||||
public interface ISqlReader
|
||||
{
|
||||
bool GetBool(int index = -1);
|
||||
|
||||
byte[] GetBytes(int index = -1);
|
||||
|
||||
DateTime GetDate(int index = -1);
|
||||
|
||||
int GetInt(int index = -1);
|
||||
|
||||
long GetLong(int index = -1);
|
||||
|
||||
short GetSmallint(int index = -1);
|
||||
|
||||
string GetString(int index = -1);
|
||||
|
||||
@ -4,53 +4,35 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
public class SQLCommand
|
||||
{
|
||||
private readonly SqlClient sqlClient;
|
||||
private readonly ICollection<SqlParameter> parameters;
|
||||
private readonly IDictionary<string, object> parameters;
|
||||
|
||||
public SQLCommand(SqlClient sqlClient, string commandText)
|
||||
{
|
||||
this.sqlClient = sqlClient;
|
||||
this.CommandText = commandText;
|
||||
this.parameters = new List<SqlParameter>();
|
||||
this.parameters = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
internal string CommandText { get; }
|
||||
|
||||
internal SqlParameter[] Parameters
|
||||
=> this.parameters.ToArray();
|
||||
internal IReadOnlyDictionary<string, object> Parameters
|
||||
=> this.parameters as IReadOnlyDictionary<string, object>;
|
||||
|
||||
public SQLCommand AddParameter(string name, object value)
|
||||
{
|
||||
this.parameters.Add(new SqlParameter(name, value ?? DBNull.Value));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLCommand AddParameter(string name, byte[] fileContent)
|
||||
{
|
||||
var sqlParameter = new SqlParameter(name, SqlDbType.VarBinary);
|
||||
|
||||
if (fileContent is null)
|
||||
{
|
||||
sqlParameter.Value = DBNull.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlParameter.Value = fileContent;
|
||||
}
|
||||
|
||||
this.parameters.Add(sqlParameter);
|
||||
this.parameters[name] = value ?? DBNull.Value;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public T FirstOrDefault<T>(Func<ISqlReader, T> expression)
|
||||
=> this.sqlClient.FirstOrDefault<T>(this, expression);
|
||||
=> this.sqlClient.FirstOrDefault(this, expression);
|
||||
|
||||
public IEnumerable<T> ExecuteReader<T>(Func<ISqlReader, T> expression)
|
||||
=> this.sqlClient.ExecuteReader(this, expression);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,21 @@
|
||||
{
|
||||
private readonly string connectionString;
|
||||
|
||||
public SqlClient(string connectionString)
|
||||
=> this.connectionString = connectionString;
|
||||
public SqlClient(string connectionString)
|
||||
{
|
||||
this.connectionString = connectionString;
|
||||
|
||||
#if DEBUG
|
||||
//var connectionBuilder = new SqlConnectionStringBuilder(connectionString);
|
||||
//connectionBuilder.PersistSecurityInfo = false;
|
||||
//connectionBuilder.Password = string.Empty;
|
||||
//connectionBuilder.UserID = string.Empty;
|
||||
//connectionBuilder.IntegratedSecurity = true;
|
||||
//connectionBuilder.InitialCatalog = "AuftragKopie";
|
||||
|
||||
//this.connectionString = connectionBuilder.ToString();
|
||||
#endif
|
||||
}
|
||||
|
||||
public SQLCommand CreateCommand(string commandText)
|
||||
=> new SQLCommand(this, commandText);
|
||||
@ -37,6 +50,36 @@
|
||||
return rowsAffected;
|
||||
}
|
||||
|
||||
internal IEnumerable<T> ExecuteReader<T>(SQLCommand command, Func<ISqlReader, T> expression)
|
||||
{
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenWithErrorHandling();
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = command.CommandText;
|
||||
|
||||
foreach (var kvp in command.Parameters)
|
||||
{
|
||||
var param = sqlCommand.CreateParameter();
|
||||
param.ParameterName = kvp.Key;
|
||||
param.Value = kvp.Value;
|
||||
|
||||
sqlCommand.Parameters.Add(param);
|
||||
}
|
||||
|
||||
using (SqlReader sqlReader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess))
|
||||
{
|
||||
while (sqlReader.Read())
|
||||
{
|
||||
yield return expression(sqlReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<T> ExecuteReader<T>(string query, Func<ISqlReader, T> reader, SqlInfoMessageEventHandler errorCallback = null)
|
||||
{
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
@ -167,7 +210,14 @@
|
||||
{
|
||||
sqlCommand.CommandText = command.CommandText;
|
||||
|
||||
sqlCommand.Parameters.AddRange(command.Parameters);
|
||||
foreach (var kvp in command.Parameters)
|
||||
{
|
||||
var param = sqlCommand.CreateParameter();
|
||||
param.ParameterName = kvp.Key;
|
||||
param.Value = kvp.Value;
|
||||
|
||||
sqlCommand.Parameters.Add(param);
|
||||
}
|
||||
|
||||
using (SqlReader sqlReader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess))
|
||||
{
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
using LaaProductionWeb.Data.Interfaces;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using System;
|
||||
|
||||
using System.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
@ -46,16 +45,7 @@
|
||||
|
||||
internal static void SqlConnectionInfoMessage(object sender, SqlInfoMessageEventArgs e)
|
||||
{
|
||||
Debug.WriteLine(e);
|
||||
|
||||
Log($"[{DateTime.Now: hh:mm:ss}] Error: {e.Source} - {e.Message}{Environment.NewLine}{string.Join(Environment.NewLine, e.Errors)}");
|
||||
|
||||
// TODO: Handle errors
|
||||
}
|
||||
|
||||
internal static void Log(string message)
|
||||
{
|
||||
// File.AppendAllText($"{Environment.CurrentDirectory}/App_Data/{DateTime.Now:yyyy_MM_dd}.log", $"{Environment.NewLine}{message}{Environment.NewLine}");
|
||||
Debug.Write(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,21 @@
|
||||
this.sqlDataReader.Dispose();
|
||||
}
|
||||
|
||||
public bool GetBool(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = this.column++;
|
||||
}
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
return this.sqlDataReader.GetBoolean(index);
|
||||
}
|
||||
|
||||
return default(bool);
|
||||
}
|
||||
|
||||
public byte[] GetBytes(int index = -1)
|
||||
{
|
||||
var bytes = default(byte[]);
|
||||
@ -56,6 +71,51 @@
|
||||
internal string[] GetColumns()
|
||||
=> this.columns.Keys.ToArray();
|
||||
|
||||
public DateTime GetDate(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = this.column++;
|
||||
}
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
return this.sqlDataReader.GetDateTime(index);
|
||||
}
|
||||
|
||||
return default(DateTime);
|
||||
}
|
||||
|
||||
public int GetInt(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = this.column++;
|
||||
}
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
return this.sqlDataReader.GetInt32(index);
|
||||
}
|
||||
|
||||
return default(int);
|
||||
}
|
||||
|
||||
public long GetLong(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = this.column++;
|
||||
}
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
return this.sqlDataReader.GetInt64(index);
|
||||
}
|
||||
|
||||
return default(long);
|
||||
}
|
||||
|
||||
public string GetString(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
@ -116,21 +176,6 @@
|
||||
return default(object);
|
||||
}
|
||||
|
||||
public int GetInt(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = this.column++;
|
||||
}
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(index))
|
||||
{
|
||||
return this.sqlDataReader.GetInt32(index);
|
||||
}
|
||||
|
||||
return default(int);
|
||||
}
|
||||
|
||||
public short GetSmallint(int index = -1)
|
||||
{
|
||||
if (index < 0)
|
||||
|
||||
@ -11,7 +11,9 @@
|
||||
|
||||
PalletsBatchModel LoadBatchModel(OrderScanModel model);
|
||||
|
||||
IEnumerable<int> LoadPallets(OrderScanModel model);
|
||||
OrderScanModel LoadPallets(OrderScanModel model);
|
||||
|
||||
IEnumerable<MissingItem> MissingItems();
|
||||
|
||||
Result UpdateBatchModel(OrderScanModel model);
|
||||
}
|
||||
|
||||
@ -63,6 +63,7 @@
|
||||
<Compile Include="Interfaces\ITransient.cs" />
|
||||
<Compile Include="Models\Employee.cs" />
|
||||
<Compile Include="Models\HttpResponseModel.cs" />
|
||||
<Compile Include="Models\MissingItem.cs" />
|
||||
<Compile Include="Models\Reports\HeliumPressurePoint.cs" />
|
||||
<Compile Include="Models\Reports\HeliumReportFilter.cs" />
|
||||
<Compile Include="Models\Reports\KottmannReportFilter.cs" />
|
||||
|
||||
@ -16,6 +16,14 @@
|
||||
public int OrderNr
|
||||
=> this.batchModel.OrderNr;
|
||||
|
||||
public int PalletNr
|
||||
=> this.batchModel
|
||||
.Positions
|
||||
?.FirstOrDefault()
|
||||
?.Items
|
||||
?.FirstOrDefault()
|
||||
?.PalletNr ?? 0;
|
||||
|
||||
public int ProductionOrderNr
|
||||
=> this.batchModel.ProductionOrderNr;
|
||||
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
namespace LaaProductionWeb.Services.Models
|
||||
{
|
||||
using System;
|
||||
|
||||
public class MissingItem
|
||||
{
|
||||
public DateTime EntryDate { get; set; }
|
||||
|
||||
public int OrderNr { get; set; }
|
||||
|
||||
public int PosNr { get; set; }
|
||||
|
||||
public int SerialNr { get; set; }
|
||||
|
||||
public string CustomSerial { get; set; }
|
||||
|
||||
public string Term { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,9 @@
|
||||
|
||||
[Required]
|
||||
public int? OrderNr { get; set; }
|
||||
|
||||
|
||||
|
||||
[Display(Name = "Positions-Nr. auswählen")]
|
||||
public int? PositionNr { get; set; }
|
||||
|
||||
[Required]
|
||||
|
||||
@ -14,7 +14,10 @@
|
||||
public int PalletsCount { get; set; }
|
||||
|
||||
[Display(Name = "Paletten-Nr.")]
|
||||
public int PalletNr { get; set; }
|
||||
public int? PalletNr { get; set; }
|
||||
|
||||
public IEnumerable<int> Positions { get; set; }
|
||||
= Array.Empty<int>();
|
||||
|
||||
public IDictionary<int, bool> Pallets { get; set; }
|
||||
= new Dictionary<int, bool> { { 1, false } };
|
||||
@ -22,21 +25,28 @@
|
||||
public string PrintUrl
|
||||
=> $"~/Shipments/Print?ordernr={this.OrderNr}&positionnr={this.PositionNr}&palletnr={this.PalletNr}";
|
||||
|
||||
public string PalletUrl
|
||||
=> $"~/Shipments/Pallet?ordernr={this.OrderNr}&positionnr={this.PositionNr}";
|
||||
public string PalletUrl(int? palletNr)
|
||||
=> $"~/Shipments/Pallet?ordernr={this.OrderNr}&positionnr={this.PositionNr}&palletnr={palletNr}";
|
||||
|
||||
public void UpdatePallets(IEnumerable<int> pallets)
|
||||
internal void UpdatePallets(IEnumerable<KeyValuePair<int, bool>> pallets)
|
||||
{
|
||||
this.Pallets = pallets.ToDictionary(x => x, x => x == this.PalletNr);
|
||||
this.Pallets = pallets.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
if (this.PalletNr == 0)
|
||||
if (this.PalletNr is null || this.PalletNr == 0)
|
||||
{
|
||||
this.PalletNr = Math.Max(this.Pallets.Keys.LastOrDefault(), 1);
|
||||
}
|
||||
|
||||
if (!this.Pallets.ContainsKey(this.PalletNr))
|
||||
{
|
||||
this.Pallets[this.PalletNr] = true;
|
||||
if (pallets.Any(x => x.Value))
|
||||
{
|
||||
this.PalletNr = Math.Max(pallets
|
||||
.Where(x => x.Value)
|
||||
.OrderByDescending(x => x.Key)
|
||||
.FirstOrDefault().Key, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.PalletNr = Math.Max(pallets
|
||||
.OrderByDescending(x => x.Key)
|
||||
.FirstOrDefault().Key, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,16 +4,16 @@
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int Nr { get; set; }
|
||||
public int Serial { get; set; }
|
||||
|
||||
public int PositionNr { get; set; }
|
||||
|
||||
public int? PalletNr { get; set; }
|
||||
|
||||
public string CustomerNr { get; set; }
|
||||
public string CustomerSerial { get; set; }
|
||||
|
||||
public bool IsScaned { get; set; }
|
||||
public bool IsScanned { get; set; }
|
||||
|
||||
public string BarcodeNr => this.CustomerNr ?? $"{this.Nr}";
|
||||
public string BarcodeNr => this.CustomerSerial ?? $"{this.Serial}";
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,9 @@
|
||||
public class ShipmentModel
|
||||
{
|
||||
public readonly string BtnSubmit = "Auftrag suchen";
|
||||
private readonly OrderModel orderModel;
|
||||
|
||||
private readonly int? palletNr;
|
||||
private readonly int? positionNr;
|
||||
|
||||
public ShipmentModel() { }
|
||||
|
||||
@ -13,36 +15,22 @@
|
||||
{
|
||||
if (orderModel != null)
|
||||
{
|
||||
this.orderModel = orderModel;
|
||||
this.OrderNr = orderModel.OrderNr;
|
||||
this.PositionNr = orderModel.PositionNr;
|
||||
this.positionNr = orderModel.PositionNr;
|
||||
this.palletNr = orderModel.PalletNr;
|
||||
}
|
||||
}
|
||||
|
||||
[Required(ErrorMessage = "Auftrags-Nr. ist erforderlich!")]
|
||||
[Display(Name = "Auftrags-Nr. scanen oder eingeben")]
|
||||
public int? OrderNr { get; set; }
|
||||
|
||||
[Display(Name = "Positions-Nr. auswählen")]
|
||||
public int? PositionNr { get; set; }
|
||||
|
||||
public bool HasOrder
|
||||
=> this.orderModel != null && this.orderModel.OrderNr > 0;
|
||||
|
||||
public OrderModel OrderModel
|
||||
=> this.orderModel
|
||||
?? new OrderModel
|
||||
public OrderScanModel OrderScanModel
|
||||
=> new OrderScanModel
|
||||
{
|
||||
OrderNr = this.OrderNr,
|
||||
PositionNr = this.PositionNr
|
||||
};
|
||||
|
||||
public OrderModel OrderScanModel
|
||||
=> this.orderModel
|
||||
?? new OrderScanModel
|
||||
{
|
||||
OrderNr = this.OrderNr,
|
||||
PositionNr = this.PositionNr
|
||||
PalletNr = this.palletNr,
|
||||
PositionNr = this.positionNr
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -17,16 +17,21 @@
|
||||
=> this.sqlClient = sqlClient;
|
||||
|
||||
public OrderScanModel DeletePalletEntry(int id)
|
||||
{
|
||||
var orderScanModel = this.DeletePalletEntryById(id);
|
||||
|
||||
if (orderScanModel != null)
|
||||
{
|
||||
var updated = this.UpdatePalletsNr(orderScanModel.OrderNr ?? 0);
|
||||
}
|
||||
|
||||
return orderScanModel;
|
||||
}
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
DELETE
|
||||
FROM [PalettenScan]
|
||||
OUTPUT [deleted].[AuftragNr]
|
||||
, [deleted].[PositionNr]
|
||||
, [deleted].[PalettenNr]
|
||||
WHERE [ID] = @{nameof(id)}")
|
||||
.AddParameter(nameof(id), id)
|
||||
.FirstOrDefault(x => new OrderScanModel
|
||||
{
|
||||
OrderNr = x.GetInt(),
|
||||
PositionNr = x.GetInt(),
|
||||
PalletNr = x.GetSmallint()
|
||||
});
|
||||
|
||||
public byte[] LoadBatchBuffer(OrderScanModel model)
|
||||
{
|
||||
@ -56,41 +61,368 @@
|
||||
public PalletsBatchModel LoadBatchModel(OrderScanModel model)
|
||||
{
|
||||
var batchModel = new PalletsBatchModel();
|
||||
var pallets = this.LoadPallets(model);
|
||||
model.UpdatePallets(pallets);
|
||||
|
||||
if (model != null && model.OrderNr != null)
|
||||
{
|
||||
var palletNo = this.PalletsNr(model);
|
||||
var orderNo = model.OrderNr.Value;
|
||||
var positionNo = model.PositionNr > 0 ? model.PositionNr : null;
|
||||
var palletNo = model.PalletNr > 0 ? model.PalletNr : null;
|
||||
|
||||
batchModel = this.LoadBatchModel(model.OrderNr, model.PositionNr, palletNo);
|
||||
batchModel = this.LoadBatchModel(orderNo, positionNo, palletNo);
|
||||
|
||||
if (model.PositionNr != null && !batchModel.Positions.Any())
|
||||
if (positionNo is null)
|
||||
{
|
||||
batchModel = this.LoadBatchModel(model.OrderNr, model.PositionNr, null);
|
||||
if (this.PalletNrExists(orderNo, palletNo))
|
||||
{
|
||||
batchModel.Positions = this.LoadPalletPositions(orderNo, palletNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
batchModel.Positions = this.LoadLastPalletPositions(orderNo);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.SamePallet(orderNo, positionNo, palletNo))
|
||||
{
|
||||
batchModel.Positions = this.LoadPalletPosition(orderNo, positionNo, palletNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
batchModel.Positions = this.LoadLastPalletPosition(orderNo, positionNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return batchModel;
|
||||
}
|
||||
|
||||
private int? PalletsNr(OrderScanModel model)
|
||||
{
|
||||
var palletNr = this.sqlClient.FirstOrDefault(
|
||||
query: $@"
|
||||
SELECT [PalettenNr]
|
||||
FROM [PalettenScan]
|
||||
WHERE [AuftragNr] = @{nameof(model.OrderNr)}
|
||||
AND [PalettenNr] = @{nameof(model.PalletNr)}",
|
||||
parameters: parameters => parameters
|
||||
.Add(nameof(model.OrderNr), model.OrderNr)
|
||||
.Add(nameof(model.PalletNr), model.PalletNr),
|
||||
reader: reader => reader.GetSmallint());
|
||||
public IEnumerable<MissingItem> MissingItems()
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
DECLARE @PalletOrders TABLE([OrderNo] INT NOT NULL)
|
||||
INSERT INTO @PalletOrders([OrderNo])
|
||||
SELECT DISTINCT [AuftragNr] FROM [PalettenScan]
|
||||
|
||||
return palletNr > 0 ? (int?)palletNr : null;
|
||||
SELECT [result].[Date]
|
||||
, [result].[OrderNo]
|
||||
, [result].[PosNo]
|
||||
, [result].[SerialNo]
|
||||
, [result].[CustomSerial]
|
||||
, [result].[Bezeichnung]
|
||||
, [result].[Type]
|
||||
FROM (SELECT DISTINCT
|
||||
CAST(MAX([x].[Date]) AS DATE) AS [Date]
|
||||
, [x].[OrderNo]
|
||||
, [x].[PosNo]
|
||||
, [x].[SerialNo]
|
||||
, [dbo].[NORMALIZE_SERIAL]([x].[CustomSerialNo]) AS [CustomSerial]
|
||||
, ([inr].[Typ]
|
||||
+ ' '
|
||||
+ CASE WHEN [inr].[Typzusatz] IS NULL
|
||||
THEN CAST([inr].[Nennweite] AS NVARCHAR(100))
|
||||
ELSE [inr].[Typzusatz]
|
||||
+ ' '
|
||||
+ CAST([inr].[Nennweite] AS NVARCHAR(100))
|
||||
END) AS [Type]
|
||||
, [inr].[Bezeichnung]
|
||||
FROM (SELECT CAST([aps].[AnlageDatum] AS DATE) AS [Date]
|
||||
, [aps].[AuftragNr] AS [OrderNo]
|
||||
, [aps].[PositionNr] AS [PosNo]
|
||||
, [aps].[SerienNr] AS [SerialNo]
|
||||
, ISNULL([aps].[KundeneigeneSerienNr], [aps].[SerienNr]) AS [CustomSerialNo]
|
||||
FROM [AuftragPositionSerienNr] AS [aps]
|
||||
JOIN @PalletOrders AS [po]
|
||||
ON [po].[OrderNo] = [aps].[AuftragNr]
|
||||
LEFT JOIN [PalettenScan] AS [ps]
|
||||
ON [ps].[AuftragNr] = [aps].[AuftragNr]
|
||||
AND [ps].[PositionNr] = [aps].[PositionNr]
|
||||
AND [ps].[SerienNr] = [dbo].[NORMALIZE_SERIAL]([aps].[KundeneigeneSerienNr])
|
||||
WHERE [ps].[SerienNr] IS NULL)
|
||||
AS [x]
|
||||
JOIN [AlleAuftragPositionen] AS [aap]
|
||||
ON [aap].[AuftragNr] = [x].[OrderNo]
|
||||
AND [aap].[PositionNr] = [x].[PosNo]
|
||||
JOIN [Identnr] AS [inr]
|
||||
ON [inr].[IdentNr] = [aap].[IdentNr]
|
||||
GROUP BY [x].[OrderNo]
|
||||
, [x].[PosNo]
|
||||
, [x].[SerialNo]
|
||||
, [x].[CustomSerialNo]
|
||||
, [inr].[Typ]
|
||||
, [inr].[Typzusatz]
|
||||
, [inr].[Nennweite]
|
||||
, [inr].[Bezeichnung])
|
||||
AS [result]
|
||||
ORDER BY [result].[OrderNo] DESC")
|
||||
.ExecuteReader(x => new MissingItem
|
||||
{
|
||||
EntryDate = x.GetDate(),
|
||||
OrderNr = x.GetInt(),
|
||||
PosNr = x.GetSmallint(),
|
||||
SerialNr = x.GetInt(),
|
||||
CustomSerial = x.GetString(),
|
||||
Term = x.GetString(),
|
||||
Type = x.GetString()
|
||||
});
|
||||
|
||||
private bool PalletNrExists(int orderNo, int? palletNo)
|
||||
{
|
||||
var countPalletsByNo = this.sqlClient
|
||||
.CreateCommand($@"
|
||||
SELECT ISNULL(COUNT(1), 0) AS [Found]
|
||||
FROM [PalettenScan] AS [PS]
|
||||
WHERE [PS].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND [PS].[PalettenNr] = @{nameof(palletNo)}")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.AddParameter(nameof(palletNo), palletNo)
|
||||
.FirstOrDefault(x => x.GetInt());
|
||||
|
||||
return countPalletsByNo > 0;
|
||||
}
|
||||
|
||||
private PalletsBatchModel LoadBatchModel(int? orderNo, int? posNo, int? palletNo)
|
||||
private IEnumerable<PalletPosition> LoadLastPalletPositions(int orderNo)
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
DECLARE @palettenNr INT;
|
||||
|
||||
SELECT @palettenNr = MAX([PalettenNr])
|
||||
FROM [PalettenScan]
|
||||
WHERE [AuftragNr] = @{nameof(orderNo)}
|
||||
|
||||
SELECT DISTINCT
|
||||
[aap].[PositionNr] AS [Pos]
|
||||
, [in].[Typ] AS [Typ]
|
||||
, [in].[Typzusatz] AS [Typzusatz]
|
||||
, [in].[Nennweite] AS [Nennweite]
|
||||
, (SELECT COUNT(1)
|
||||
FROM [PalettenScan] AS [x]
|
||||
WHERE [x].[AuftragNr] = [ps].[AuftragNr]
|
||||
AND [x].[PositionNr] = [ps].[PositionNr]
|
||||
AND [x].[PalettenNr] = [ps].[PalettenNr])
|
||||
, (SELECT TOP 1 [Menge]
|
||||
FROM [AlleAuftragPositionen] AS [x]
|
||||
WHERE [x].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [x].[PositionNr] = [aap].[PositionNr])
|
||||
, [aap].[AuftragNr]
|
||||
, [aap].[PositionNr]
|
||||
, [ps].[PalettenNr]
|
||||
FROM [Identnr] AS [in]
|
||||
JOIN [AlleAuftragPositionen] AS [aap]
|
||||
ON [aap].[IdentNr] = [in].[IdentNr]
|
||||
LEFT JOIN [PalettenScan] AS [ps]
|
||||
ON [ps].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [ps].[PositionNr] = [aap].[PositionNr]
|
||||
WHERE [aap].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND [ps].[PalettenNr] = @palettenNr")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.ExecuteReader(x => new PalletPosition
|
||||
{
|
||||
PositionNr = x.GetSmallint(),
|
||||
Description = string
|
||||
.Join(" ", new[] { x.GetString(), x.GetString(), x.GetString() }
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))),
|
||||
ItemsCount = x.GetInt(),
|
||||
TotalItemsCount = x.GetInt(),
|
||||
Items = this.LoadPalletItems(x.GetInt(), x.GetSmallint(), x.GetSmallint())
|
||||
});
|
||||
|
||||
private IEnumerable<PalletPosition> LoadPalletPositions(int orderNo, int? palletNo)
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
SELECT DISTINCT
|
||||
[aap].[PositionNr] AS [Pos]
|
||||
, [in].[Typ] AS [Typ]
|
||||
, [in].[Typzusatz] AS [Typzusatz]
|
||||
, [in].[Nennweite] AS [Nennweite]
|
||||
, (SELECT COUNT(1)
|
||||
FROM [PalettenScan] AS [x]
|
||||
WHERE [x].[AuftragNr] = [ps].[AuftragNr]
|
||||
AND [x].[PositionNr] = [ps].[PositionNr]
|
||||
AND [x].[PalettenNr] = [ps].[PalettenNr])
|
||||
, (SELECT TOP 1 [Menge]
|
||||
FROM [AlleAuftragPositionen] AS [x]
|
||||
WHERE [x].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [x].[PositionNr] = [aap].[PositionNr])
|
||||
, [aap].[AuftragNr]
|
||||
, [aap].[PositionNr]
|
||||
, [ps].[PalettenNr]
|
||||
FROM [Identnr] AS [in]
|
||||
JOIN [AlleAuftragPositionen] AS [aap]
|
||||
ON [aap].[IdentNr] = [in].[IdentNr]
|
||||
LEFT JOIN [PalettenScan] AS [ps]
|
||||
ON [ps].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [ps].[PositionNr] = [aap].[PositionNr]
|
||||
WHERE [aap].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND [ps].[PalettenNr] = @{nameof(palletNo)}")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.AddParameter(nameof(palletNo), palletNo)
|
||||
.ExecuteReader(x => new PalletPosition
|
||||
{
|
||||
PositionNr = x.GetSmallint(),
|
||||
Description = string
|
||||
.Join(" ", new[] { x.GetString(), x.GetString(), x.GetString() }
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))),
|
||||
ItemsCount = x.GetInt(),
|
||||
TotalItemsCount = x.GetInt(),
|
||||
Items = this.LoadPalletItems(x.GetInt(), x.GetSmallint(), x.GetSmallint())
|
||||
});
|
||||
|
||||
private bool SamePallet(int orderNo, int? positionNo, int? palletNo)
|
||||
{
|
||||
var countPalletsByNo = this.sqlClient
|
||||
.CreateCommand($@"
|
||||
SELECT ISNULL(COUNT(1), 0) AS [Found]
|
||||
FROM [PalettenScan] AS [PS]
|
||||
WHERE [PS].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND [PS].[PositionNr] = @{nameof(positionNo)}
|
||||
AND [PS].[PalettenNr] = @{nameof(palletNo)}")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.AddParameter(nameof(positionNo), positionNo)
|
||||
.AddParameter(nameof(palletNo), palletNo)
|
||||
.FirstOrDefault(x => x.GetInt());
|
||||
|
||||
return countPalletsByNo > 0;
|
||||
}
|
||||
|
||||
private IEnumerable<PalletPosition> LoadLastPalletPosition(int orderNo, int? positionNo)
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
DECLARE @palettenNr INT;
|
||||
|
||||
SELECT @palettenNr = MAX([PalettenNr])
|
||||
FROM [PalettenScan]
|
||||
WHERE [AuftragNr] = @{nameof(orderNo)}
|
||||
AND [PositionNr] = @{nameof(positionNo)}
|
||||
|
||||
SELECT DISTINCT
|
||||
[aap].[PositionNr] AS [Pos]
|
||||
, [in].[Typ] AS [Typ]
|
||||
, [in].[Typzusatz] AS [Typzusatz]
|
||||
, [in].[Nennweite] AS [Nennweite]
|
||||
, (SELECT COUNT(1)
|
||||
FROM [PalettenScan] AS [x]
|
||||
WHERE [x].[AuftragNr] = [ps].[AuftragNr]
|
||||
AND [x].[PositionNr] = [ps].[PositionNr]
|
||||
AND [x].[PalettenNr] = [ps].[PalettenNr])
|
||||
, (SELECT TOP 1 [Menge]
|
||||
FROM [AlleAuftragPositionen] AS [x]
|
||||
WHERE [x].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [x].[PositionNr] = [aap].[PositionNr])
|
||||
, [aap].[AuftragNr]
|
||||
, [aap].[PositionNr]
|
||||
, [ps].[PalettenNr]
|
||||
FROM [Identnr] AS [in]
|
||||
JOIN [AlleAuftragPositionen] AS [aap]
|
||||
ON [aap].[IdentNr] = [in].[IdentNr]
|
||||
LEFT JOIN [PalettenScan] AS [ps]
|
||||
ON [ps].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [ps].[PositionNr] = [aap].[PositionNr]
|
||||
WHERE [aap].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND ([ps].[PalettenNr] = @palettenNr
|
||||
OR [aap].[PositionNr] = @{nameof(positionNo)})")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.AddParameter(nameof(positionNo), positionNo)
|
||||
.ExecuteReader(x => new PalletPosition
|
||||
{
|
||||
PositionNr = x.GetSmallint(),
|
||||
Description = string
|
||||
.Join(" ", new[] { x.GetString(), x.GetString(), x.GetString() }
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))),
|
||||
ItemsCount = x.GetInt(),
|
||||
TotalItemsCount = x.GetInt(),
|
||||
Items = this.LoadPalletItems(x.GetInt(), x.GetSmallint(), x.GetSmallint())
|
||||
});
|
||||
|
||||
private IEnumerable<PalletPosition> LoadPalletPosition(int orderNo, int? positionNo, int? palletNo)
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
SELECT DISTINCT
|
||||
[aap].[PositionNr] AS [Pos]
|
||||
, [in].[Typ] AS [Typ]
|
||||
, [in].[Typzusatz] AS [Typzusatz]
|
||||
, [in].[Nennweite] AS [Nennweite]
|
||||
, (SELECT COUNT(1)
|
||||
FROM [PalettenScan] AS [x]
|
||||
WHERE [x].[AuftragNr] = [ps].[AuftragNr]
|
||||
AND [x].[PositionNr] = [ps].[PositionNr]
|
||||
AND [x].[PalettenNr] = [ps].[PalettenNr])
|
||||
, (SELECT TOP 1 [Menge]
|
||||
FROM [AlleAuftragPositionen] AS [x]
|
||||
WHERE [x].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [x].[PositionNr] = [aap].[PositionNr])
|
||||
, [aap].[AuftragNr]
|
||||
, [aap].[PositionNr]
|
||||
, [ps].[PalettenNr]
|
||||
FROM [Identnr] AS [in]
|
||||
JOIN [AlleAuftragPositionen] AS [aap]
|
||||
ON [aap].[IdentNr] = [in].[IdentNr]
|
||||
LEFT JOIN [PalettenScan] AS [ps]
|
||||
ON [ps].[AuftragNr] = [aap].[AuftragNr]
|
||||
AND [ps].[PositionNr] = [aap].[PositionNr]
|
||||
WHERE [aap].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND [ps].[PositionNr] = @{nameof(positionNo)}
|
||||
AND [ps].[PalettenNr] = @{nameof(palletNo)}")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.AddParameter(nameof(positionNo), positionNo)
|
||||
.AddParameter(nameof(palletNo), palletNo)
|
||||
.ExecuteReader(x => new PalletPosition
|
||||
{
|
||||
PositionNr = x.GetSmallint(),
|
||||
Description = string
|
||||
.Join(" ", new[] { x.GetString(), x.GetString(), x.GetString() }
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))),
|
||||
ItemsCount = x.GetInt(),
|
||||
TotalItemsCount = x.GetInt(),
|
||||
Items = this.LoadPalletItems(x.GetInt(), x.GetSmallint(), x.GetSmallint())
|
||||
});
|
||||
|
||||
private IEnumerable<SerialNr> LoadPalletItems(int orderNo, int posNo, int palletNr)
|
||||
=> this.sqlClient
|
||||
.CreateCommand($@"
|
||||
SELECT [x].[Id] AS [Id]
|
||||
, [x].[PositionNr] AS [Pos]
|
||||
, [x].[Serial] AS [Serial]
|
||||
, [x].[CustomerSerial] AS [CustomerSerial]
|
||||
, [x].[IsScanned] AS [IsScanned]
|
||||
FROM (SELECT DISTINCT
|
||||
[ps].[ID] AS [Id]
|
||||
, [aps].[PositionNr] AS [PositionNr]
|
||||
, [aps].[SerienNr] AS [Serial]
|
||||
, ISNULL([dbo].[NORMALIZE_SERIAL]([aps].[KundeneigeneSerienNr]), [aps].[SerienNr]) AS [CustomerSerial]
|
||||
, CAST(CASE WHEN [ps].[Datum] IS NOT NULL THEN 1 ELSE 0 END AS BIT) AS [IsScanned]
|
||||
, [ps].[Datum] AS [DateAdded]
|
||||
FROM [AuftragPositionSerienNr] AS [aps]
|
||||
LEFT JOIN [PalettenScan] AS [ps]
|
||||
ON [ps].[AuftragNr] = [aps].[AuftragNr]
|
||||
AND [ps].[PositionNr] = [aps].[PositionNr]
|
||||
AND [ps].[SerienNr] = [dbo].[NORMALIZE_SERIAL]([aps].[KundeneigeneSerienNr])
|
||||
AND [ps].[PalettenNr] = @{nameof(palletNr)}
|
||||
WHERE [aps].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND [aps].[PositionNr] = @{nameof(posNo)}
|
||||
AND [dbo].[NORMALIZE_SERIAL]([aps].[KundeneigeneSerienNr])
|
||||
NOT IN (SELECT [SerienNr]
|
||||
FROM [PalettenScan]
|
||||
WHERE [AuftragNr] = @{nameof(orderNo)}
|
||||
AND [PositionNr] = @{nameof(posNo)}
|
||||
AND [PalettenNr] != @{nameof(palletNr)}))
|
||||
AS [x]
|
||||
ORDER BY [x].[IsScanned] DESC
|
||||
, [x].[CustomerSerial]")
|
||||
.AddParameter(nameof(orderNo), orderNo)
|
||||
.AddParameter(nameof(posNo), posNo)
|
||||
.AddParameter(nameof(palletNr), palletNr)
|
||||
.ExecuteReader(x => new SerialNr
|
||||
{
|
||||
Id = x.GetInt(),
|
||||
PositionNr = x.GetSmallint(),
|
||||
Serial = x.GetInt(),
|
||||
CustomerSerial = x.GetString(),
|
||||
IsScanned = x.GetBool(),
|
||||
PalletNr = palletNr
|
||||
});
|
||||
|
||||
private PalletsBatchModel LoadBatchModel(int orderNo, int? posNo, int? palletNo)
|
||||
{
|
||||
var batchModel = this.sqlClient.FirstOrDefault(
|
||||
query: $@"
|
||||
@ -102,8 +434,6 @@
|
||||
FROM [AlleAuftragPositionen] AS [AAP]
|
||||
JOIN [Kunde] ON [Kunde].[KundenNr] = [AAP].[KundenNr]
|
||||
WHERE [AAP].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND (@{nameof(posNo)} IS NULL
|
||||
OR [AAP].[PositionNr] = @{nameof(posNo)})
|
||||
ORDER BY [AAP].[FertigungsauftragNr] DESC",
|
||||
parameters: parameters => parameters
|
||||
.Add(nameof(orderNo), orderNo)
|
||||
@ -113,151 +443,48 @@
|
||||
OrderNr = reader.GetValue<int>(),
|
||||
ProductionOrderNr = reader.GetValue<int>(),
|
||||
Customer = reader.GetString(),
|
||||
AdditionalText = reader.GetString(),
|
||||
Positions = this.LoadBatchPositions(orderNo, posNo, palletNo)
|
||||
AdditionalText = reader.GetString()
|
||||
});
|
||||
|
||||
if (batchModel != null)
|
||||
{
|
||||
batchModel.Positions = this.LoadBatchPositions(orderNo, posNo, palletNo);
|
||||
}
|
||||
|
||||
return batchModel ?? new PalletsBatchModel();
|
||||
}
|
||||
|
||||
private IEnumerable<PalletPosition> LoadBatchPositions(int? orderNo, int? posNo, int? palletNo)
|
||||
=> this.sqlClient.ExecuteReader(
|
||||
query: $@"SELECT [AAP].[PositionNr] AS [Pos]
|
||||
, [Identnr].[Typ] AS [Typ]
|
||||
, [Identnr].[Typzusatz] AS [Typzusatz]
|
||||
, [Identnr].[Nennweite] AS [Nennweite]
|
||||
, (SELECT COUNT(1)
|
||||
FROM [PalettenScan] AS [x]
|
||||
WHERE [x].[AuftragNr] = [PS].[AuftragNr]
|
||||
AND [x].[PositionNr] = [PS].[PositionNr]
|
||||
AND [x].[PalettenNr] = [PS].[PalettenNr]) AS [Count]
|
||||
, (SELECT TOP 1 [Menge]
|
||||
FROM [AlleAuftragPositionen] AS [x]
|
||||
WHERE [x].[AuftragNr] = [AAP].[AuftragNr]
|
||||
AND [x].[PositionNr] = [AAP].[PositionNr]) AS [TotalCount]
|
||||
FROM [Identnr]
|
||||
JOIN [AlleAuftragPositionen] AS [AAP]
|
||||
ON [AAP].[IdentNr] = [Identnr].[IdentNr]
|
||||
LEFT JOIN [PalettenScan] AS [PS]
|
||||
ON [PS].[AuftragNr] = [AAP].[AuftragNr]
|
||||
AND [PS].[PositionNr] = [AAP].[PositionNr]
|
||||
WHERE [AAP].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND (@{nameof(palletNo)} IS NULL
|
||||
OR [PS].[PalettenNr] = @{nameof(palletNo)})
|
||||
AND (@{nameof(posNo)} IS NULL
|
||||
OR [AAP].[PositionNr] = @{nameof(posNo)})
|
||||
GROUP BY [AAP].[AuftragNr]
|
||||
, [PS].[AuftragNr]
|
||||
, [AAP].[PositionNr]
|
||||
, [PS].[PositionNr]
|
||||
, [Identnr].[Typ]
|
||||
, [Identnr].[Typzusatz]
|
||||
, [Identnr].[Nennweite]
|
||||
, [PS].[PalettenNr]
|
||||
ORDER BY [AAP].[PositionNr]",
|
||||
parameters: parameters => parameters
|
||||
.Add(nameof(orderNo), orderNo)
|
||||
.Add(nameof(posNo), posNo)
|
||||
.Add(nameof(palletNo), palletNo),
|
||||
reader: reader => new PalletPosition
|
||||
{
|
||||
PositionNr = reader.GetValue<short>(),
|
||||
Description = string
|
||||
.Join(" ", new[]
|
||||
{
|
||||
reader.GetString(),
|
||||
reader.GetString(),
|
||||
reader.GetString(),
|
||||
}
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))),
|
||||
ItemsCount = reader.GetValue<int>(),
|
||||
TotalItemsCount = reader.GetValue<int>(),
|
||||
Items = this.LoadBatchItems(orderNo, posNo, palletNo),
|
||||
});
|
||||
|
||||
private IEnumerable<SerialNr> LoadBatchItems(int? orderNo, int? posNo, int? palletNo)
|
||||
=> this.sqlClient.ExecuteReader(
|
||||
query: $@"SELECT DISTINCT
|
||||
[x].[Id]
|
||||
, [x].[PositionNr]
|
||||
, [x].[SerienNr]
|
||||
, [x].[CustomerSerienNr]
|
||||
, [x].[PalettenNr]
|
||||
, [x].[IsScanned]
|
||||
FROM (SELECT [PS].[ID] AS [Id]
|
||||
, ISNULL([PS].[PositionNr], [APS].[PositionNr]) AS [PositionNr]
|
||||
, [APS].[SerienNr] AS [SerienNr]
|
||||
, REPLACE(RTRIM(LTRIM([APS].[KundeneigeneSerienNr])), ' ', '') AS [CustomerSerienNr]
|
||||
, [PS].[PalettenNr] AS [PalettenNr]
|
||||
, CAST(CASE WHEN [PS].[ID] IS NULL THEN 0 ELSE 1 END AS BIT) AS [IsScanned]
|
||||
FROM [AuftragPositionSerienNr] AS [APS]
|
||||
LEFT JOIN [PalettenScan] AS [PS]
|
||||
ON [PS].[AuftragNr] = [APS].[AuftragNr]
|
||||
AND [PS].[PositionNr] = [APS].[PositionNr]
|
||||
AND [PS].[SerienNr] = REPLACE(RTRIM(LTRIM([APS].[KundeneigeneSerienNr])), ' ', '')
|
||||
WHERE [APS].[AuftragNr] = @{nameof(orderNo)}
|
||||
AND (@{nameof(palletNo)} IS NULL
|
||||
OR [PS].[PalettenNr] = @{nameof(palletNo)})
|
||||
AND (@{nameof(posNo)} IS NULL
|
||||
OR [APS].[PositionNr] = @{nameof(posNo)}))
|
||||
AS [x]
|
||||
ORDER BY [x].[IsScanned] DESC
|
||||
, [x].[PositionNr]
|
||||
, [x].[CustomerSerienNr]
|
||||
, [x].[SerienNr]",
|
||||
parameters: parameters => parameters
|
||||
.Add(nameof(orderNo), orderNo)
|
||||
.Add(nameof(posNo), posNo)
|
||||
.Add(nameof(palletNo), palletNo),
|
||||
reader: reader => new SerialNr
|
||||
{
|
||||
Id = reader.GetValue<int>(),
|
||||
PositionNr = reader.GetValue<int>(),
|
||||
Nr = reader.GetValue<int>(),
|
||||
CustomerNr = reader.GetString(),
|
||||
PalletNr = reader.GetValue<short>(),
|
||||
IsScaned = reader.GetValue<bool>(),
|
||||
});
|
||||
|
||||
public IEnumerable<int> LoadPallets(OrderScanModel model)
|
||||
public OrderScanModel LoadPallets(OrderScanModel model)
|
||||
{
|
||||
this.UpdatePalletsNr(model.OrderNr ?? 0);
|
||||
if (model != null && model.OrderNr != null && model.OrderNr > 0)
|
||||
{
|
||||
var pallets = this.sqlClient.ExecuteReader(
|
||||
query: $@" SELECT DISTINCT
|
||||
[PSI].[PalettenNr]
|
||||
, CAST(CASE WHEN [PSII].[ID] IS NULL
|
||||
THEN 0
|
||||
ELSE 1
|
||||
END AS BIT)
|
||||
FROM [PalettenScan] AS [PSI]
|
||||
LEFT JOIN [PalettenScan] AS [PSII]
|
||||
ON [PSII].[ID] = [PSI].[ID]
|
||||
AND [PSII].[PositionNr] = @{nameof(model.PositionNr)}
|
||||
WHERE [PSI].[AuftragNr] = @{nameof(model.OrderNr)}
|
||||
ORDER BY [PSI].[PalettenNr]",
|
||||
parameters: parameters => parameters
|
||||
.Add(nameof(model.OrderNr), model.OrderNr)
|
||||
.Add(nameof(model.PositionNr), model.PositionNr),
|
||||
reader: reader => new KeyValuePair<int, bool>(
|
||||
key: (int)reader.GetValue<short>(),
|
||||
value: reader.GetValue<bool>()));
|
||||
|
||||
var pallets = this.sqlClient.ExecuteReader(
|
||||
query: $@"SELECT DISTINCT [PS].[PalettenNr]
|
||||
FROM [PalettenScan] AS [PS]
|
||||
WHERE [PS].[AuftragNr] = @{nameof(model.OrderNr)}
|
||||
AND (@{nameof(model.PositionNr)} IS NULL
|
||||
OR [PS].[PositionNr] = @{nameof(model.PositionNr)})
|
||||
ORDER BY [PS].[PalettenNr]",
|
||||
parameters: parameters => parameters
|
||||
.Add(nameof(model.OrderNr), model.OrderNr)
|
||||
.Add(nameof(model.PositionNr), model.PositionNr),
|
||||
reader: reader => (int)reader.GetValue<short>());
|
||||
model.UpdatePallets(pallets);
|
||||
|
||||
//if (!pallets.Any())
|
||||
//{
|
||||
// return this.sqlClient.ExecuteReader(
|
||||
// query: $@"SELECT CAST(ISNULL(MAX([PS].[PalettenNr])
|
||||
// , (SELECT ISNULL(MAX([PS].[PalettenNr]), 0)
|
||||
// FROM [PalettenScan] AS [PS]
|
||||
// WHERE [PS].[AuftragNr] = @{nameof(model.OrderNr)})) AS INT)
|
||||
// FROM [PalettenScan] AS [PS]
|
||||
// WHERE [PS].[AuftragNr] = @{nameof(model.OrderNr)}
|
||||
// AND (@{nameof(model.PositionNr)} IS NULL
|
||||
// OR [PS].[PositionNr] = @{nameof(model.PositionNr)})",
|
||||
// parameters: parameters => parameters
|
||||
// .Add(nameof(model.OrderNr), model.OrderNr)
|
||||
// .Add(nameof(model.PositionNr), model.PositionNr),
|
||||
// reader: reader => reader.GetValue<int>());
|
||||
//}
|
||||
model.Positions = this.sqlClient.ExecuteReader(
|
||||
query: $@"SELECT DISTINCT [x].[PositionNr]
|
||||
FROM [AlleAuftragPositionen] AS [x]
|
||||
WHERE [x].[AuftragNr] = @{nameof(model.OrderNr)}
|
||||
ORDER BY [x].[PositionNr]",
|
||||
parameters: parameters => parameters.Add(nameof(model.OrderNr), model.OrderNr),
|
||||
reader: reader => (int)reader.GetValue<short>());
|
||||
}
|
||||
|
||||
return pallets;
|
||||
return model;
|
||||
}
|
||||
|
||||
public Result UpdateBatchModel(OrderScanModel model)
|
||||
@ -284,9 +511,6 @@
|
||||
model.SerialNr = orderIdentity.CustomerSerialNr;
|
||||
model.PositionNr = orderIdentity.PositionNr;
|
||||
|
||||
var nextPalletNr = this.NextPallet(model.OrderNr.Value);
|
||||
model.PalletNr = Math.Max(Math.Min(model.PalletNr, nextPalletNr), 1);
|
||||
|
||||
if (this.PalletsEntryExists(model.OrderNr, model.PositionNr, model.SerialNr))
|
||||
{
|
||||
return $"Wasserzähler mit Serien-Nr: {model.SerialNr} wurde bereits hinzugefügt.";
|
||||
@ -300,29 +524,6 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
private int NextPallet(int orderno)
|
||||
=> this.sqlClient.FirstOrDefault(
|
||||
query: $@"SELECT MAX([PalettenNr]) + 1 FROM [PalettenScan] WHERE [AuftragNr] = @{nameof(orderno)}",
|
||||
parameters: parameters => parameters.Add(nameof(orderno), orderno),
|
||||
reader: reader => reader.GetValue<int>());
|
||||
|
||||
private OrderScanModel DeletePalletEntryById(int id)
|
||||
=> this.sqlClient.FirstOrDefault(
|
||||
query: $@"
|
||||
DELETE
|
||||
FROM [PalettenScan]
|
||||
OUTPUT [deleted].[AuftragNr]
|
||||
, [deleted].[PositionNr]
|
||||
, [deleted].[PalettenNr]
|
||||
WHERE [ID] = @{nameof(id)}",
|
||||
parameters: parameters => parameters.Add(nameof(id), id),
|
||||
reader: reader => new OrderScanModel
|
||||
{
|
||||
OrderNr = reader.GetValue<int>(0),
|
||||
PositionNr = reader.GetValue<int>(1),
|
||||
PalletNr = reader.GetValue<short>(2)
|
||||
});
|
||||
|
||||
private OrderIdentity UpdateOrderIdentifiers(int? orderNr, int? positionNr, string serialNr)
|
||||
=> this.sqlClient.FirstOrDefault(
|
||||
query: $@"
|
||||
@ -440,27 +641,11 @@
|
||||
FROM [PalettenScan]
|
||||
WHERE [PalettenScan].[AuftragNr] = @{nameof(orderNr)}
|
||||
AND [PalettenScan].[PositionNr] = @{nameof(positionNr)}
|
||||
AND @{nameof(serialNr)} = [PalettenScan].[SerienNr]",
|
||||
AND [PalettenScan].[SerienNr] = @{nameof(serialNr)}",
|
||||
parameters => parameters
|
||||
.Add(nameof(orderNr), orderNr)
|
||||
.Add(nameof(positionNr), positionNr)
|
||||
.Add(nameof(serialNr), serialNr),
|
||||
reader => reader.GetValue<bool>());
|
||||
|
||||
private bool UpdatePalletsNr(int orderNo)
|
||||
=> this.sqlClient.ExecuteNonQuery(
|
||||
query: $@"UPDATE [PalettenScan]
|
||||
SET [PalettenNr] = [P2].[RowNumber]
|
||||
FROM [PalettenScan] AS [P1]
|
||||
JOIN (SELECT [P].[PalettenNr]
|
||||
, ROW_NUMBER() OVER (ORDER BY [P].[PalettenNr]) AS [RowNumber]
|
||||
FROM (SELECT DISTINCT
|
||||
[PalettenNr]
|
||||
FROM [PalettenScan]
|
||||
WHERE [AuftragNr] = @{nameof(orderNo)})
|
||||
AS [P])
|
||||
AS [P2]
|
||||
ON [P2].[PalettenNr] = [P1].[PalettenNr]",
|
||||
parameters: parameters => parameters.Add(nameof(orderNo), orderNo)) == 1;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
namespace LaaProductionWeb.App_Infrastructure
|
||||
{
|
||||
using LaaProductionWeb.Services.Interfaces;
|
||||
using LaaProductionWeb.Services.Models;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
@ -13,14 +14,19 @@
|
||||
var httpContext = filterContext.HttpContext;
|
||||
var userId = httpContext.UserId();
|
||||
var accountService = ServiceProvider.Current.GetService<IAccountService>();
|
||||
var employee = accountService.FindEmployee(userId);
|
||||
var claims = new List<Claim>();
|
||||
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
|
||||
httpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
|
||||
{
|
||||
new Claim(ClaimTypes.Name, string.Empty),
|
||||
new Claim(ClaimTypes.Role, UserRoles.WEB_Anonymous),
|
||||
}, nameof(Claim), ClaimTypes.Name, ClaimTypes.Role));
|
||||
|
||||
#if DEBUG
|
||||
var employee = new Employee("DEVELOPER", UserRoles.ALL);
|
||||
#else
|
||||
var employee = accountService.FindEmployee(userId);
|
||||
#endif
|
||||
var claims = new List<Claim>();
|
||||
|
||||
if (employee.IsValid)
|
||||
{
|
||||
|
||||
@ -9,5 +9,15 @@
|
||||
public const string WEB_PalettenScan = nameof(WEB_PalettenScan);
|
||||
public const string WEB_ProdApproval = nameof(WEB_ProdApproval);
|
||||
public const string WEB_PuneProtokoll = nameof(WEB_PuneProtokoll);
|
||||
|
||||
public static string[] ALL = new string []
|
||||
{
|
||||
WEB_Admin,
|
||||
WEB_API_Explorer,
|
||||
WEB_HeReport,
|
||||
WEB_PalettenScan,
|
||||
WEB_ProdApproval,
|
||||
WEB_PuneProtokoll
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -18,7 +18,6 @@
|
||||
=> new ServiceCollection()
|
||||
.ConfigureServices()
|
||||
.BuildServiceProvider()
|
||||
.BuildControllerFactory()
|
||||
.RegisterServiceProvider();
|
||||
|
||||
/// <summary>
|
||||
@ -29,7 +28,6 @@
|
||||
static IServiceCollection ConfigureServices(this IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddControllers()
|
||||
.AddTransientServices()
|
||||
.AddHttpClient(ApplicationSettings.APIURL)
|
||||
.AddDbContext(ApplicationSettings.ConnectionString);
|
||||
|
||||
21
LaaProductionWeb/LaaProductionWeb/App_Start/WebApiConfig.cs
Normal file
21
LaaProductionWeb/LaaProductionWeb/App_Start/WebApiConfig.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace LaaProductionWeb
|
||||
{
|
||||
public static class WebApiConfig
|
||||
{
|
||||
public static void Register(HttpConfiguration config)
|
||||
{
|
||||
config.MapHttpAttributeRoutes();
|
||||
|
||||
config.Routes.MapHttpRoute(
|
||||
name: "DefaultApi",
|
||||
routeTemplate: "api/{controller}/{id}",
|
||||
defaults: new { id = RouteParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,8 +10,8 @@
|
||||
{
|
||||
private readonly IAccountService accountService;
|
||||
|
||||
public AdminController(IAccountService accountService)
|
||||
=> this.accountService = accountService;
|
||||
public AdminController()
|
||||
=> this.accountService = ServiceProvider.Current.GetService<IAccountService>();
|
||||
|
||||
public ActionResult Index()
|
||||
=> this.View();
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
{
|
||||
private readonly IApprovalsService approvals;
|
||||
|
||||
public ApprovalsController(IApprovalsService approvals)
|
||||
=> this.approvals = approvals;
|
||||
public ApprovalsController()
|
||||
=> this.approvals = ServiceProvider.Current.GetService<IApprovalsService>();
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Add()
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
{
|
||||
private readonly IAccountService accountService;
|
||||
|
||||
public HomeController(IAccountService accountService)
|
||||
=> this.accountService = accountService;
|
||||
public HomeController()
|
||||
=> this.accountService = ServiceProvider.Current.GetService<IAccountService>();
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Index()
|
||||
|
||||
@ -13,8 +13,8 @@
|
||||
|
||||
private readonly IProtocolService protocolService;
|
||||
|
||||
public ProtocolController(IProtocolService protocolService)
|
||||
=> this.protocolService = protocolService;
|
||||
public ProtocolController()
|
||||
=> this.protocolService = ServiceProvider.Current.GetService<IProtocolService>();
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Index(int orderId = 0)
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
{
|
||||
private readonly IReportService reportService;
|
||||
|
||||
public ReportController(IReportService reportService)
|
||||
=> this.reportService = reportService;
|
||||
public ReportController()
|
||||
=> this.reportService = ServiceProvider.Current.GetService<IReportService>();
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Helium()
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
private readonly IOrdersService ordersService;
|
||||
private readonly IHttpService httpService;
|
||||
|
||||
public SearchController(IOrdersService ordersService, IHttpService httpService)
|
||||
public SearchController()
|
||||
{
|
||||
this.ordersService = ordersService;
|
||||
this.httpService = httpService;
|
||||
this.ordersService = ServiceProvider.Current.GetService<IOrdersService>();
|
||||
this.httpService = ServiceProvider.Current.GetService<IHttpService>();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
|
||||
@ -21,10 +21,10 @@
|
||||
private readonly IShipmentsService shipmentsService;
|
||||
private readonly IHttpService httpService;
|
||||
|
||||
public ShipmentsController(IShipmentsService shipmentsService, IHttpService httpService)
|
||||
public ShipmentsController()
|
||||
{
|
||||
this.shipmentsService = shipmentsService;
|
||||
this.httpService = httpService;
|
||||
this.shipmentsService = ServiceProvider.Current.GetService<IShipmentsService>();
|
||||
this.httpService = ServiceProvider.Current.GetService<IHttpService>();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@ -45,39 +45,31 @@
|
||||
[HttpPost]
|
||||
public ActionResult Index(ShipmentModel model)
|
||||
{
|
||||
this.HttpContext.SetUserData(model.OrderScanModel as OrderScanModel);
|
||||
this.HttpContext.SetUserData(model.OrderScanModel);
|
||||
|
||||
return this.View(model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Pallet(OrderScanModel model)
|
||||
=> this.View(nameof(this.Index), new ShipmentModel(model));
|
||||
public ActionResult Pallet(OrderScanModel model)
|
||||
{
|
||||
this.HttpContext.SetUserData(model);
|
||||
|
||||
return this.View(nameof(this.Index), new ShipmentModel(model));
|
||||
}
|
||||
|
||||
public ActionResult Batch(OrderScanModel model)
|
||||
{
|
||||
var batchModel = this.shipmentsService
|
||||
.LoadBatchModel(model ?? new OrderScanModel());
|
||||
var batchModel = this.shipmentsService.LoadBatchModel(model);
|
||||
|
||||
this.UpdateClientName(batchModel);
|
||||
|
||||
return this.PartialView(batchModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Print(OrderScanModel model)
|
||||
{
|
||||
var batchModel = this.shipmentsService.LoadBatchModel(model);
|
||||
var batchPrintModel = new BatchPrintModel(batchModel);
|
||||
|
||||
return this.View(batchPrintModel);
|
||||
}
|
||||
|
||||
public ActionResult Scan(OrderScanModel model)
|
||||
{
|
||||
var pallets = this.shipmentsService.LoadPallets(model);
|
||||
|
||||
model.UpdatePallets(pallets);
|
||||
model = this.shipmentsService.LoadPallets(model);
|
||||
|
||||
return this.PartialView(model);
|
||||
}
|
||||
@ -106,6 +98,14 @@
|
||||
this.TempData[nameof(model.SerialNr)] = result;
|
||||
}
|
||||
}
|
||||
else if (this.TempData[nameof(model.PositionNr)] is int p && p != model.PositionNr)
|
||||
{
|
||||
this.TempData[nameof(model.PositionNr)] = model.PositionNr;
|
||||
|
||||
return this.Pallet(model);
|
||||
}
|
||||
|
||||
this.TempData[nameof(model.PositionNr)] = model.PositionNr;
|
||||
|
||||
return this.View(nameof(this.Index), new ShipmentModel(model));
|
||||
}
|
||||
@ -118,6 +118,23 @@
|
||||
return this.View(nameof(this.Index), new ShipmentModel(orderScanModel));
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Missing()
|
||||
{
|
||||
var model = this.shipmentsService.MissingItems();
|
||||
|
||||
return this.View(model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Print(OrderScanModel model)
|
||||
{
|
||||
var batchModel = this.shipmentsService.LoadBatchModel(model);
|
||||
var batchPrintModel = new BatchPrintModel(batchModel);
|
||||
|
||||
return this.View(batchPrintModel);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ActionResult Download(OrderScanModel model)
|
||||
{
|
||||
|
||||
@ -18,8 +18,8 @@
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<Use64BitIISExpress />
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
|
||||
<IISExpressWindowsAuthentication>disabled</IISExpressWindowsAuthentication>
|
||||
<IISExpressAnonymousAuthentication>disabled</IISExpressAnonymousAuthentication>
|
||||
<IISExpressWindowsAuthentication>enabled</IISExpressWindowsAuthentication>
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<NuGetPackageImportStamp>
|
||||
@ -189,6 +189,7 @@
|
||||
<Content Include="Views\Report\HiddenFilter.cshtml" />
|
||||
<Content Include="Views\Report\Kottmann.cshtml" />
|
||||
<Content Include="Views\Search\Wildcard.cshtml" />
|
||||
<Content Include="Views\Shipments\Missing.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="App_Content\font\fonts\bootstrap-icons.woff" />
|
||||
|
||||
@ -60,23 +60,23 @@
|
||||
|
||||
foreach (var item in this.Model.Positions.SelectMany(x => x.Items))
|
||||
{
|
||||
<tr class="is_scaned_@(item.IsScaned ? 1 : 0)">
|
||||
<td class="va-middle @(item.IsScaned ? null : "text-secondary")">@(count++).</td>
|
||||
<td class="va-middle w-100 @(item.IsScaned ? null : "text-secondary")">(@item.PositionNr) @item.BarcodeNr</td>
|
||||
<tr class="is_scaned_@(item.IsScanned ? 1 : 0)">
|
||||
<td class="va-middle @(item.IsScanned ? null : "text-secondary")">@(count++).</td>
|
||||
<td class="va-middle w-100 @(item.IsScanned ? null : "text-secondary")">(@item.PositionNr) @item.BarcodeNr</td>
|
||||
<td class="va-middle w-100 text-center">
|
||||
<svg class="barcode"
|
||||
jsbarcode-format="auto"
|
||||
jsbarcode-value="@item.BarcodeNr"
|
||||
jsbarcode-displayValue="false"
|
||||
jsbarcode-background="transparent"
|
||||
jsbarcode-lineColor="@(item.IsScaned ? "black" : "#ced4da")"
|
||||
jsbarcode-lineColor="@(item.IsScanned ? "black" : "#ced4da")"
|
||||
jsbarcode-height="50"
|
||||
jsbarcode-margin="0"
|
||||
jsbarcode-textMargin="0"
|
||||
jsbarcode-fontoptions="bold">
|
||||
</svg>
|
||||
</td>
|
||||
<td class="va-middle text-end">@(item.IsScaned ? item.PalletNr : null)</td>
|
||||
<td class="va-middle text-end">@(item.IsScanned ? item.PalletNr : null)</td>
|
||||
<td class="va-middle text-center">
|
||||
<a class="btn btn-sm btn-danger" href="~/Shipments/Delete/@item.Id">
|
||||
<i class="bi bi-x"></i>
|
||||
|
||||
@ -15,14 +15,6 @@
|
||||
@this.Html.ValidationMessageFor(x => x.OrderNr, string.Empty, new { @class = "small text-danger m-0 p-0" })
|
||||
<ul id="order_nr_menu" class="dropdown-menu w-100 mt-1"></ul>
|
||||
</div>
|
||||
<div class="form-floating mb-3 dropdown">
|
||||
@this.Html.TextBoxFor(x => x.PositionNr, new { id = "pos_nr", @class = "form-control bg-white cursor-pointer", placeholder = "0000000000", @readonly = "readonly" })
|
||||
@this.Html.LabelFor(x => x.PositionNr, new { @for = "pos_nr", @class = "text-smallcaps" })
|
||||
<i class="bi bi-chevron-down" style="position: absolute;right: 3.5%;top: 35%;" data-bs-toggle="dropdown"></i>
|
||||
<ul id="pos_nr_menu" class="dropdown-menu w-100 mt-1">
|
||||
<li class="dropdown-item disabled white-space-break">Keine Positionen vorhanden.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="form-floating mb-3">
|
||||
<button type="submit" class="btn btn-primary py-3 w-100 text-smallcaps">
|
||||
@this.Model.BtnSubmit <i class="bi bi-chevron-right ms-2"></i>
|
||||
@ -116,19 +108,13 @@
|
||||
});
|
||||
|
||||
orderNrInput.oninput = onOrderNrInput;
|
||||
|
||||
positionNrInput.setAttribute('data-bs-toggle', 'dropdown');
|
||||
positionNrInput.setAttribute('aria-expanded', 'false');
|
||||
positionNrMenu.innerHTML = '<li class="dropdown-item disabled white-space-break">Keine Positionen vorhanden.</li>';
|
||||
|
||||
getPositions('@this.Model.OrderNr');
|
||||
JsBarcode(".barcode").init();
|
||||
|
||||
let serialNrInput = document.getElementById('serial_nr');
|
||||
if (serialNrInput) {
|
||||
serialNrInput.focus({ focusVisible: true });
|
||||
}
|
||||
})();
|
||||
|
||||
let serialNrInput = document.getElementById('serial_nr');
|
||||
if (serialNrInput) {
|
||||
serialNrInput.focus({ focusVisible: true });
|
||||
}
|
||||
|
||||
JsBarcode(".barcode").init();
|
||||
</script>
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
@model IEnumerable<LaaProductionWeb.Services.Models.MissingItem>
|
||||
|
||||
<div class="container-fluid my-3">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Auftrag Nr</th>
|
||||
<th>Position Nr</th>
|
||||
<th>Serien Nr</th>
|
||||
<th>Kunden Serien Nr</th>
|
||||
<th>Bezeichnung</th>
|
||||
<th>Typ</th>
|
||||
<th>Anlage Datum</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in this.Model)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.OrderNr</td>
|
||||
<td>@item.PosNr</td>
|
||||
<td>@item.SerialNr</td>
|
||||
<td>@item.CustomSerial</td>
|
||||
<td>@item.Term</td>
|
||||
<td>@item.Type</td>
|
||||
<td>@item.EntryDate.ToString("yyyy-MM-dd")</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
this.Layout = "~/Views/Shared/_PrintLayout.cshtml";
|
||||
}
|
||||
|
||||
<table class="table table-borderless table-striped">
|
||||
<table class="table table-borderless table-striped" border="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="6" class="px-0">
|
||||
<th colspan="8" class="px-0">
|
||||
<table class="table table-borderless">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -25,22 +25,22 @@
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<th class="text-end">Pos</th>
|
||||
<th >Bezeichnung</th>
|
||||
<th>Bezeichnung</th>
|
||||
<th class="text-end">Menge</th>
|
||||
<th class="text-end">Bestellmenge</th>
|
||||
</tr>
|
||||
@foreach (var pos in this.Model.Positions)
|
||||
{
|
||||
<tr>
|
||||
<td class="fw-normal text-end">@pos.PositionNr</td>
|
||||
<td class="fw-normal ">@pos.Description</td>
|
||||
<td class="fw-normal text-end">@pos.ItemsCount</td>
|
||||
<td class="fw-normal text-end">@pos.TotalItemsCount</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="fw-normal text-end">@pos.PositionNr</td>
|
||||
<td class="fw-normal ">@pos.Description</td>
|
||||
<td class="fw-normal text-end">@pos.ItemsCount</td>
|
||||
<td class="fw-normal text-end">@pos.TotalItemsCount</td>
|
||||
</tr>
|
||||
}
|
||||
<tr class="border-top">
|
||||
<td colspan="3" class="text-end fw-bold">Palettenmenge: @this.Model.Positions.Sum(x => x.ItemsCount)</td>
|
||||
<td colspan="1"></td>
|
||||
<td colspan="1" class="text-end fw-bold">Palettennummer: @this.Model.PalletNr</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
@ -50,12 +50,14 @@
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="small">No.</th>
|
||||
<th class="small">Pos.</th>
|
||||
<th class="small"></th>
|
||||
<th class="small">No.</th>
|
||||
<th class="small">Pos.</th>
|
||||
<th class="small"></th>
|
||||
<th class="small">#</th>
|
||||
<th class="small">Pos</th>
|
||||
<th class="small">SerienNr</th>
|
||||
<th class="small">Barcode</th>
|
||||
<th class="small">#</th>
|
||||
<th class="small">Pos</th>
|
||||
<th class="small">SerienNr</th>
|
||||
<th class="small">Barcode</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -63,7 +65,7 @@
|
||||
var items = this.Model
|
||||
.Positions
|
||||
.SelectMany(x => x.Items
|
||||
.Where(i => i.IsScaned))
|
||||
.Where(i => i.IsScanned))
|
||||
.ToList();
|
||||
var itemsCount = items.Count;
|
||||
|
||||
@ -73,28 +75,38 @@
|
||||
var item = items[i];
|
||||
|
||||
<tr>
|
||||
<td class="fs-5">@(i + 1).</td>
|
||||
<td class="fs-5">@item.PositionNr</td>
|
||||
<td class="py-0">
|
||||
<td class="va-middle">@(i + 1).</td>
|
||||
<td class="va-middle">@item.PositionNr</td>
|
||||
<td class="va-middle">@item.BarcodeNr</td>
|
||||
<td class="p-0">
|
||||
<svg class="barcode"
|
||||
jsbarcode-height="70"
|
||||
jsbarcode-marginTop="2"
|
||||
jsbarcode-marginLeft="0"
|
||||
jsbarcode-marginRight="0"
|
||||
jsbarcode-marginBottom="2"
|
||||
jsbarcode-height="50"
|
||||
jsbarcode-format="auto"
|
||||
jsbarcode-displayValue="true"
|
||||
jsbarcode-textMargin="0"
|
||||
jsbarcode-displayValue="false"
|
||||
jsbarcode-background="transparent"
|
||||
jsbarcode-value="@item.BarcodeNr" />
|
||||
</td>
|
||||
|
||||
@if (ni < itemsCount)
|
||||
{
|
||||
var nitem = items[ni];
|
||||
<td class="fs-5">@(ni + 1).</td>
|
||||
<td class="fs-5">@nitem.PositionNr</td>
|
||||
<td class="py-0">
|
||||
|
||||
<td class="va-middle">@(ni + 1).</td>
|
||||
<td class="va-middle">@nitem.PositionNr</td>
|
||||
<td class="va-middle">@item.BarcodeNr</td>
|
||||
<td class="p-0">
|
||||
<svg class="barcode"
|
||||
jsbarcode-height="70"
|
||||
jsbarcode-marginTop="2"
|
||||
jsbarcode-marginLeft="0"
|
||||
jsbarcode-marginRight="0"
|
||||
jsbarcode-marginBottom="2"
|
||||
jsbarcode-height="50"
|
||||
jsbarcode-format="auto"
|
||||
jsbarcode-displayValue="true"
|
||||
jsbarcode-textMargin="0"
|
||||
jsbarcode-displayValue="false"
|
||||
jsbarcode-background="transparent"
|
||||
jsbarcode-value="@nitem.BarcodeNr" />
|
||||
</td>
|
||||
@ -104,6 +116,7 @@
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
}
|
||||
</tr>
|
||||
}
|
||||
@ -112,7 +125,7 @@
|
||||
</table>
|
||||
|
||||
@section scripts {
|
||||
<script>
|
||||
JsBarcode(".barcode").init();
|
||||
</script>
|
||||
<script>
|
||||
JsBarcode(".barcode").init();
|
||||
</script>
|
||||
}
|
||||
@ -8,39 +8,64 @@
|
||||
</div>
|
||||
<form id="scan_form" action="~/Shipments/ScanPost" method="post" autocomplete="off">
|
||||
@this.Html.HiddenFor(x => x.OrderNr)
|
||||
@this.Html.HiddenFor(x => x.PositionNr)
|
||||
@this.Html.HiddenFor(x => x.PalletNr)
|
||||
<div class="d-flex flex-wrap">
|
||||
@foreach (var pallet in this.Model.Pallets)
|
||||
{
|
||||
var css = pallet.Key == this.Model.PalletNr
|
||||
? "btn btn-success"
|
||||
: "btn btn-outline-success";
|
||||
var id = $"pallet_{pallet.Key}";
|
||||
var palletNr = pallet.Key;
|
||||
var forPosition = pallet.Value;
|
||||
var href = this.Url.Content(this.Model.PalletUrl(palletNr));
|
||||
|
||||
<a class="@css mb-3 me-3" href="@this.Url.Content($"{this.Model.PalletUrl}&palletnr={pallet.Key}")">@pallet.Key</a>
|
||||
if (!forPosition && palletNr == this.Model.PalletNr)
|
||||
{
|
||||
<a class="btn btn-secondary opacity-25 mb-3 me-3" href="@href">@palletNr</a>
|
||||
}
|
||||
else if (!forPosition)
|
||||
{
|
||||
<a class="btn btn-outline-secondary opacity-25 mb-3 me-3" href="@href">@palletNr</a>
|
||||
}
|
||||
else if (forPosition && palletNr == this.Model.PalletNr)
|
||||
{
|
||||
<a class="btn btn-success mb-3 me-3" href="@href">@palletNr</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="btn btn-outline-success mb-3 me-3" href="@href">@palletNr</a>
|
||||
}
|
||||
}
|
||||
|
||||
@{
|
||||
var nextPalletNr = this.Model.Pallets.Keys.LastOrDefault() + 1;
|
||||
}
|
||||
|
||||
<a class="btn btn-outline-success mb-3 me-3" href="@this.Url.Content($"{this.Model.PalletUrl}&palletnr={nextPalletNr}")">
|
||||
<i class="bi bi-plus-square"></i>
|
||||
</a>
|
||||
|
||||
<a class="btn btn-outline-secondary mb-3 me-3" href="@this.Url.Content(this.Model.PrintUrl)" target="_blank">
|
||||
<i class="bi bi-printer"></i> Druckvorschau
|
||||
</a>
|
||||
</div>
|
||||
<div class="form-floating mb-3 dropdown">
|
||||
<i class="bi bi-chevron-down" style="position: absolute;right: 3.5%;top: 35%;" data-bs-toggle="dropdown"></i>
|
||||
<select id="@nameof(this.Model.PositionNr)"
|
||||
name="@nameof(this.Model.PositionNr)"
|
||||
class="form-control bg-white cursor-pointer"
|
||||
onchange="this.form.submit();">
|
||||
<option value=""></option>
|
||||
@foreach (var positionNr in this.Model.Positions)
|
||||
{
|
||||
if (this.Model.PositionNr == positionNr)
|
||||
{
|
||||
<option value="@positionNr" selected="selected">@positionNr</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@positionNr">@positionNr</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
@this.Html.LabelFor(x => x.PositionNr, new { @for = "pos_nr", @class = "text-smallcaps" })
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="form-floating w-auto">
|
||||
@this.Html.TextBoxFor(x => x.SerialNr, new { id = "serial_nr", @class = "form-control form-control-success text-center", placeholder = "0000000000" })
|
||||
@this.Html.LabelFor(x => x.SerialNr, new { @for = "serial_nr", @class = "text-smallcaps" })
|
||||
</div>
|
||||
<div class="form-floating">
|
||||
<input class="form-control form-control-success disabled readonly text-center" value="@this.Model.PalletNr" readonly disabled />
|
||||
@this.Html.LabelFor(x => x.PalletNr)
|
||||
<input value="@this.Model.PalletNr" name="palletnr" id="palletnr" class="form-control form-control-success text-center" />
|
||||
@this.Html.LabelFor(x => x.PalletNr, new { @class = "text-smallcaps", @for = "palletnr" })
|
||||
</div>
|
||||
</div>
|
||||
@if (this.IsPost)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user