Update ricerfa articoli x tipo

This commit is contained in:
Samuele Locatelli
2026-05-27 16:20:09 +02:00
parent 9d513edab4
commit fcf3bc8400
6 changed files with 137 additions and 121 deletions
+37 -11
View File
@@ -502,25 +502,51 @@ namespace MP.Data.Controllers
/// Elenco tabella Articoli da filtro
/// </summary>
/// <param name="numRecord"></param>
/// <param name="tipoArt"></param>
/// <param name="azienda"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<List<AnagArticoliModel>> ArticoliGetSearchAsync(int numRecord, string azienda = "*", string searchVal = "")
public async Task<List<AnagArticoliModel>> ArticoliGetSearchAsync(int numRecord, string tipoArt = "*", string azienda = "*", string searchVal = "")
{
List<AnagArticoliModel> dbResult = new List<AnagArticoliModel>();
using (var dbCtx = new MoonProContext(options))
using var dbCtx = new MoonProContext(options);
IQueryable<AnagArticoliModel> query = dbCtx.DbSetArticoli
.AsNoTracking();
// filtro tipo articolo
if (tipoArt != "*")
{
dbResult = await dbCtx
.DbSetArticoli
.AsNoTracking()
.Where(x => (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper()) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal)))
.OrderBy(x => x.CodArticolo)
.Take(numRecord)
.ToListAsync();
//query = query.Where(x => x.Tipo.ToLower() == tipoArt.ToLower());
query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt));
}
return dbResult;
// filtro azienda
if (azienda != "*")
{
//query = query.Where(x => x.Azienda.ToLower() == azienda.ToLower());
query = query.Where(x => EF.Functions.Like(x.Azienda, azienda));
}
// filtro ricerca
if (!string.IsNullOrWhiteSpace(searchVal))
{
//query = query.Where(x =>
// x.CodArticolo.Contains(searchVal) ||
// x.DescArticolo.Contains(searchVal) ||
// x.Disegno.Contains(searchVal));
string pattern = $"%{searchVal}%";
query = query.Where(x =>
EF.Functions.Like(x.CodArticolo, pattern) ||
EF.Functions.Like(x.DescArticolo, pattern) ||
EF.Functions.Like(x.Disegno, pattern));
}
return await query
.OrderBy(x => x.CodArticolo)
.Take(numRecord)
.ToListAsync();
}
/// <summary>
/// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async
/// </summary>
+1 -1
View File
@@ -234,7 +234,7 @@ namespace MP.SPEC.Components
ListStati = await MDService.AnagStatiComm();
selAzienda = await MDService.ConfigTryGetAsync("AZIENDA");
giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze");
ListArticoli = await MDService.ArticoliGetSearchAsync(100000, selAzienda, "");
ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, "");
ListMacchine = MDService.MacchineGetFilt("*");
await ReloadData(true);
}
+1 -1
View File
@@ -108,7 +108,7 @@ namespace MP.SPEC.Components
if (!ListArtDisabled)
{
Log.Debug("START GetArticoli");
var rawData = await MDataService.ArticoliGetSearch(10000, "*", searchVal);
var rawData = await MDataService.ArticoliGetSearch(10000, "*", "*", searchVal);
// trasformo!
if (rawData != null)
{
+4 -5
View File
@@ -416,19 +416,18 @@ namespace MP.SPEC.Data
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<List<AnagArticoliModel>> ArticoliGetSearchAsync(int numRecord, string azienda, string searchVal)
public async Task<List<AnagArticoliModel>> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal)
{
string sKey = string.IsNullOrWhiteSpace(searchVal) ? "***" : searchVal.Trim();
string memKey = $"ART_SEARCH_MEM:{azienda}:{sKey}:{numRecord}";
string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{numRecord}";
string redisKey = $"{Utils.redisArtList}:{tipoArt}:{azienda}:{sKey}:{numRecord}";
return await GetOrFetchAsync(
operationName: "ArticoliGetSearchAsync",
cacheKey: redisKey,
expiration: TimeSpan.FromMinutes(2),
expiration: TimeSpan.FromMinutes(redisLongTimeCache),
fetchFunc: async () =>
await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal)
await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal)
?? new List<AnagArticoliModel>()
);
}
+56 -19
View File
@@ -12,17 +12,31 @@
<h3>Articoli </h3>
</div>
<div class="px-2">
<button class="btn btn-success" @onclick="() => addNew()">Nuovo <i class="bi bi-plus-square"></i></button>
@if (CanAdd)
{
<button class="btn btn-success" @onclick="AddNew">Nuovo <i class="bi bi-plus-square"></i></button>
}
</div>
</div>
</div>
<div class="px-0 align-content-center">
<div class="input-group">
<span class="input-group-text"><i class="fa fa-rectangle-list"></i></span>
<select @bind="@selTipoArt" class="form-select form-select-sm" style="width: 8rem; flex: 0 0 auto;" title="Selezionare il tipo di Articolo da mostrare" @bind:after="ResetDataAsync">
<option value="*">--- Tutti ---</option>
@if (ListTipoArt != null)
{
foreach (var item in ListTipoArt)
{
<option value="@item.value">@item.label</option>
}
}
</select>
<span class="input-group-text"><i class="fa fa-search"></i></span>
<input type="text" class="form-control form-control-sm" placeholder="Cerca (3+ char)" aria-label="Ricerca" title="Ricerca (3+ char)" @bind="@SearchVal" @bind:after="ReloadDataAsync">
<button class="btn @searchCss" @onclick="() => resetSearch()"><i class="fa fa-ban"></i></button>
<input type="text" class="form-control form-control-sm" placeholder="Cerca (3+ char)" aria-label="Ricerca" title="Ricerca (3+ char)" @bind="@SearchVal" @bind:after="ResetDataAsync">
<button class="btn @searchCss" @onclick="() => ResetSearch()"><i class="fa fa-ban"></i></button>
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
<select @bind="@selAzienda" class="form-select form-select-sm" title="Selezionare l'azienda da visualizzare" @bind:after="ReloadAziendaAsync">
<select @bind="@selAzienda" class="form-select form-select-sm" style="width: 15rem; flex: 0 0 auto;" title="Selezionare l'azienda da visualizzare" @bind:after="ReloadAziendaAsync">
@if (ListAziende != null)
{
foreach (var item in ListAziende)
@@ -47,11 +61,11 @@
<div class="col-3">
<div class="input-group">
<span class="input-group-text">Codice</span>
@if(isNewArt)
@if (isNewArt)
{
<input type="text" class="form-control" placeholder="Articolo" @bind-value="@currRecord.CodArticolo">
}
else
else
{
<input type="text" class="form-control" disabled placeholder="Articolo" @bind-value="@currRecord.CodArticolo">
}
@@ -83,15 +97,31 @@
<div class="col-3">
<div class="input-group" title="Tipo">
<span class="input-group-text">Tipo</span>
<select @bind="@currRecord.Tipo" class="form-select text-end">
@if (ListTipoArt != null)
{
foreach (var item in ListTipoArt)
@if (currRecord.Tipo.Equals("KIT"))
{
<select @bind="@currRecord.Tipo" class="form-select text-end" disabled>
@if (ListTipoArt != null)
{
<option value="@item.value">@item.label</option>
foreach (var item in ListTipoArt)
{
<option value="@item.value">@item.label</option>
}
}
}
</select>
</select>
}
else
{
<select @bind="@currRecord.Tipo" class="form-select text-end">
@if (ListTipoArt != null)
{
foreach (var item in ListTipoArt)
{
<option value="@item.value">@item.label</option>
}
}
</select>
}
</div>
</div>
<div class="col-5">
@@ -102,12 +132,12 @@
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
<button class="btn btn-warning" @onclick="() => ResetDataAsync()">Annulla <i class="bi bi-x-circle"></i></button>
</div>
</div>
<div class="col-2">
<div class="d-grid gap-2">
<button class="btn btn-success" @onclick="() => update(currRecord)">Salva <i class="bi bi-save"></i></button>
<button class="btn btn-success" @onclick="() => UpdateAsync(currRecord)">Salva <i class="bi bi-save"></i></button>
</div>
</div>
</div>
@@ -154,8 +184,15 @@
{
<tr class="@CheckSelect(@record.CodArticolo)">
<td>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm me-1" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
@if (record.Tipo.Equals("KIT"))
{
<button class="btn btn-secondary btn-sm disabled" title="Veto duplicazione KIT"><i class="bi bi-clipboard-check"></i></button>
}
else
{
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
}
</td>
<td>
<div>@record.CodArticolo</div>
@@ -171,7 +208,7 @@
</td>
<td>@record.Azienda</td>
<td>
@if (ArticoloDelEnabled(record.CodArticolo))
@if (ArticoloDelEnabled(record))
{
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
}
@@ -191,7 +228,7 @@
<div class="card-footer py-1">
@if (totalCount > numRecord)
{
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
<DataPager PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
}
</div>
</div>
+38 -84
View File
@@ -26,16 +26,6 @@ namespace MP.SPEC.Pages
GC.Collect();
}
public async void OnSeachUpdated()
{
await InvokeAsync(() =>
{
currPage = 1;
Task task = UpdateData();
StateHasChanged();
});
}
#endregion Public Methods
#region Protected Properties
@@ -49,10 +39,7 @@ namespace MP.SPEC.Pages
[Inject]
protected NavigationManager NavManager { get; set; } = null!;
protected string searchCss
{
get => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary";
}
private string searchCss => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary";
protected string SearchVal
{
@@ -62,35 +49,12 @@ namespace MP.SPEC.Pages
// salvo solo se 3+ chars
if (value.Length > 2 || string.IsNullOrEmpty(value))
{
if (searchVal != value)
{
searchVal = value;
#if false
var pUpd = Task.Run(async () =>
{
ListRecords = null;
await Task.Delay(1);
await ReloadDataAsync();
});
pUpd.Wait();
#endif
}
searchVal = value;
}
}
}
protected int totalCount
{
get
{
int answ = 0;
if (SearchRecords != null)
{
answ = SearchRecords.Count;
}
return answ;
}
}
protected int totalCount = 0;
#endregion Protected Properties
@@ -100,30 +64,26 @@ namespace MP.SPEC.Pages
/// Crea nuovo record e va in editing...
/// </summary>
/// <returns></returns>
protected async Task addNew()
protected void AddNew()
{
isNewArt = true;
currRecord = new AnagArticoliModel()
{
CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}",
DescArticolo = "Nuovo articolo",
Azienda = selAzienda != "*" ? selAzienda : "MAPO",
Azienda = !selAzienda.Equals("*") ? selAzienda : "MAPO",
Disegno = "",
Tipo = "ART",
Tipo = !selTipoArt.Equals("*") ? selTipoArt : "ART",
CurrRev = "",
ProdRev = ""
};
await Task.Delay(1);
}
protected async Task cancel()
{
currRecord = null;
await ReloadDataAsync();
await Task.Delay(1);
}
protected async Task cloneRecord(AnagArticoliModel selRec)
/// <summary>
/// Cloning record
/// </summary>
/// <param name="selRec"></param>
protected void cloneRecord(AnagArticoliModel selRec)
{
isNewArt = true;
// creo record duplicato...
@@ -138,7 +98,6 @@ namespace MP.SPEC.Pages
ProdRev = ""
};
currRecord = newRec;
await Task.Delay(1);
}
/// <summary>
@@ -184,10 +143,10 @@ namespace MP.SPEC.Pages
currRecord = null;
}
protected async Task resetSearch()
protected async Task ResetSearch()
{
SearchVal = "";
await ReloadDataAsync();
await ResetDataAsync();
}
protected async Task resetSel()
@@ -204,19 +163,18 @@ namespace MP.SPEC.Pages
await Task.Delay(1);
}
protected async Task update(AnagArticoliModel selRec)
protected async Task UpdateAsync(AnagArticoliModel selRec)
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche?"))
return;
await Task.Delay(1);
var done = await MDService.ArticoliUpdateRecord(selRec);
currRecord = null;
await ReloadDataAsync();
await Task.Delay(1);
await ResetDataAsync();
}
protected async Task UpdateData()
protected async Task ResetDataAsync()
{
currPage = 1;
currRecord = null;
await ReloadDataAsync();
}
@@ -239,9 +197,8 @@ namespace MP.SPEC.Pages
#region Private Properties
private int _currPage { get; set; } = 1;
private int _numRecord { get; set; } = 10;
private string chkDisabled => isNewArt ? "" : "disabled";
private int _currPage = 1;
private int _numRecord = 10;
private int currPage
{
@@ -281,26 +238,14 @@ namespace MP.SPEC.Pages
if (value != _selAzienda)
{
_selAzienda = value;
#if false
var pUpd = Task.Run(async () =>
{
// svuoto cache redis...
ConfigModel updRec = new ConfigModel()
{
Chiave = "AZIENDA",
Valore = value
};
MDService.ConfigUpdate(updRec);
await MDService.ConfigResetCache();
// ricarico
await Task.Delay(1);
await ReloadDataAsync();
});
pUpd.Wait();
#endif
}
}
}
/// <summary>
/// Tipo articolo selezionato
/// </summary>
private string selTipoArt = "*";
private async Task ReloadAziendaAsync()
{
isLoading = true;
@@ -313,7 +258,7 @@ namespace MP.SPEC.Pages
await MDService.ConfigUpdateAsync(updRec);
await MDService.ConfigResetCache();
// ricarico
await ReloadDataAsync();
await ResetDataAsync();
}
@@ -328,9 +273,12 @@ namespace MP.SPEC.Pages
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
private bool ArticoloDelEnabled(string codArt)
private bool ArticoloDelEnabled(AnagArticoliModel currRec)
{
return MDService.ArticoloDelEnabled(codArt);
if (currRec.Tipo.Equals("KIT"))
return false;
return MDService.ArticoloDelEnabled(currRec.CodArticolo);
}
private async Task ReloadBaseData()
@@ -345,10 +293,16 @@ namespace MP.SPEC.Pages
ListTipoArt = await MDService.AnagTipoArtLvAsync();
}
/// <summary>
/// Verifica cablata x add tutto tranne KIT
/// </summary>
private bool CanAdd => !selTipoArt.Equals("KIT");
private async Task ReloadDataAsync()
{
isLoading = true;
SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selAzienda, SearchVal);
SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selTipoArt, selAzienda, SearchVal);
totalCount = SearchRecords.Count;
UpdateTable();
}