Update filtro x ultimi movimenti

This commit is contained in:
Samuele Locatelli
2021-11-22 20:34:49 +01:00
parent c9cd2b2df1
commit b2677219d5
9 changed files with 549 additions and 240 deletions
@@ -76,6 +76,22 @@ namespace NKC.Data.Controllers
return dbResult;
}
public List<MovMagModel> MovMagGetFilt(int RemnId, int numShow)
{
List<MovMagModel> dbResult = new List<MovMagModel>();
using (NKCContext localDbCtx = new NKCContext(_configuration))
{
dbResult = localDbCtx
.DbSetMovMag
.Where(x => x.RemnID==RemnId)
.OrderByDescending(o => o.DtRec)
//.Include(m => m.RemnantNav)
.Take(numShow)
.ToList();
}
return dbResult;
}
public List<RemnantsModel> RemnantsGetAll()
{
List<RemnantsModel> dbResult = new List<RemnantsModel>();
+1 -147
View File
@@ -1,16 +1,4 @@
@using Microsoft.AspNetCore.Components.Authorization
@using NKC.Data.DbModels
@using REMAN.Components
@using REMAN.Data
@using static JsFunctions
@inject AuthenticationStateProvider AuthStateProvider
@inject IJSRuntime JSRuntime
@inject RDataService DataService
<PageTitle>@Title</PageTitle>
<PageTitle>@Title</PageTitle>
<div class="card">
<div class="card-header table-primary pb-0 mb-0">
@@ -65,138 +53,4 @@
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Pick/Deposit";
[Parameter]
public bool IsPickup { get; set; } = true;
private ElementReference CodeInput;
private bool processing = false;
private string alertMessage = "";
private string lastMessage = "";
private MarkupString alertMsg
{
get => (MarkupString)alertMessage;
}
private MarkupString lastMsg
{
get => (MarkupString)lastMessage;
}
private RemnantsModel currRecord = null;
private string lastCmd = "";
private string inputValue
{
get
{
return "";
}
set
{
var pUpd = Task.Run(async () =>
{
await processInput(value.Trim());
});
pUpd.Wait();
}
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await SetFocusAsync();
}
}
public async Task SetFocusAsync()
{
await CodeInput.FocusAsync(JSRuntime);
}
protected async Task processInput(string newVal)
{
processing = true;
alertMessage = "";
lastMessage = "";
var remnRecord = await DataService.SearchQrRemnant(newVal);
if (remnRecord != null && remnRecord.MatID > 0 && remnRecord.RemDtmx == newVal)
{
currRecord = remnRecord;
lastCmd = newVal;
lastMessage = $"<b>{remnRecord.MaterialNav.MatExtCode}</b> {remnRecord.MaterialNav.MatDesc} <div class=\"small\">{remnRecord.LMm:N3}x{remnRecord.WMm:N3}x{remnRecord.TMm:N3}</div>";
}
else
{
alertMessage = $"Error: code {newVal} not valid / not found";
lastCmd = "";
}
processing = false;
}
private async Task ReloadData()
{
currRecord = null;
alertMessage = "";
lastMessage = "";
lastCmd = "";
await Task.Delay(1);
}
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;
}
}
protected async Task Reset()
{
await ReloadData();
await SetFocusAsync();
}
protected async Task ConfirmOperation()
{
//if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confirm operation?"))
// return;
int qtyMov = IsPickup ? -1 : 1;
await DataService.RemnantsMovMag(currRecord, currUserId, qtyMov);
alertMessage = "";
lastCmd = "";
lastMessage = $"<h4>Operation Confirmed!</h4><b>{qtyMov} x {currRecord.MaterialNav.MatExtCode}</b> {currRecord.MaterialNav.MatDesc} <div class=\"small\">{currRecord.LMm:N3}x{currRecord.WMm:N3}x{currRecord.TMm:N3}</div>";
await Task.Delay(1);
StateHasChanged();
await Task.Delay(3000);
await ReloadData();
await SetFocusAsync();
}
}
+180
View File
@@ -0,0 +1,180 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.JSInterop;
using NKC.Data.DbModels;
using REMAN.Data;
namespace REMAN.Components
{
public partial class CodeReader
{
#region Private Fields
private string alertMessage = "";
private ElementReference CodeInput;
private RemnantsModel currRecord = null;
private string lastCmd = "";
private string lastMessage = "";
private bool processing = false;
#endregion Private Fields
#region Private Properties
private MarkupString alertMsg { get => (MarkupString)alertMessage; }
[Inject]
private AuthenticationStateProvider AuthStateProvider { get; set; }
[Inject]
private RDataService DataService { get; set; }
private string inputValue
{
get
{
return "";
}
set
{
var pUpd = Task.Run(async () =>
{
await processInput(value.Trim());
});
pUpd.Wait();
}
}
[Inject]
private IJSRuntime JSRuntime { get; set; }
private MarkupString lastMsg { get => (MarkupString)lastMessage; }
#endregion Private Properties
#region Protected Properties
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 Public Properties
[Parameter]
public bool IsPickup { get; set; } = true;
[Parameter]
public string Title { get; set; } = "Pick/Deposit";
#endregion Public Properties
#region Private Methods
private async Task ReloadData()
{
currRecord = null;
alertMessage = "";
lastMessage = "";
lastCmd = "";
await Task.Delay(1);
}
#endregion Private Methods
#region Protected Methods
protected async Task ConfirmOperation()
{
//if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confirm operation?"))
// return;
int qtyMov = IsPickup ? -1 : 1;
await DataService.RemnantsMovMag(currRecord, currUserId, qtyMov);
alertMessage = "";
lastCmd = "";
lastMessage = $"<h4>Operation Confirmed!</h4><b>{qtyMov} x {currRecord.MaterialNav.MatExtCode}</b> {currRecord.MaterialNav.MatDesc} <div class=\"small\">{currRecord.LMm:N3}x{currRecord.WMm:N3}x{currRecord.TMm:N3}</div>";
await Task.Delay(1);
StateHasChanged();
await Task.Delay(3000);
await ReloadData();
await SetFocusAsync();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await SetFocusAsync();
}
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
protected async Task processInput(string newVal)
{
processing = true;
alertMessage = "";
lastMessage = "";
var remnRecord = await DataService.SearchQrRemnant(newVal);
if (remnRecord != null && remnRecord.MatID > 0 && remnRecord.RemDtmx == newVal)
{
currRecord = remnRecord;
lastCmd = newVal;
lastMessage = $"<b>{remnRecord.MaterialNav.MatExtCode}</b> {remnRecord.MaterialNav.MatDesc} <div class=\"small\">{remnRecord.LMm:N3}x{remnRecord.WMm:N3}x{remnRecord.TMm: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 Public Methods
public async Task SetFocusAsync()
{
await CodeInput.FocusAsync(JSRuntime);
}
#endregion Public Methods
}
}
+65
View File
@@ -0,0 +1,65 @@
<div class="card">
<div class="card-header bg-info text-light pb-0 mb-0">
<div class="d-flex justify-content-between">
<div class="px-2">
<div class="d-flex">
<div class="px-2">
<button type="button" class="btn btn-warning py-0" value="Cancel" @onclick="() => Close()">&times;</button>
</div>
<div class="px-2">
<h5>Movements Log</h5>
</div>
</div>
</div>
<div class="px-2">
last <input style="width: 3rem;" @bind-value="@maxRec" />
</div>
</div>
</div>
<div class="card-body">
@if (ListRecords == null)
{
<LoadingData></LoadingData>
}
else if (totalCount == 0)
{
<div class="alert alert-warning text-center display-4">No Record Found</div>
}
else
{
<div class="row">
<div class="col-12">
<table class="table table-sm table-striped">
<thead>
<tr>
<th>Date</th>
<th>Qty</th>
<th class="text-right">Operator</th>
</tr>
</thead>
<tbody>
@foreach (var record in ListRecords)
{
<tr>
<td>
@record.DtRec
</td>
<td>
<b>@record.QtyRec</b>
</td>
<td class="text-right">
<span>@record.UserId</span>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
}
</div>
<div class="card-footer p-1">
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
</div>
</div>
@@ -0,0 +1,140 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using NKC.Data.DbModels;
using REMAN.Data;
namespace REMAN.Components
{
public partial class MovMagDetail
{
#region Private Fields
private List<MovMagModel> ListRecords;
private int _maxRec = 100;
private int maxRec
{
get
{
return _maxRec;
}
set
{
_maxRec = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
private List<MovMagModel> SearchRecords;
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
private int _numRecord { get; set; } = 10;
private int currPage
{
get => _currPage;
set
{
if (_currPage != value)
{
_currPage = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
private bool isLoading { get; set; } = false;
private int numRecord
{
get => _numRecord;
set
{
if (_numRecord != value)
{
_numRecord = value;
var pUpd = Task.Run(async () => await ReloadData());
pUpd.Wait();
}
}
}
#endregion Private Properties
#region Protected Properties
[Inject]
protected RDataService DataService { get; set; }
[Inject]
protected IJSRuntime JSRuntime { get; set; }
protected int totalCount
{
get
{
int answ = 0;
if (SearchRecords != null)
{
answ = SearchRecords.Count;
}
return answ;
}
}
#endregion Protected Properties
#region Public Properties
[Parameter]
public int RemnID { get; set; } = 0;
#endregion Public Properties
#region Private Methods
private async Task ReloadData()
{
isLoading = true;
SearchRecords = await DataService.MovMagGetFilt(RemnID, maxRec);
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
isLoading = false;
}
#endregion Private Methods
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
}
protected void ForceReloadPage(int newNum)
{
currPage = newNum;
}
protected override async Task OnInitializedAsync()
{
await ReloadData();
}
[Parameter]
public EventCallback<int> DataReset { get; set; }
protected async Task Close()
{
await DataReset.InvokeAsync(0);
}
#endregion Protected Methods
}
}
+60 -49
View File
@@ -1,12 +1,10 @@
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using NKC.Data.DbModels;
using NKC.Data.DTO;
using NLog;
using System.Diagnostics;
using System.Security.Claims;
using System.Text;
namespace REMAN.Data
@@ -19,7 +17,6 @@ namespace REMAN.Data
private static ILogger<RDataService> _logger;
private static JsonSerializerSettings? JSSettings;
private List<string> cachedDataList = new List<string>();
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
//private readonly IEmailSender _emailSender;
@@ -27,6 +24,7 @@ namespace REMAN.Data
private readonly IDistributedCache distributedCache;
private readonly IMemoryCache memoryCache;
private List<string> cachedDataList = new List<string>();
/// <summary>
/// Durata assoluta massima della cache IN SECONDI
@@ -44,8 +42,8 @@ namespace REMAN.Data
#region Protected Fields
protected const string rKeyMaterials = "Cache:Materials";
protected const string rKeyRemnants = "Cache:Remnants";
protected const string rKeyQrRemnants = "Cache:QrRemnants";
protected const string rKeyRemnants = "Cache:Remnants";
protected static string connStringBBM = "";
#endregion Protected Fields
@@ -106,6 +104,21 @@ namespace REMAN.Data
dbController.Dispose();
}
/// <summary>
/// invalida tutta la cache in caso di update
/// </summary>
/// <returns></returns>
public async Task InvalidateAllCache()
{
await distributedCache.RemoveAsync(rKeyMaterials);
await distributedCache.RemoveAsync(rKeyRemnants);
foreach (var item in cachedDataList)
{
await distributedCache.RemoveAsync(item);
}
cachedDataList = new List<string>();
}
public async Task<List<MaterialDTO>> MaterialsGetAll()
{
List<MaterialDTO> dbResult = new List<MaterialDTO>();
@@ -131,6 +144,18 @@ namespace REMAN.Data
return await Task.FromResult(dbResult);
}
public async Task<List<MovMagModel>> MovMagGetFilt(int RemnId, int numShow)
{
List<MovMagModel> dbResult = new List<MovMagModel>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.MovMagGetFilt(RemnId, numShow);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB + caching per MovMagGetFilt: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
public async Task<List<RemnantsModel>> RemnantsGetFilt(int matId, int minQty)
{
List<RemnantsModel> dbResult = new List<RemnantsModel>();
@@ -162,6 +187,7 @@ namespace REMAN.Data
}
return await Task.FromResult(dbResult);
}
public async Task<bool> RemnantsIsDupl(RemnantsModel currItem)
{
bool answ = false;
@@ -173,6 +199,31 @@ namespace REMAN.Data
return await Task.FromResult(answ);
}
public async Task<bool> RemnantsMovMag(RemnantsModel currItem, string userId, int deltaQty)
{
bool done = false;
try
{
// recupero item da DB
var currRecord = dbController.RemnantGetByid(currItem.RemnID);
if (currRecord != null && currRecord.RemnID == currItem.RemnID)
{
// modifico qty entro limiti >=0..
if (currRecord.QtyAvail + deltaQty >= 0)
{
currRecord.QtyAvail = currRecord.QtyAvail + deltaQty;
done = dbController.RemnantsUpsert(currRecord, userId);
await InvalidateAllCache();
}
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in RemnantsMovMag:{Environment.NewLine}{exc}");
}
return await Task.FromResult(done);
}
public async Task<bool> RemnantsUpsert(RemnantsModel currItem, string userId)
{
bool done = false;
@@ -187,29 +238,10 @@ namespace REMAN.Data
}
return await Task.FromResult(done);
}
public async Task<bool> RemnantsMovMag(RemnantsModel currItem, string userId, int deltaQty)
public void rollBackEdit(object item)
{
bool done = false;
try
{
// recupero item da DB
var currRecord = dbController.RemnantGetByid(currItem.RemnID);
if (currRecord != null && currRecord.RemnID == currItem.RemnID)
{
// modifico qty entro limiti >=0..
if (currRecord.QtyAvail + deltaQty >= 0)
{
currRecord.QtyAvail = currRecord.QtyAvail+ deltaQty;
done = dbController.RemnantsUpsert(currRecord, userId);
await InvalidateAllCache();
}
}
}
catch (Exception exc)
{
Log.Error($"Eccezione in RemnantsMovMag:{Environment.NewLine}{exc}");
}
return await Task.FromResult(done);
dbController.rollBackEntity(item);
}
public async Task<RemnantsModel> SearchQrRemnant(string QrCode)
@@ -217,7 +249,7 @@ namespace REMAN.Data
RemnantsModel answ = new RemnantsModel();
string rawData = "";
string cacheKey = $"{rKeyQrRemnants}:{QrCode}";
// cerco in redis
// cerco in redis
var redisData = await distributedCache.GetAsync(cacheKey);
if (redisData != null)
{
@@ -244,27 +276,6 @@ namespace REMAN.Data
return await Task.FromResult(answ);
}
/// <summary>
/// invalida tutta la cache in caso di update
/// </summary>
/// <returns></returns>
public async Task InvalidateAllCache()
{
await distributedCache.RemoveAsync(rKeyMaterials);
await distributedCache.RemoveAsync(rKeyRemnants);
foreach (var item in cachedDataList)
{
await distributedCache.RemoveAsync(item);
}
cachedDataList = new List<string>();
}
public void rollBackEdit(object item)
{
dbController.rollBackEntity(item);
}
#endregion Public Methods
}
}
+46 -37
View File
@@ -1,33 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using System.Net.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
using REMAN;
using REMAN.Shared;
using REMAN.Components;
using NKC.Data.DbModels;
using REMAN.Data;
using NKC.Data.DTO;
using REMAN.Data;
namespace REMAN.Pages
{
public partial class Materials : ComponentBase, IDisposable
{
#region Private Fields
private List<MaterialDTO> SearchRecords;
private List<MaterialDTO> ListRecords;
private List<MaterialDTO> SearchRecords;
[Inject]
protected MessageService AppMService { get; set; }
#endregion Private Fields
#region Private Properties
private int _currPage { get; set; } = 1;
@@ -46,8 +33,24 @@ namespace REMAN.Pages
}
}
}
private bool isLoading { get; set; } = false;
private int MatIdSel
{
get
{
return AppMService.MatIdSel;
}
set
{
AppMService.MatIdSel = value;
}
}
[Inject]
private NavigationManager NavManager { get; set; }
private int numRecord
{
get => _numRecord;
@@ -62,17 +65,12 @@ namespace REMAN.Pages
}
}
private int MatIdSel
{
get
{
return AppMService.MatIdSel;
}
set
{
AppMService.MatIdSel = value;
}
}
#endregion Private Properties
#region Protected Properties
[Inject]
protected MessageService AppMService { get; set; }
[Inject]
protected RDataService DataService { get; set; }
@@ -80,9 +78,6 @@ namespace REMAN.Pages
[Inject]
protected IJSRuntime JSRuntime { get; set; }
[Inject]
private NavigationManager NavManager { get; set; }
protected int totalCount
{
get
@@ -96,6 +91,10 @@ namespace REMAN.Pages
}
}
#endregion Protected Properties
#region Private Methods
private async Task ReloadData()
{
isLoading = true;
@@ -104,6 +103,10 @@ namespace REMAN.Pages
isLoading = false;
}
#endregion Private Methods
#region Protected Methods
protected void ForceReload(int newNum)
{
numRecord = newNum;
@@ -125,6 +128,11 @@ namespace REMAN.Pages
await ReloadData();
}
protected void ResetData()
{
//DataService.rollBackEdit(currRecord);
}
protected void Select(MaterialDTO selRecord)
{
MatIdSel = selRecord.MatID;
@@ -132,14 +140,15 @@ namespace REMAN.Pages
NavManager.NavigateTo($"Remnants");
}
protected void ResetData()
{
//DataService.rollBackEdit(currRecord);
}
#endregion Protected Methods
#region Public Methods
public void Dispose()
{
//AppMService.EA_SearchUpdated -= OnSeachUpdated;
}
#endregion Public Methods
}
}
+11 -5
View File
@@ -10,7 +10,7 @@
<div class="px-2">
<h2>Remnants</h2>
</div>
width <div class="px-2">
width <div class="px-2">
@if (processing)
{
<span class="spinner-border"></span> <i>...working...</i>
@@ -63,7 +63,7 @@ width <div class="px-2">
else
{
<div class="row">
<div class="col-12">
<div class="col">
<table class="table table-sm table-striped">
<thead>
<tr>
@@ -79,7 +79,7 @@ width <div class="px-2">
<tbody>
@foreach (var record in ListRecords)
{
<tr>
<tr class="@checkSelect(record.RemnID)">
<td class="text-nowrap pr-2" style="width:6rem;">
<div class="row mb-2">
<div class="col-6 px-2">
@@ -112,8 +112,8 @@ width <div class="px-2">
<td>
<div class="small">@record.RemDtmx</div>
<div>
<b>@record.MaterialNav.MatExtCode</b>
<span class="small">@record.MaterialNav.MatDesc</span>
<b>@record.MaterialNav.MatExtCode</b>
<span class="small">@record.MaterialNav.MatDesc</span>
</div>
</td>
<td>
@@ -143,6 +143,12 @@ width <div class="px-2">
</tbody>
</table>
</div>
@if (showDetail)
{
<div class="col-4 small">
<MovMagDetail RemnID="@RemnIdSel" DataReset="ResetData"></MovMagDetail>
</div>
}
</div>
}
</div>
+30 -2
View File
@@ -21,7 +21,7 @@ namespace REMAN.Pages
#region Protected Fields
//protected int _SelMatID = 0;
protected int RemnIdSel = 0;
protected bool processing = false;
#endregion Protected Fields
@@ -46,6 +46,14 @@ namespace REMAN.Pages
}
}
private bool showDetail
{
get
{
return RemnIdSel > 0;
}
}
private bool isLoading { get; set; } = false;
private int numRecord
@@ -203,6 +211,7 @@ namespace REMAN.Pages
protected void Clone(RemnantsModel selRecord)
{
RemnIdSel = 0;
currRecord = new RemnantsModel()
{
MatID = selRecord.MatID,
@@ -219,6 +228,7 @@ namespace REMAN.Pages
protected void Edit(RemnantsModel selRecord)
{
RemnIdSel = 0;
currRecord = selRecord;
}
@@ -232,6 +242,21 @@ namespace REMAN.Pages
currPage = newNum;
}
public string checkSelect(int RemnId)
{
string answ = "";
if (currRecord != null)
{
try
{
answ = (currRecord.RemnID == RemnId) ? "table-info" : "";
}
catch
{ }
}
return answ;
}
protected override async Task OnInitializedAsync()
{
//SelMatID = 0;
@@ -263,16 +288,19 @@ namespace REMAN.Pages
{
DataService.rollBackEdit(currRecord);
currRecord = null;
RemnIdSel = 0;
}
protected void Select(RemnantsModel selRecord)
{
currRecord = selRecord;
//currRecord = selRecord;
RemnIdSel = selRecord.RemnID;
}
protected async Task UpdateData()
{
currRecord = null;
RemnIdSel = 0;
await ReloadData();
}