Shipments bug fix

This commit is contained in:
Stoyan Zlatev 2023-05-17 14:57:05 +02:00
parent d137d9efe0
commit 4ef3651ed7
32 changed files with 828 additions and 423 deletions

View File

@ -22,7 +22,7 @@
{
using (var client = new SmtpClient())
{
await client.AuthenticateAsync(this.settings.Username, this.settings.Password);
// await client.AuthenticateAsync(this.settings.Username, this.settings.Password);
await client.ConnectAsync(this.settings.Host, this.settings.Port);
var message = new MimeMessage

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,9 @@
PalletsBatchModel LoadBatchModel(OrderScanModel model);
IEnumerable<int> LoadPallets(OrderScanModel model);
OrderScanModel LoadPallets(OrderScanModel model);
IEnumerable<MissingItem> MissingItems();
Result UpdateBatchModel(OrderScanModel model);
}

View File

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

View File

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

View File

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

View File

@ -9,7 +9,9 @@
[Required]
public int? OrderNr { get; set; }
[Display(Name = "Positions-Nr. auswählen")]
public int? PositionNr { get; set; }
[Required]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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 }
);
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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