Completato editing dei record elenchi generico, compreso spostamenti + eliminazioni varie

This commit is contained in:
Samuele Locatelli
2025-09-18 18:23:49 +02:00
parent 184d536bb0
commit 7fbec59c8d
11 changed files with 339 additions and 112 deletions
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NLog;
using NLog.LayoutRenderers;
using static EgwCoreLib.Lux.Core.Enums;
namespace EgwCoreLib.Lux.Data.Controllers
@@ -63,11 +64,11 @@ namespace EgwCoreLib.Lux.Data.Controllers
}
/// <summary>
/// Esegue eliminazione + refresh cache
/// Esegue eliminazione
/// </summary>
/// <param name="selRec"></param>
/// <param name="rec2del"></param>
/// <returns></returns>
internal async Task<bool> GenClassDeleteAsync(GenClassModel upsRec)
internal async Task<bool> GenClassDeleteAsync(GenClassModel rec2del)
{
bool answ = false;
//using (DataLayerContext dbCtx = new DataLayerContext(configuration))
@@ -77,12 +78,12 @@ namespace EgwCoreLib.Lux.Data.Controllers
{
var dbResult = dbCtx
.DbSetGenClass
.Where(x => x.ClassCod == upsRec.ClassCod)
.Where(x => x.ClassCod == rec2del.ClassCod)
.FirstOrDefault();
var numChild = dbCtx
.DbSetGenVal
.Count(x => x.ClassCod == upsRec.ClassCod);
.Count(x => x.ClassCod == rec2del.ClassCod);
// se trovato e NON HA record child --> elimino
if (dbResult != null && numChild == 0)
{
@@ -152,7 +153,8 @@ namespace EgwCoreLib.Lux.Data.Controllers
dbCtx.DbSetGenClass.Add(upsRec);
}
// salvo...
await dbCtx.SaveChangesAsync();
int numAct = await dbCtx.SaveChangesAsync();
answ = numAct > 0;
}
catch (Exception exc)
{
@@ -162,6 +164,51 @@ namespace EgwCoreLib.Lux.Data.Controllers
return answ;
}
/// <summary>
/// Esegue eliminazione
/// </summary>
/// <param name="rec2del"></param>
/// <returns></returns>
internal async Task<bool> GenValDeleteAsync(GenValueModel rec2del)
{
bool answ = false;
//using (DataLayerContext dbCtx = new DataLayerContext(configuration))
using (DataLayerContext dbCtx = new DataLayerContext())
{
try
{
var dbResult = dbCtx
.DbSetGenVal
.Where(x => x.GenValID == rec2del.GenValID)
.FirstOrDefault();
// se trovato --> elimino e sposto i rimanenti...
if (dbResult != null)
{
// modifico record successivi...
var list2Move = dbCtx
.DbSetGenVal
.Where(x => x.ClassCod == rec2del.ClassCod && x.Ordinal> dbResult.Ordinal)
.ToList();
foreach (var item in list2Move)
{
item.Ordinal--;
dbCtx.Entry(item).State = EntityState.Modified;
}
// elimino
dbCtx.DbSetGenVal.Remove(dbResult);
// salvo tutto
await dbCtx.SaveChangesAsync();
}
}
catch (Exception exc)
{
Log.Error($"Eccezione durante GenValDeleteAsync{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Elenco valori x classe richiesta
/// </summary>
@@ -191,6 +238,112 @@ namespace EgwCoreLib.Lux.Data.Controllers
return dbResult;
}
/// <summary>
/// Esegue spostamento nell'ordinamento relativo alla classe
/// NB: verifica spostamento sia ammissibile: se primo rec non "sale", se ultimo non "scende"...
/// </summary>
/// <param name="selRec"></param>
/// <param name="moveUp"></param>
/// <returns></returns>
internal async Task<bool> GenValMoveAsync(GenValueModel selRec, bool moveUp)
{
bool answ = false;
//using (DataLayerContext dbCtx = new DataLayerContext(configuration))
using (DataLayerContext dbCtx = new DataLayerContext())
{
try
{
var currRec = dbCtx
.DbSetGenVal
.Where(x => x.GenValID == selRec.GenValID)
.FirstOrDefault();
if (currRec != null)
{
// recupero info del num rec del suo gruppo
int numRec = dbCtx
.DbSetGenVal
.Count(x => x.ClassCod == selRec.ClassCod);
// verifico NON sia primo/ultimo...
bool canMove = false;
int newPos = moveUp ? currRec.Ordinal - 1 : currRec.Ordinal + 1;
if (moveUp)
{
canMove = newPos > 0;
}
else
{
canMove = newPos <= numRec;
}
// se abilitato --> aggiorno i 2 record...
if (canMove)
{
var otherRec = dbCtx
.DbSetGenVal
.Where(x => x.ClassCod == selRec.ClassCod && x.Ordinal == newPos)
.FirstOrDefault();
if (otherRec != null)
{
otherRec.Ordinal = currRec.Ordinal;
dbCtx.Entry(otherRec).State = EntityState.Modified;
currRec.Ordinal = newPos;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
// salvo...
int numAct = await dbCtx.SaveChangesAsync();
answ = numAct > 0;
}
}
}
catch (Exception exc)
{
Log.Error($"Eccezione durante GenValMoveAsync{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Esegue Upsert del record ricevuto
/// </summary>
/// <param name="upsRec"></param>
/// <returns></returns>
internal async Task<bool> GenValUpsertAsync(GenValueModel upsRec)
{
bool answ = false;
//using (DataLayerContext dbCtx = new DataLayerContext(configuration))
using (DataLayerContext dbCtx = new DataLayerContext())
{
try
{
var currRec = dbCtx
.DbSetGenVal
.Where(x => x.GenValID == upsRec.GenValID)
.FirstOrDefault();
// se trovato --> aggiorno
if (currRec != null)
{
currRec.ValString = upsRec.ValString;
dbCtx.Entry(currRec).State = EntityState.Modified;
}
// se mancasse --> aggiungo
else
{
dbCtx.DbSetGenVal.Add(upsRec);
}
// salvo...
int numAct = await dbCtx.SaveChangesAsync();
answ = numAct > 0;
}
catch (Exception exc)
{
Log.Error($"Eccezione durante GenValUpsertAsync{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Eliminazione record item
/// </summary>
@@ -202,6 +202,33 @@ namespace EgwCoreLib.Lux.Data.Services
return result;
}
/// <summary>
/// Esegue eliminazione + refresh cache
/// </summary>
/// <param name="selRec"></param>
/// <returns></returns>
public async Task<bool> GenValDeleteAsync(GenValueModel selRec)
{
bool result = await dbController.GenValDeleteAsync(selRec);
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:GenClass");
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:GenVal:*");
return result;
}
/// <summary>
/// Esegue spostamento nell'ordinamento relativo alla classe + refresh cache
/// </summary>
/// <param name="selRec"></param>
/// <param name="moveUp"></param>
/// <returns></returns>
public async Task<bool> GenValMoveAsync(GenValueModel selRec, bool moveUp)
{
bool result = await dbController.GenValMoveAsync(selRec, moveUp);
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:GenClass");
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:GenVal:*");
return result;
}
/// <summary>
/// Elenco valori x classe richiesta
/// </summary>
@@ -237,6 +264,19 @@ namespace EgwCoreLib.Lux.Data.Services
return result;
}
/// <summary>
/// Esegue Upsert del record ricevuto
/// </summary>
/// <param name="upsRec"></param>
/// <returns></returns>
public async Task<bool> GenValUpsertAsync(GenValueModel upsRec)
{
bool result = await dbController.GenValUpsertAsync(upsRec);
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:GenClass");
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:GenVal:*");
return result;
}
/// <summary>
/// Eliminazione record item
/// </summary>
+11 -11
View File
@@ -69,7 +69,7 @@
<button class="btn btn-sm btn-secondary opacity-50"><i class="fa-solid fa-pencil"></i></button>
</td>
<td>@item.ClassCod</td>
<td><input class="form-control form-control-sm" type="text" style="width: 12rem;" @bind="@item.Description" /></td>
<td><input class="form-control form-control-sm border-2 border-info py-1" type="text" style="width: 12rem;" @bind="@item.Description" /></td>
<td class="text-end">@item.NumChild</td>
<td class="text-end">
<button class="btn btn-sm btn-warning" @onclick="DoReset"><i class="fa-solid fa-ban"></i></button>
@@ -88,7 +88,7 @@
<td class="text-end">
@if (item.NumChild > 0)
{
<button class="btn btn-sm btn-secondary opacity-50" disabled><i class="fa-solid fa-trash-can"></i></button>
<button class="btn btn-sm btn-secondary opacity-50" disabled title="Record Child correlati: cancellazione non permessa"><i class="fa-solid fa-trash-can"></i></button>
}
else
{
@@ -99,14 +99,14 @@
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="4">
@if (totalCount >= numRecord)
{
@if (totalCount >= numRecord)
{
<tfoot>
<tr>
<td colspan="5">
<EgwCoreLib.Razor.DataPager currPage="@currPage" PageSize="@numRecord" totalCount="@totalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
}
</td>
</tr>
</tfoot>
</td>
</tr>
</tfoot>
}
</table>
+13 -34
View File
@@ -45,18 +45,6 @@ namespace Lux.UI.Components.Compo
#region Protected Methods
protected void ToggleAdd()
{
AddVisible = !AddVisible;
NewRecord = new GenClassModel()
{
ClassCod = "NewClass",
Description = $"Descrizione-{DateTime.Now:yyyy.MM.dd-HH.mm.ss}"
};
}
private bool AddVisible = false;
private string ErrorMsg = "";
/// <summary>
/// Genera nuovo record e lo salva
/// </summary>
@@ -95,24 +83,6 @@ namespace Lux.UI.Components.Compo
/// <param name="curRec"></param>
protected void DoClone(GenClassModel curRec)
{
#if false
editRecord = new ItemModel()
{
ItemIDParent = curRec.ItemType == Enums.ItemClassType.Bom ? curRec.ItemID : curRec.ItemIDParent,
CodGroup = curRec.CodGroup,
ItemType = curRec.ItemType == Enums.ItemClassType.Bom ? Enums.ItemClassType.BomAlt : curRec.ItemType,
IsService = curRec.IsService,
ItemCode = curRec.ItemCode,
ExtItemCode = $"{curRec.ExtItemCode} - COPY",
SupplCode = curRec.ItemType == Enums.ItemClassType.Bom ? $"{curRec.SupplCode} ALT" : curRec.SupplCode,
Description = $"{curRec.Description} - COPY",
Cost = curRec.Cost,
Margin = curRec.Margin,
QtyMin = curRec.QtyMin,
QtyMax = curRec.QtyMax,
UM = curRec.UM
};
#endif
}
/// <summary>
@@ -192,17 +162,26 @@ namespace Lux.UI.Components.Compo
UpdateTable();
}
protected void ToggleAdd()
{
AddVisible = !AddVisible;
NewRecord = new GenClassModel()
{
ClassCod = "NewClass",
Description = $"Descrizione-{DateTime.Now:yyyy.MM.dd-HH.mm.ss}"
};
}
#endregion Protected Methods
#region Private Fields
private bool AddVisible = false;
private int currPage = 1;
private GenClassModel? EditRecord = null;
private GenClassModel? NewRecord = null;
private string ErrorMsg = "";
private bool isLoading = false;
private GenClassModel? NewRecord = null;
private int numRecord = 10;
private GenClassModel? SelRecord = null;
+55 -39
View File
@@ -8,58 +8,74 @@ else if (totalCount == 0)
}
else
{
if (editRecord != null)
{
@* <ItemEdit CurrRecord="editRecord" ListItemGroup="ListItemGroup" EC_Updated="DoSave" EC_Close="DoCancel"></ItemEdit> *@
}
<table class="table table-sm table-striped">
<thead>
<tr>
<th>
<th class="text-nowrap">
<button class="btn btn-sm btn-primary" title="Reset selezione" @onclick="DoReset"><i class="fa-solid fa-arrow-rotate-right"></i></button>
</th>
<th>ID</th>
<th>Gruppo</th>
<th>Ordin</th>
<th>Valore</th>
<th></th>
@* <th>ID</th> *@
<th class="text-nowrap text-center mx-2">Ord.</th>
<th class="w-100">Valore</th>
<th class="text-nowrap text-end">
<button class="btn btn-sm btn-success" @onclick="DoAdd"><i class="fa-solid fa-plus"></i></button>
</th>
</tr>
</thead>
<tbody>
@foreach (var item in ListRecords)
{
string cssBtnUp = EditRecord == null && item.Ordinal > 1 ? "btn-outline-primary" : "btn-outline-secondary opacity-50 disabled";
string cssBtnDown = EditRecord == null && item.Ordinal < totalCount ? "btn-outline-primary" : "btn-outline-secondary opacity-50 disabled";
<tr>
<td class="text-start text-nowrap">
<button class="btn btn-sm btn-primary" @onclick="() => DoSelect(item)"><i class="fa-solid fa-magnifying-glass"></i></button>
<button class="btn btn-sm btn-info" @onclick="() => DoEdit(item)"><i class="fa-solid fa-pencil"></i></button>
<button class="btn btn-sm btn-success" @onclick="() => DoClone(item)"><i class="fa-solid fa-clone"></i></button>
</td>
<td>@item.GenValID</td>
<td>
@if (item.GenClassNav != null)
{
@item.GenClassNav.Description
}
else
{
@item.ClassCod
}
</td>
<td>@item.Ordinal</td>
<td>@item.ValString</td>
<td>
<button class="btn btn-sm btn-danger" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash-can"></i></button>
</td>
@if (EditRecord != null && item.GenValID == EditRecord.GenValID)
{
<td class="text-start text-nowrap">
<button class="btn btn-sm btn-success" @onclick="() => DoSave(item)"><i class="fa-solid fa-save"></i></button>
<button class="btn btn-sm btn-secondary opacity-50"><i class="fa-solid fa-pencil" title="Edit @item.GenValID"></i></button>
@* <button class="btn btn-sm btn-success" @onclick="() => DoClone(item)" title="Duplicate @item.GenValID"><i class="fa-solid fa-clone"></i></button> *@
</td>
@* <td>@item.GenValID</td> *@
<td class="text-nowrap text-center mx-2">
<button class="btn @cssBtnUp btn-sm fa-solid fa-caret-up"></button>
@item.Ordinal
<button class="btn @cssBtnDown btn-sm fa-solid fa-caret-down"></button>
</td>
<td class="w-100"><input class="form-control form-control-sm border-2 border-info py-1" type="text" @bind="@item.ValString" /></td>
<td class="text-nowrap text-end">
<button class="btn btn-sm btn-warning" @onclick="DoReset"><i class="fa-solid fa-ban"></i></button>
</td>
}
else
{
<td class="text-start text-nowrap">
<button class="btn btn-sm btn-primary" @onclick="() => DoSelect(item)" title="Select @item.GenValID"><i class="fa-solid fa-magnifying-glass"></i></button>
<button class="btn btn-sm btn-info" @onclick="() => DoEdit(item)"><i class="fa-solid fa-pencil" title="Edit @item.GenValID"></i></button>
@* <button class="btn btn-sm btn-success" @onclick="() => DoClone(item)" title="Duplicate @item.GenValID"><i class="fa-solid fa-clone"></i></button> *@
</td>
@* <td>@item.GenValID</td> *@
<td class="text-nowrap text-center mx-2">
<button class="btn @cssBtnUp btn-sm fa-solid fa-caret-up" @onclick="() => MoveRec(item, true)"></button>
@item.Ordinal
<button class="btn @cssBtnDown btn-sm fa-solid fa-caret-down" @onclick="() => MoveRec(item, false)"></button>
</td>
<td class="w-100">@item.ValString</td>
<td class="text-nowrap text-end">
<button class="btn btn-sm btn-danger" @onclick="() => DoDelete(item)"><i class="fa-solid fa-trash-can"></i></button>
</td>
}
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="15">
<EgwCoreLib.Razor.DataPager currPage="@currPage" PageSize="@numRecord" totalCount="@totalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
</td>
</tr>
</tfoot>
@if (totalCount >= numRecord)
{
<tfoot>
<tr>
<td colspan="15">
<EgwCoreLib.Razor.DataPager currPage="@currPage" PageSize="@numRecord" totalCount="@totalCount" numPageChanged="SavePage" numRecordChanged="SaveNumRec"></EgwCoreLib.Razor.DataPager>
</td>
</tr>
</tfoot>
}
</table>
}
+51 -15
View File
@@ -101,7 +101,7 @@ namespace Lux.UI.Components.Compo
QtyMin = curRec.QtyMin,
QtyMax = curRec.QtyMax,
UM = curRec.UM
};
};
#endif
}
@@ -113,13 +113,18 @@ namespace Lux.UI.Components.Compo
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Sicuro di voler eliminare il record? Dettagli: {selRec.ClassCod} | {selRec.ValString}"))
return;
//// esegue eliminazione del record...
//await DLService.ItemDeleteAsync(selRec);
editRecord = null;
selRecord = null;
// esegue eliminazione del record...
await DLService.GenValDeleteAsync(selRec);
EditRecord = null;
SelRecord = null;
await ReloadData();
UpdateTable();
#if false
// segnalo update x reload
await EC_Updated.InvokeAsync(true);
#endif
}
/// <summary>
@@ -128,7 +133,7 @@ namespace Lux.UI.Components.Compo
/// <param name="curRec"></param>
protected void DoEdit(GenValueModel curRec)
{
editRecord = curRec;
EditRecord = curRec;
}
/// <summary>
@@ -136,7 +141,7 @@ namespace Lux.UI.Components.Compo
/// </summary>
protected void DoReset()
{
editRecord = null;
EditRecord = null;
}
/// <summary>
@@ -145,7 +150,7 @@ namespace Lux.UI.Components.Compo
/// <param name="curRec"></param>
protected void DoSelect(GenValueModel curRec)
{
selRecord = curRec;
SelRecord = curRec;
}
protected override async Task OnParametersSetAsync()
@@ -178,13 +183,13 @@ namespace Lux.UI.Components.Compo
private int currPage = 1;
private GenValueModel? editRecord = null;
private GenValueModel? EditRecord = null;
private bool isLoading = false;
private int numRecord = 10;
private GenValueModel? selRecord = null;
private GenValueModel? SelRecord = null;
private int totalCount = 0;
@@ -192,6 +197,30 @@ namespace Lux.UI.Components.Compo
#region Private Methods
private async Task DoAdd()
{
// aggiungo un nuovo record in coda...
EditRecord = new GenValueModel()
{
ClassCod = actFilt.SelCodGroup,
ValString = $"Nuovo-{DateTime.Now:yy.MM.ss HH.mm.ss}",
Ordinal = totalCount + 1
};
await DoSave(EditRecord);
}
/// <summary>
/// Esegue spostamento
/// </summary>
/// <param name="curRec"></param>
/// <param name="moveUp"></param>
/// <returns></returns>
private async Task MoveRec(GenValueModel curRec, bool moveUp)
{
await DLService.GenValMoveAsync(curRec, moveUp);
await DoCancel();
}
private async Task DoCancel()
{
await ResetEdit();
@@ -201,11 +230,11 @@ namespace Lux.UI.Components.Compo
private async Task DoSave(GenValueModel currRec)
{
// salvo
#if false
await DLService.ItemUpsertAsync(currRec);
#endif
await DLService.GenValUpsertAsync(currRec);
await ResetEdit();
UpdateTable();
EditRecord = null;
SelRecord = null;
}
private async Task ReloadData()
@@ -213,12 +242,19 @@ namespace Lux.UI.Components.Compo
isLoading = true;
AllRecords = await DLService.GenValGetFiltAsync(actFilt.SelCodGroup);
// se ho ricerca testuale faccio filtro ulteriore...
if (!string.IsNullOrEmpty(actFilt.SearchVal))
if (string.IsNullOrEmpty(actFilt.SearchVal))
{
AllRecords = AllRecords
.OrderBy(x => x.Ordinal)
.ToList();
}
else
{
AllRecords = AllRecords
.Where(x =>
x.ClassCod.Contains(actFilt.SearchVal, StringComparison.InvariantCultureIgnoreCase) ||
x.ValString.Contains(actFilt.SearchVal, StringComparison.InvariantCultureIgnoreCase))
.OrderBy(x => x.Ordinal)
.ToList();
}
totalCount = AllRecords.Count;
@@ -227,7 +263,7 @@ namespace Lux.UI.Components.Compo
private async Task ResetEdit()
{
// reset edit
editRecord = null;
EditRecord = null;
await ReloadData();
}
+6 -3
View File
@@ -26,11 +26,14 @@
}
else
{
<div class="col-12 col-md-5 col-lg-4">
<div class="col-6">
<GenClassMan ListGenClass="ListGenClass" EC_Selected="SaveSel" EC_Updated="() => ForceReloadAsync()"></GenClassMan>
</div>
<div class="col-12 col-md-7 col-lg-8">
<GenValMan SelFilt="CurrFilt" ListGenClass="ListGenClass"></GenValMan>
<div class="col-6">
@if (!string.IsNullOrEmpty(CurrFilt.SelCodGroup))
{
<GenValMan SelFilt="CurrFilt" ListGenClass="ListGenClass"></GenValMan>
}
</div>
}
</div>
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50</UserSecretsId>
<Version>0.9.2509.1816</Version>
<Version>0.9.2509.1818</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>LUX - Web Windows MES</i>
<h4>Versione: 0.9.2509.1816</h4>
<h4>Versione: 0.9.2509.1818</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
0.9.2509.1816
0.9.2509.1818
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>0.9.2509.1816</version>
<version>0.9.2509.1818</version>
<url>http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html</changelog>
<mandatory>false</mandatory>