Update in dev versione corrente

This commit is contained in:
Samuele Locatelli
2025-12-09 18:31:31 +01:00
parent fcf3087b89
commit 54c4df7c2f
10 changed files with 269 additions and 27 deletions
+50
View File
@@ -0,0 +1,50 @@
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EgwCoreLib.Lux.Core
{
public class FileUtils
{
#region Public Methods
/// <summary>
/// Restituisce il contenuto del file salvato
/// </summary>
/// <param name="folderPath">Path completo (da share/base path + folder)</param>
/// <param name="secureName">Nome del file "obfuscated"</param>
/// <returns></returns>
public static string LoadFileContent(string folderPath, string secureName)
{
string answ = "";
if (!string.IsNullOrEmpty(folderPath))
{
try
{
// calcolo path file...
string filePath = Path.Combine(folderPath, secureName);
if (File.Exists(filePath))
{
answ = File.ReadAllText(filePath);
}
}
catch (Exception exc)
{
Log.Error($"Exception on LoadFileContent{Environment.NewLine}{exc}");
}
}
return answ;
}
#endregion Public Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
}
}
@@ -1814,7 +1814,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
StepFlowTime = c.StepFlowTime,
StepLeadTime = c.StepLeadTime,
StepPrice = c.StepPrice,
//OrderID = newRec.OrderID,
//OrderID = dbRec.OrderID,
OfferRowUID = c.OfferRowDtx
})
.ToList();
@@ -2483,14 +2483,43 @@ namespace EgwCoreLib.Lux.Data.Controllers
return answ;
}
/// <summary>
/// Restituisce record ordine + righe Ordine dato ID
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
internal async Task<OrderModel?> OrderById(int orderId)
{
OrderModel? dbRec = null;
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
using (DataLayerContext dbCtx = new DataLayerContext())
{
try
{
DateTime adesso = DateTime.Now;
// recupero offerta...
var currRec = dbCtx
.DbSetOrder
.Where(x => x.OrderID == orderId)
.Include(x => x.OrderRowNav)
.FirstOrDefault();
}
catch (Exception exc)
{
Log.Error($"Eccezione durante OrderById{Environment.NewLine}{exc}");
}
}
return dbRec;
}
/// <summary>
/// Genera un nuovo record ordine come cloning completo di un offerta e di TUTTE le relative righe di offerta + rif offerta
/// </summary>
/// <param name="rec2clone"></param>
/// <returns></returns>
internal async Task<bool> OrderFromOffer(OfferModel rec2clone)
internal async Task<int> OrderFromOffer(OfferModel rec2clone)
{
bool answ = false;
int orderId = 0;
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
using (DataLayerContext dbCtx = new DataLayerContext())
{
@@ -2576,11 +2605,12 @@ namespace EgwCoreLib.Lux.Data.Controllers
}
// salvo TUTTI i cambiamenti...
var result = await dbCtx.SaveChangesAsync();
answ = result > 0;
var numSave = await dbCtx.SaveChangesAsync();
// se ok sistemo UID...
if (answ && newRec != null)
if (numSave > 0 && newRec != null)
{
orderId = newRec.OrderID;
// sistemo UID...
foreach (var item in newRec.OrderRowNav)
{
@@ -2627,7 +2657,7 @@ namespace EgwCoreLib.Lux.Data.Controllers
Log.Error($"Eccezione durante OrderFromOffer{Environment.NewLine}{exc}");
}
}
return answ;
return orderId;
}
/// <summary>
@@ -1255,6 +1255,41 @@ namespace EgwCoreLib.Lux.Data.Services
return fatto;
}
/// <summary>
/// Restituisce record ordine + righe Ordine dato ID
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
public async Task<OrderModel> OrderById(int orderId)
{
string source = "DB";
Stopwatch sw = new Stopwatch();
sw.Start();
OrderModel? result = new OrderModel();
// cerco in redis...
string currKey = $"{redisBaseKey}:Orders:ById:{orderId}";
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<OrderModel>($"{rawData}");
source = "REDIS";
}
else
{
result = await dbController.OrderById(orderId);
// serializzo e salvo con config x evitare loop...
rawData = JsonConvert.SerializeObject(result, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, LongCache);
}
if (result == null)
{
result = new OrderModel();
}
sw.Stop();
Log.Debug($"OrderById | {source} | {sw.Elapsed.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Genera un nuovo record ordine:
/// - cloning completo di un offerta + TUTTE le relative righe di offerta + rif offerta
@@ -1262,18 +1297,21 @@ namespace EgwCoreLib.Lux.Data.Services
/// </summary>
/// <param name="rec2clone"></param>
/// <returns></returns>
public async Task<bool> OrderFromOffer(OfferModel rec2clone)
public async Task<int> OrderFromOffer(OfferModel rec2clone)
{
Stopwatch sw = new Stopwatch();
sw.Start();
// calcolo
bool fatto = await dbController.OrderFromOffer(rec2clone);
// svuoto cache...
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Orders:*");
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OrderRows:*");
int orderId = await dbController.OrderFromOffer(rec2clone);
if (orderId > 0)
{
// svuoto cache...
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Orders:*");
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OrderRows:*");
}
sw.Stop();
Log.Debug($"OrderFromOffer in {sw.Elapsed.TotalMilliseconds} ms");
return fatto;
return orderId;
}
/// <summary>
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>0.9.2512.0917</Version>
<Version>0.9.2512.0918</Version>
</PropertyGroup>
<ItemGroup>
+130 -3
View File
@@ -1,3 +1,8 @@
using EgwCoreLib.Lux.Core;
using EgwCoreLib.Lux.Core.Generic;
using EgwCoreLib.Lux.Core.RestPayload;
using EgwCoreLib.Lux.Data;
using EgwCoreLib.Lux.Data.DbModel.Config;
using EgwCoreLib.Lux.Data.DbModel.Sales;
using EgwCoreLib.Lux.Data.Services;
using EgwCoreLib.Razor;
@@ -46,6 +51,9 @@ namespace Lux.UI.Components.Pages
}
}
[Inject]
protected IConfiguration Config { get; set; } = null!;
protected string DivMainCss
{
get => SelRecord != null ? "col-6" : "col-12";
@@ -57,6 +65,9 @@ namespace Lux.UI.Components.Pages
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
[Inject]
protected ProdService PService { get; set; } = null!;
protected string txtState
{
get => allState ? "Tutte" : "Aperte";
@@ -117,6 +128,8 @@ namespace Lux.UI.Components.Pages
{
PeriodoSel = new EgwCoreLib.Utils.DtUtils.Periodo(EgwCoreLib.Utils.DtUtils.PeriodSet.ThisTrim);
SetupArrows();
ConfInit();
await ReloadBaseData();
await ReloadData();
UpdateTable();
}
@@ -138,7 +151,7 @@ namespace Lux.UI.Components.Pages
*
* il puro invio dovrà poter essere fatto anche dalla tab ordini... e serve visualizzazione delle estim pending
* --------------------------------- */
// in primis: se è già confermata chiede una autorizzazione di conferma speciale
if (currRec.OffertState == OfferStates.Confirmed)
{
@@ -150,9 +163,94 @@ namespace Lux.UI.Components.Pages
{
if (!await JSRuntime.InvokeAsync<bool>("confirm", $"Confermi di voler confermare l'offerta e generare gli ordini? verranno generate anche le etichette per tutti i prodotti correlati ({currRec.NumProdItems})"))
return;
await DLService.OrderFromOffer(currRec);
}
// creazione nuovo ordine da offerta
int orderId = await DLService.OrderFromOffer(currRec);
if (orderId > 0)
{
// aggiunge una richiesta di CREAZIONE del file progetto NGE in coda esecuzione per ogni riga d'ordine...
var listOrdRow = await DLService.OrderById(orderId);
// processo riga ordine x riga ordine creando per ogni riga una richiesta...
if (listOrdRow.OrderRowNav != null && listOrdRow.OrderRowNav.Count > 0)
{
// verifico parametri da conf envir...
var envRec = AllConfEnvir.FirstOrDefault(x => x.EnvirID == listOrdRow.Envir);
Egw.Window.Data.Enums.QuestionModes rMode = Egw.Window.Data.Enums.QuestionModes.ORDER;
Egw.Window.Data.Enums.QuestionOrderSubModes rSubMode = Egw.Window.Data.Enums.QuestionOrderSubModes.CREATE;
string reqKey = "";
foreach (var rigaOrd in listOrdRow.OrderRowNav)
{
// preparo le 2 richieste (creazione, stima)
CalcRequestDTO calcReq = new CalcRequestDTO();
bool needCalc = false;
// recupero elenco items collegati alla riga d'ordine
var ProdList = await DLService.ProdItemByOrderRow(rigaOrd.OrderRowID);
List<string> TagsList = ProdList.Select(x => x.ProdLabel).ToList();
//string serTagList = JsonConvert.SerializeObject(TagsList);
string serTagList = string.Join(",", TagsList);
// preparo richiesta serializzata e la accodo (viene inviata richiesta calcolo)
Dictionary<string, string> dictArgs = new Dictionary<string, string>();
dictArgs.Add("UID", rigaOrd.OrderRowUID);
dictArgs.Add("OrderUID", rigaOrd.OrderNav.OrderCode);
dictArgs.Add("Mode", $"{(int)rMode}");
dictArgs.Add("TagsList", serTagList);
// aggiungo file secondo ambiente...
string serKey = envRec != null ? envRec.SerStrucKey : "SerializedData";
switch (listOrdRow.Envir)
{
case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW:
dictArgs.Add(serKey, rigaOrd.SerStruct);
needCalc = rigaOrd.SerStruct.Length > 2;
break;
case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.BEAM:
case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WALL:
case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.CABINET:
// rileggo da file... 2check, spostare?!?
string folderPath = $"SO-{listOrdRow.OfferID:X8}";
string rawData = FileUtils.LoadFileContent(Path.Combine(basePath, folderPath), rigaOrd.FileResource);
dictArgs.Add(serKey, rawData);
dictArgs.Add("FileName", rigaOrd.FileName);
needCalc = rawData.Length > 2;
break;
case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.NULL:
default:
break;
}
// solo SE va calcolato...
if (needCalc)
{
// mando richiesta "create" preliminare con tutti i dati
rSubMode = Egw.Window.Data.Enums.QuestionOrderSubModes.CREATE;
dictArgs.Add("SubMode", $"{(int)rSubMode}");
calcReq = new CalcRequestDTO()
{
DictExec = dictArgs,
EnvType = listOrdRow.Envir
};
reqKey = $"{rMode}:{rSubMode}:{rigaOrd.OrderRowUID}";
await PService.EnqueueRequest("Estimation", reqKey, calcReq);
// parto dalla history attuale
var currHist = listOrdRow.LogHistory;
// aggiungo evento...
currHist.Add(new TaskHistDTO()
{
DtEvent = DateTime.Now,
UserName = "Default User",
Message = $"{reqKey}",
IconCss = "fa-solid fa-hourglass-start"
});
listOrdRow.LogHistory = currHist;
//OrderHist = listOrdRow.LogHistory;
await DLService.OrderUpsert(listOrdRow);
}
}
}
}
}
currRec.OffertState = newStatus;
await DLService.OffertUpsert(currRec);
@@ -164,14 +262,28 @@ namespace Lux.UI.Components.Pages
#region Private Fields
private List<EnvirParamModel> AllConfEnvir = new();
private List<OfferModel> AllRecords = new List<OfferModel>();
private bool allState = false;
/// <summary>
/// Base path x network share files
/// </summary>
private string basePath = "unsafe_uploads";
private int currPage = 1;
private CompileStep currStep = CompileStep.Draft;
private OfferModel? EditRecord = null;
private OfferModel? EditStateRec = null;
private bool isLoading = false;
private List<OfferModel> ListFilt = new List<OfferModel>();
private List<OfferModel> ListRecords = new List<OfferModel>();
private int numRecord = 10;
@@ -182,6 +294,7 @@ namespace Lux.UI.Components.Pages
private EgwCoreLib.Utils.DtUtils.Periodo PeriodoSel = new EgwCoreLib.Utils.DtUtils.Periodo(EgwCoreLib.Utils.DtUtils.PeriodSet.ThisYear);
private string searchVal = "";
private OfferModel? SelRecord = null;
private int totalCount = 0;
@@ -221,6 +334,11 @@ namespace Lux.UI.Components.Pages
return answ;
}
private void ConfInit()
{
basePath = Config.GetValue<string>("ServerConf:FileSharePath") ?? "unsafe_uploads";
}
private void DoClose()
{
EditRecord = null;
@@ -275,6 +393,15 @@ namespace Lux.UI.Components.Pages
await Task.Delay(50);
}
/// <summary>
/// Rilettura info di base
/// </summary>
/// <returns></returns>
private async Task ReloadBaseData()
{
AllConfEnvir = await DLService.ConfEnvirParamGetAllAsync();
}
/// <summary>
/// Legge i dati dei record completi
/// </summary>
+3 -6
View File
@@ -1,17 +1,12 @@
using EgwCoreLib.Lux.Core;
using EgwCoreLib.Lux.Core.Generic;
using EgwCoreLib.Lux.Core.RestPayload;
using EgwCoreLib.Lux.Data;
using EgwCoreLib.Lux.Data.DbModel.Config;
using EgwCoreLib.Lux.Data.DbModel.Sales;
using EgwCoreLib.Lux.Data.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using Newtonsoft.Json;
using NLog;
using NLog.LayoutRenderers;
using System.Globalization;
using static EgwCoreLib.Lux.Core.Enums;
namespace Lux.UI.Components.Pages
{
@@ -233,7 +228,7 @@ namespace Lux.UI.Components.Pages
case EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.CABINET:
// rileggo da file... 2check, spostare?!?
string folderPath = $"SO-{currRec.OfferID:X8}";
string rawData = LoadFileContent(folderPath, rigaOrd.FileResource);
string rawData = FileUtils.LoadFileContent(Path.Combine(basePath, folderPath), rigaOrd.FileResource);
dictArgs.Add(serKey, rawData);
dictArgs.Add("FileName", rigaOrd.FileName);
needCalc = rawData.Length > 2;
@@ -433,6 +428,7 @@ namespace Lux.UI.Components.Pages
await Task.Delay(50);
}
#if false
/// <summary>
/// Restituisce il contenuto del file salvato
/// </summary>
@@ -460,6 +456,7 @@ namespace Lux.UI.Components.Pages
}
return answ;
}
#endif
/// <summary>
/// Modalità gestione code calcolo + display history
+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.2512.0917</Version>
<Version>0.9.2512.0918</Version>
</PropertyGroup>
<ItemGroup>
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>LUX - Web Windows MES</i>
<h4>Versione: 0.9.2512.0917</h4>
<h4>Versione: 0.9.2512.0918</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
0.9.2512.0917
0.9.2512.0918
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>0.9.2512.0917</version>
<version>0.9.2512.0918</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>