Prima versione deposit/pickup da verificare

This commit is contained in:
Samuele Locatelli
2024-02-02 19:38:42 +01:00
parent e55610870c
commit 4055ce8426
13 changed files with 466 additions and 21 deletions
@@ -89,7 +89,6 @@ namespace MagMan.Data.Tenant.Controllers
{
dbResult = dbCtx
.DbSetItems
//.Where(x => CustomerId == 0 || x.CustomerID == CustomerId)
.Include(c => c.MaterialNav)
.OrderBy(x => x.MatId)
.ToList();
@@ -121,6 +120,32 @@ namespace MagMan.Data.Tenant.Controllers
return dbResult;
}
/// <summary>
/// Elenco Items gestiti a magazzino dato Materiale
/// </summary>
/// <param name="connString">Stringa connessione (variabile x cliente)</param>
/// <param name="QrCode">QrCode/Dtmx cercato</param>
/// <returns></returns>
public RawItemModel ItemGetByQr(string connString, string qrCode)
{
RawItemModel? dbResult = new RawItemModel();
using (MagManContext dbCtx = new MagManContext(connString))
{
var rawList = dbCtx
.DbSetItems
.Include(m => m.MaterialNav)
.ToList();
dbResult = rawList
.Where(x => x.ItemDtmx == qrCode)
.FirstOrDefault();
if (dbResult == null)
{
dbResult = new RawItemModel();
}
}
return dbResult;
}
/// <summary>
/// Aggiunge/Modifica un item in magazzino
/// </summary>
@@ -148,21 +173,28 @@ namespace MagMan.Data.Tenant.Controllers
.FirstOrDefault();
if (currData != null)
{
MovMagModel recMovMag = new MovMagModel()
{
DtRec = DateTime.Now,
RawItemId = rec2upd.RawItemId,
QtyRec = deltaQty,
UserId = userId,
Note = deltaQty > 0 ? "M01+: Rettifica Inventariale" : "M01-: Rettifica Inventariale"
};
dbCtx.DbSetMovMag.Add(recMovMag);
// calcolo variazione
currData.QtyAvail += deltaQty;
dbCtx.Entry(currData).State = EntityState.Modified;
// salvo SOLO SE è >=0,,,
if (currData.QtyAvail >= 0)
{
MovMagModel recMovMag = new MovMagModel()
{
DtRec = DateTime.Now,
RawItemId = rec2upd.RawItemId,
QtyRec = deltaQty,
UserId = userId,
Note = deltaQty > 0 ? "M01+: Rettifica Inventariale" : "M01-: Rettifica Inventariale"
};
// registro movimento
dbCtx.DbSetMovMag.Add(recMovMag);
// registro modifica RawItem
dbCtx.Entry(currData).State = EntityState.Modified;
// salvo il tutto
dbCtx.SaveChanges();
done = true;
}
}
dbCtx.SaveChanges();
done = true;
}
catch (Exception exc)
{
@@ -916,7 +948,7 @@ namespace MagMan.Data.Tenant.Controllers
* */
var currData = dbCtx
.DbSetResources
.Where(x => rec2upd.ResourceId > 0 && x.ResourceId == rec2upd.ResourceId)
.Where(x => rec2upd.ResourceId > 0 && x.ResourceId == rec2upd.ResourceId)
.FirstOrDefault();
// aggiorno
@@ -2,6 +2,7 @@
using MagMan.Core.DTO;
using MagMan.Data.Tenant.Controllers;
using MagMan.Data.Tenant.DbModels;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NLog;
@@ -231,6 +232,62 @@ namespace MagMan.Data.Tenant.Services
return fatto;
}
/// <summary>
/// Ricerca item da QrCode
/// </summary>
/// <param name="nKey">Key di riferimento</param>
/// <param name="QrCode">QrCode/Dtmx cercato</param>
/// <returns></returns>
public async Task<RawItemModel> ItemGetByQr(int nKey, string QrCode)
{
RawItemModel? dbResult = new RawItemModel();
string cacheKey = $"{Const.rKeyConfig}:{nKey}:{QrCode}";
string source = "DB";
string cString = ConnString(nKey);
try
{
string currKey = $"{Const.rKeyConfig}:{nKey}:ItemByQr:{QrCode}";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = await redisDb.StringGetAsync(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
var tempResult = JsonConvert.DeserializeObject<RawItemModel>(rawData);
if (tempResult == null)
{
dbResult = new RawItemModel();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.ItemGetByQr(cString, QrCode);
if (dbResult != null && dbResult.ItemDtmx.ToUpper() == QrCode.ToUpper())
{
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
}
}
if (dbResult == null)
{
dbResult = new RawItemModel();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"ItemGetByQr | {source} in: {ts.TotalMilliseconds} ms");
}
catch (Exception exc)
{
Log.Error($"Error during ItemGetByQr:{Environment.NewLine}{exc}");
}
return dbResult;
}
/// <summary>
/// Update record Item + refresh cache
/// </summary>
@@ -1039,6 +1096,7 @@ namespace MagMan.Data.Tenant.Services
return newId;
}
#endregion Public Methods
#region Private Fields
+60
View File
@@ -0,0 +1,60 @@
<PageTitle>@Title</PageTitle>
<div class="card">
<div class="card-header table-primary pb-0 mb-0">
<div class="d-flex justify-content-between">
<div class="px-2">
<h2>@Title</h2>
</div>
<div class="px-2">
@if (processing)
{
<span class="spinner-border"></span> <i>...working...</i>
}
<button @onclick="() => Reset()" class="btn btn-primary"><i class="fas fa-sync-alt"></i></button>
</div>
</div>
</div>
<div class="card-body p-1">
<div class="row">
<div class="col-12 form-group">
<input @ref="CodeInput" @bind="@inputValue" class="form-control" autofocus="true"></input>
</div>
@if (!string.IsNullOrEmpty(lastCmd))
{
<div class="col-12 my-1">
@if (IsPickup || IsDeposit)
{
<button class="btn btn-lg btn-block btn-success" @onclick="() => ConfirmOperation()">
@if (IsPickup)
{
<i class="fas fa-download pr-2" aria-hidden="true"></i>
}
else if (IsDeposit)
{
<i class="fas fa-upload pr-2" aria-hidden="true"></i>
}
Confirm @Title
</button>
}
</div>
}
<div class="col-12">
@if (!string.IsNullOrEmpty(alertMessage))
{
<div class="alert alert-danger text-center fade show">
@alertMsg
</div>
}
@if (!string.IsNullOrEmpty(lastMessage))
{
<div class="alert alert-success text-center fade show">
@lastMsg
</div>
}
</div>
</div>
</div>
</div>
+255
View File
@@ -0,0 +1,255 @@
// Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this
// file to you under the MIT license.
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MagMan.Data.Tenant.DbModels;
using MagMan.Data.Tenant.Services;
using MagMan.Core.Services;
namespace MagMan.UI.Components
{
public partial class CodeReader : IDisposable
{
#region Public Properties
[Parameter]
public bool IsDeposit { get; set; } = true;
[Parameter]
public bool IsPickup { get; set; } = true;
[Parameter]
public string Title { get; set; } = "Pick/Deposit";
#endregion Public Properties
#region Public Methods
public void Dispose()
{
AppMService.EA_CustomerSel -= AppMService_EA_CustomerSel;
AppMService.EA_KeySel -= AppMService_EA_KeySel;
}
public async Task SetFocusAsync()
{
//await CodeInput.FocusAsync(JSRuntime);
await CodeInput.FocusAsync(true);
}
#endregion Public Methods
#region Protected Properties
[Inject]
protected MessageService AppMService { get; set; } = null!;
protected string currUserId
{
get
{
string userName = "";
var authState = AuthStateProvider.GetAuthenticationStateAsync().Result;
var user = authState.User;
if (user != null && user.Identity != null)
{
if (user.Identity.IsAuthenticated)
{
userName = $"{user.Identity.Name}";
}
else
{
userName = "N.A.";
}
}
return userName;
}
}
#endregion Protected Properties
#region Protected Methods
protected async Task ConfirmOperation()
{
//if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confirm operation?"))
// return;
int qtyMov = 0;
if (IsPickup)
{
qtyMov = -1;
}
else if (IsDeposit)
{
qtyMov = 1;
}
if (qtyMov != 0)
{
if (currRecord != null)
{
await TService.ItemModQty(KeyNum, currRecord, qtyMov, currUserId);
alertMessage = "";
lastCmd = "";
if (currRecord.MaterialNav != null)
{
lastMessage = $"<h4>Operation Confirmed!</h4><b>{qtyMov} x {currRecord.MaterialNav.MatCode}</b> {currRecord.MaterialNav.MatDesc} <div class=\"small\">{currRecord.LMm:N3}x{currRecord.WMm:N3}x{currRecord.HMm:N3}</div>";
}
else
{
lastMessage = $"<h4>Operation Confirmed!</h4><b>{qtyMov} x ND</b> ??? <div class=\"small\">{currRecord.LMm:N3}x{currRecord.WMm:N3}x{currRecord.HMm:N3}</div>";
}
}
await Task.Delay(1);
StateHasChanged();
await Task.Delay(scanOpDelay);
await ReloadData();
await SetFocusAsync();
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await SetFocusAsync();
}
}
protected override async Task OnInitializedAsync()
{
string rawConf = Configuration["OptConf:ScanOpDelay"];
if (rawConf != null)
{
int.TryParse(rawConf, out scanOpDelay);
}
KeyNum = AppMService.KeyNum;
AppMService.EA_CustomerSel += AppMService_EA_CustomerSel;
AppMService.EA_KeySel += AppMService_EA_KeySel;
await ReloadData();
}
protected async Task processInput(string newVal)
{
processing = true;
alertMessage = "";
lastMessage = "";
var remnRecord = await TService.ItemGetByQr(KeyNum, newVal);
if (remnRecord != null && remnRecord.MatId > 0 && remnRecord.ItemDtmx == newVal)
{
currRecord = remnRecord;
lastCmd = newVal;
if (remnRecord.MaterialNav != null)
{
lastMessage = $"<b>{remnRecord.MaterialNav.MatCode}</b> {remnRecord.MaterialNav.MatDesc} <div class=\"small\">{remnRecord.LMm:N3}x{remnRecord.WMm:N3}x{remnRecord.HMm:N3}</div>";
}
else
{
lastMessage = $"<b>ND</b> ??? <div class=\"small\">{remnRecord.LMm:N3}x{remnRecord.WMm:N3}x{remnRecord.HMm:N3}</div>";
}
}
else
{
alertMessage = $"Error: code {newVal} not valid / not found";
lastCmd = "";
}
processing = false;
}
protected async Task Reset()
{
await ReloadData();
await SetFocusAsync();
}
#endregion Protected Methods
#region Private Fields
private string alertMessage = "";
private ElementReference CodeInput;
private RawItemModel? currRecord = null;
private string lastCmd = "";
private string lastMessage = "";
private bool processing = false;
private int scanOpDelay = 5000;
#endregion Private Fields
#region Private Properties
private MarkupString alertMsg { get => (MarkupString)alertMessage; }
[Inject]
private AuthenticationStateProvider AuthStateProvider { get; set; } = null!;
[Inject]
private IConfiguration Configuration { get; set; } = null!;
private int CustomerID { get; set; } = 0;
private string inputValue
{
get
{
return "";
}
set
{
var pUpd = Task.Run(async () =>
{
await processInput(value.Trim());
});
pUpd.Wait();
}
}
[Inject]
private IJSRuntime JSRuntime { get; set; } = null!;
private int KeyNum { get; set; } = 0;
private MarkupString lastMsg { get => (MarkupString)lastMessage; }
[Inject]
private TenantService TService { get; set; } = null!;
#endregion Private Properties
#region Private Methods
private async void AppMService_EA_CustomerSel()
{
CustomerID = AppMService.CustomerID;
//await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
private async void AppMService_EA_KeySel()
{
KeyNum = AppMService.KeyNum;
//await Task.Delay(1);
await InvokeAsync(StateHasChanged);
}
private async Task ReloadData()
{
currRecord = null;
alertMessage = "";
lastMessage = "";
lastCmd = "";
await Task.Delay(1);
}
#endregion Private Methods
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.0.2402.0211</Version>
<Version>1.0.2402.0219</Version>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
+1 -1
View File
@@ -37,7 +37,7 @@ namespace MagMan.UI.Pages
protected override void OnInitialized()
{
AppMService.ShowSearch = false;
AppMService.ShowCustomers = false;
AppMService.ShowCustomers = true;
AppMService.PageName = "Admin Area";
AppMService.PageIcon = "fa-solid fa-building pr-2";
AppMService.EA_CustomerSel += AppMService_EA_CustomerSel;
+14
View File
@@ -0,0 +1,14 @@
@page "/Deposit"
@inject MessageService AppMService
<CodeReader IsPickup="false" IsDeposit="true" Title="Deposit"></CodeReader>
@code {
protected override void OnInitialized()
{
AppMService.ShowSearch = false;
AppMService.ShowCustomers = true;
AppMService.PageName = "Deposit";
AppMService.PageIcon = "fa-solid fa-upload pr-2";
}
}
+15
View File
@@ -0,0 +1,15 @@
@page "/PickUp"
@inject MessageService AppMService
<CodeReader IsPickup="true" IsDeposit="false" Title="PickUp"></CodeReader>
@code {
protected override void OnInitialized()
{
AppMService.ShowSearch = false;
AppMService.ShowCustomers = true;
AppMService.PageName = "Pickup";
AppMService.PageIcon = "fa-solid fa-download pr-2";
}
}
+10
View File
@@ -56,6 +56,16 @@
<i class="fa-solid fa-warehouse pe-2"></i> Magazzino
</NavLink>
</div>
<div class="nav-item px-2">
<NavLink class="nav-link py-0 px-2 mb-0" href="Deposit">
<i class="fa-solid fa-upload pe-2" aria-hidden="true"></i>Deposit
</NavLink>
</div>
<div class="nav-item px-2">
<NavLink class="nav-link py-0 px-2 mb-0" href="PickUp">
<i class="fa-solid fa-download pe-2" aria-hidden="true"></i>Pickup
</NavLink>
</div>
<div class="nav-item px-2">
<NavLink class="nav-link py-0 px-2 mb-0" href="ResetCache">
<i class="fa-solid fa-exclamation-triangle pe-2"></i> Reset Cache
+2 -1
View File
@@ -33,7 +33,8 @@
"jumpRedir": "~/../../",
"CodModulo": "MagMan",
"MultiRoleEnab": false,
"MultiClaimEnab": true
"MultiClaimEnab": true,
"ScanOpDelay": 3000
},
"AlarmDest": "samuele.locatelli@egalware.com, ceo@steamware.net",
"MailKitMailSettings": {
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>MagMan - Wood Warehouse Management System</i>
<h4>Versione: 1.0.2402.0211</h4>
<h4>Versione: 1.0.2402.0219</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
1.0.2402.0211
1.0.2402.0219
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.0.2402.0211</version>
<version>1.0.2402.0219</version>
<url>http://nexus.steamware.net/repository/SWS/MagMan/stable/0/MagMan.UI.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/MagMan/stable/0/ChangeLog.html</changelog>
<mandatory>false</mandatory>