diff --git a/EgwCoreLib.Lux.Core/CloneExtensions.cs b/EgwCoreLib.Lux.Core/CloneExtensions.cs new file mode 100644 index 00000000..80dd108a --- /dev/null +++ b/EgwCoreLib.Lux.Core/CloneExtensions.cs @@ -0,0 +1,39 @@ + + +using Newtonsoft.Json; + +namespace EgwCoreLib.Lux.Core +{ + public static class CloneExtensions + { + #region Public Methods + + /// + /// Clone profondo tramite serializzazione/deserializzazione di obj generici + /// + /// + /// + /// + public static T DeepClone(this T obj) + { + // Configurazione serializzatore JSON per risolvere errore di loop circolare + var JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + var json = JsonConvert.SerializeObject(obj, JSSettings); + return JsonConvert.DeserializeObject(json)!; + } + + /// + /// Comparatore statico tra entità + /// + /// + /// + /// + /// + public static bool IsChanged(T original, T edited) => !EqualityComparer.Default.Equals(original, edited); + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Core/Enums.cs b/EgwCoreLib.Lux.Core/Enums.cs index ca95df68..5887e6a4 100644 --- a/EgwCoreLib.Lux.Core/Enums.cs +++ b/EgwCoreLib.Lux.Core/Enums.cs @@ -4,6 +4,19 @@ { #region Public Enums + /// + /// Stato compilazione offerta + /// + public enum CompileStep + { + Draft = 0, + Header = 1, + General, + Rows, + Delivery, + FinalCheck + } + public enum DisplayMode { Standard, @@ -44,6 +57,27 @@ JobCycle } + /// + /// Tipologia immagine + /// + public enum ImageType + { + /// + /// Non definita (da calcolare...) + /// + ND = 0, + + /// + /// Calcolata (es JWD, BTL) + /// + Calculated, + + /// + /// Fissa (tipicamente prodotto da rivendita/servizio) + /// + Fixed + } + /// /// Tipologia item (classe/natura articolo) /// @@ -77,25 +111,6 @@ BomAlt } - /// - /// Tipologia immagine - /// - public enum ImageType - { - /// - /// Non definita (da calcolare...) - /// - ND = 0, - /// - /// Calcolata (es JWD, BTL) - /// - Calculated, - /// - /// Fissa (tipicamente prodotto da rivendita/servizio) - /// - Fixed - } - /// /// Tipologia item per Source (modalità costruzione) /// diff --git a/EgwCoreLib.Lux.Core/Generic/EditStepDto.cs b/EgwCoreLib.Lux.Core/Generic/EditStepDto.cs new file mode 100644 index 00000000..6e3167c3 --- /dev/null +++ b/EgwCoreLib.Lux.Core/Generic/EditStepDto.cs @@ -0,0 +1,8 @@ +namespace EgwCoreLib.Lux.Core.Generic +{ + public class EditStepDto + { + public Enums.CompileStep SrcStep { get; set; } + public bool Changed { get; set; } = false; + } +} diff --git a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs index 22b5ceca..98639826 100644 --- a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs @@ -184,7 +184,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetTemplate.Local.FirstOrDefault(x => x.TemplateID == entity.TemplateID); + var trackedEntity = await dbCtx.DbSetTemplate.FirstOrDefaultAsync(x => x.TemplateID == entity.TemplateID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs index 86793c04..a4fe139c 100644 --- a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs @@ -157,7 +157,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetTemplateRow.Local.FirstOrDefault(x => x.TemplateID == entity.TemplateID); + var trackedEntity = await dbCtx.DbSetTemplateRow.FirstOrDefaultAsync(x => x.TemplateID == entity.TemplateID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Config/ConfGlassRepository.cs b/EgwCoreLib.Lux.Data/Repository/Config/ConfGlassRepository.cs index 6a4489aa..8b998ec6 100644 --- a/EgwCoreLib.Lux.Data/Repository/Config/ConfGlassRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Config/ConfGlassRepository.cs @@ -46,7 +46,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Config public async Task UpdateAsync(GlassModel entity) { await using var dbCtx = await CreateContextAsync(); - var trackedEntity = dbCtx.DbSetConfGlass.Local.FirstOrDefault(x => x.GlassID == entity.GlassID); + var trackedEntity = await dbCtx.DbSetConfGlass.FirstOrDefaultAsync(x => x.GlassID == entity.GlassID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Config/ConfProfileRepository.cs b/EgwCoreLib.Lux.Data/Repository/Config/ConfProfileRepository.cs index 57938b9f..8ca19a82 100644 --- a/EgwCoreLib.Lux.Data/Repository/Config/ConfProfileRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Config/ConfProfileRepository.cs @@ -46,21 +46,19 @@ namespace EgwCoreLib.Lux.Data.Repository.Config await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetConfProfile .FirstOrDefaultAsync(x => x.ProfileID == recId); - //.Where(x => x.ProfileID == recId) } public async Task GetByUidAsync(string uID) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetConfProfile .FirstOrDefaultAsync(x => x.Code == uID); - //.FirstOrDefaultAsync(); } public async Task UpdateAsync(ProfileModel entity) { await using var dbCtx = await CreateContextAsync(); - var trackedEntity = dbCtx.DbSetConfProfile.Local.FirstOrDefault(x => x.ProfileID == entity.ProfileID); + var trackedEntity = await dbCtx.DbSetConfProfile.FirstOrDefaultAsync(x => x.ProfileID == entity.ProfileID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Config/ConfWoodRepository.cs b/EgwCoreLib.Lux.Data/Repository/Config/ConfWoodRepository.cs index a4c6e14e..1ede1a45 100644 --- a/EgwCoreLib.Lux.Data/Repository/Config/ConfWoodRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Config/ConfWoodRepository.cs @@ -48,7 +48,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Config public async Task UpdateAsync(WoodModel entity) { await using var dbCtx = await CreateContextAsync(); - var trackedEntity = dbCtx.DbSetConfWood.Local.FirstOrDefault(x => x.WoodID == entity.WoodID); + var trackedEntity = await dbCtx.DbSetConfWood.FirstOrDefaultAsync(x => x.WoodID == entity.WoodID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Cost/ResourceRepository.cs b/EgwCoreLib.Lux.Data/Repository/Cost/ResourceRepository.cs index 04a01b6a..6a024f02 100644 --- a/EgwCoreLib.Lux.Data/Repository/Cost/ResourceRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Cost/ResourceRepository.cs @@ -49,7 +49,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Cost { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetResource.Local.FirstOrDefault(x => x.ResourceID == entity.ResourceID); + var trackedEntity = await dbCtx.DbSetResource.FirstOrDefaultAsync(x => x.ResourceID == entity.ResourceID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs b/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs index 0077993a..961cb609 100644 --- a/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs @@ -203,7 +203,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Items { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetItem.Local.FirstOrDefault(x => x.ItemID == entity.ItemID); + var trackedEntity = await dbCtx.DbSetItem.FirstOrDefaultAsync(x => x.ItemID == entity.ItemID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Items/SellingItemRepository.cs b/EgwCoreLib.Lux.Data/Repository/Items/SellingItemRepository.cs index f1ada4a1..12825510 100644 --- a/EgwCoreLib.Lux.Data/Repository/Items/SellingItemRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Items/SellingItemRepository.cs @@ -61,7 +61,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Items { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetSellItem.Local.FirstOrDefault(x => x.SellingItemID == entity.SellingItemID); + var trackedEntity = await dbCtx.DbSetSellItem.FirstOrDefaultAsync(x => x.SellingItemID == entity.SellingItemID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs b/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs index 54339891..4594e370 100644 --- a/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs @@ -52,10 +52,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Job dbCtx.DbSetJobStep.Remove(dbResult); bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -124,10 +124,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Job dbCtx.Entry(currRec).State = EntityState.Modified; bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -140,7 +140,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job public async Task UpdateAsync(JobStepModel entity) { await using var dbCtx = await CreateContextAsync(); - var trackedEntity = dbCtx.DbSetJobStep.Local.FirstOrDefault(x => x.JobStepID == entity.JobStepID); + var trackedEntity = await dbCtx.DbSetJobStep.FirstOrDefaultAsync(x => x.JobStepID == entity.JobStepID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs b/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs index ce4af2b5..989cc405 100644 --- a/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs @@ -52,10 +52,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Job dbCtx.DbSetJobTask.Remove(dbResult); bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -123,10 +123,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Job dbCtx.Entry(currRec).State = EntityState.Modified; bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -163,7 +163,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job return false; var otherRec = await dbCtx.DbSetJobTask - .FirstOrDefaultAsync(x => x.Index == newPos); + .FirstOrDefaultAsync(x => x.JobID == selRec.JobID && x.Index == newPos); if (otherRec == null) return false; @@ -175,10 +175,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Job dbCtx.Entry(currRec).State = EntityState.Modified; bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -191,7 +191,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job public async Task UpdateAsync(JobTaskModel entity) { await using var dbCtx = await CreateContextAsync(); - var trackedEntity = dbCtx.DbSetJobTask.Local.FirstOrDefault(x => x.JobID == entity.JobID); + var trackedEntity = await dbCtx.DbSetJobTask.FirstOrDefaultAsync(x => x.JobID == entity.JobID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs index d42025cb..950cbe68 100644 --- a/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs @@ -220,7 +220,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Production public async Task UpdateAsync(ProductionODLModel entity) { await using var dbCtx = await CreateContextAsync(); - var trackedEntity = dbCtx.DbSetProdODL.Local.FirstOrDefault(x => x.ProdODLID == entity.ProdODLID); + var trackedEntity = await dbCtx.DbSetProdODL.FirstOrDefaultAsync(x => x.ProdODLID == entity.ProdODLID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs index b83a3817..9a61342a 100644 --- a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs @@ -248,7 +248,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetOffer.Local.FirstOrDefault(x => x.OfferID == entity.OfferID); + var trackedEntity = await dbCtx.DbSetOffer.FirstOrDefaultAsync(x => x.OfferID == entity.OfferID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs index 86c71b0f..3a45672a 100644 --- a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs @@ -55,10 +55,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales // 4. Salvo tutto bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -123,10 +123,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales dbCtx.Entry(row).State = EntityState.Modified; bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -140,7 +140,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetOfferRow.Local.FirstOrDefault(x => x.OfferRowID == entity.OfferRowID); + var trackedEntity = await dbCtx.DbSetOfferRow.FirstOrDefaultAsync(x => x.OfferRowID == entity.OfferRowID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs index 66316380..e0948b71 100644 --- a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs @@ -269,7 +269,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetOrder.Local.FirstOrDefault(x => x.OrderID == entity.OrderID); + var trackedEntity = await dbCtx.DbSetOrder.FirstOrDefaultAsync(x => x.OrderID == entity.OrderID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs index d4ea7623..7e130ca3 100644 --- a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs @@ -161,7 +161,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetOrderRow.Local.FirstOrDefault(x => x.OrderRowID == entity.OrderRowID); + var trackedEntity = await dbCtx.DbSetOrderRow.FirstOrDefaultAsync(x => x.OrderRowID == entity.OrderRowID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Utils/GenClassRepository.cs b/EgwCoreLib.Lux.Data/Repository/Utils/GenClassRepository.cs index 48ae39c7..45ebe840 100644 --- a/EgwCoreLib.Lux.Data/Repository/Utils/GenClassRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Utils/GenClassRepository.cs @@ -28,9 +28,9 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils await using var dbCtx = await CreateContextAsync(); dbCtx.DbSetGenClass.Remove(entity); - + bool done = await dbCtx.SaveChangesAsync() > 0; - + return done; } @@ -61,7 +61,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetGenClass.Local.FirstOrDefault(x => x.ClassCod == entity.ClassCod); + var trackedEntity = await dbCtx.DbSetGenClass.FirstOrDefaultAsync(x => x.ClassCod == entity.ClassCod); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs b/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs index a48bf5b7..86ea0dbe 100644 --- a/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs @@ -56,10 +56,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils // 4. Salvo tutto bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -129,10 +129,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils // 6. Salvo bool done = await dbCtx.SaveChangesAsync() > 0; - + if (done) tx.Commit(); - + return done; } catch @@ -146,7 +146,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context - var trackedEntity = dbCtx.DbSetGenVal.Local.FirstOrDefault(x => x.GenValID == entity.GenValID); + var trackedEntity = dbCtx.DbSetGenVal.FirstOrDefaultAsync(x => x.GenValID == entity.GenValID); if (trackedEntity != null) { diff --git a/EgwCoreLib.Lux.Data/Services/IImageCacheService.cs b/EgwCoreLib.Lux.Data/Services/IImageCacheService.cs new file mode 100644 index 00000000..5445fd85 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/IImageCacheService.cs @@ -0,0 +1,250 @@ +using EgwMultiEngineManager.Data; +using StackExchange.Redis; + +namespace EgwCoreLib.Lux.Data.Services +{ + /// + /// Interfaccia per ImageCacheService - caching e publishing immagini via Redis + /// + public interface IImageCacheService + { + #region Public Methods + + /// + /// Effettua una generica chiamata ApiRest GET + /// + /// URL Api di base + /// Richiesta completa + /// Risposta RestSharp + Task CallRestGet(string ApiUrl, string ApiRequest); + + /// + /// Effettua una generica chiamata ApiRest POST + /// + /// URL Api di base + /// Richiesta completa + /// Corpo Json trasmesso con richiesta + /// Risposta RestSharp + Task CallRestPost(string ApiUrl, string ApiRequest, object rawBody); + + /// + /// Elimina da cache Redis SVG per il record richiesto + /// + /// UID immagine + /// Environment + /// True se eliminato con successo + bool DeleteSvg(string imgId, Constants.EXECENVIRONMENTS env); + + /// + /// Elimina da cache Redis SVG per il record richiesto (async) + /// + /// UID immagine + /// Environment + /// True se eliminato con successo + Task DeleteSvgAsync(string imgId, Constants.EXECENVIRONMENTS env); + + /// + /// Esegue flush memoria Redis dato pattern + /// + /// Pattern di cancellazione + /// True se eseguito con successo + Task ExecFlushRedisPatternAsync(RedisValue pat2Flush); + + /// + /// Genera URL immagine dato + /// + /// Base url IMG server + /// Live = in fase di calcolo (cache REDIS) + /// UID elemento/immagine + /// Environment item (opzionale) + /// URL immagine completa + string ImageUrl(string baseUrl, bool isLive, string imgUID, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW); + + /// + /// Rilettura risposta da debug in formato string + /// + /// UID record + /// Environment + /// Contenuto da debug + Task LoadDebug(string uID, Constants.EXECENVIRONMENTS env); + + /// + /// Recupera immagine PNG x id item richiesto + /// + /// UID item + /// Environment item (opzionale) + /// Contenuto PNG come stringa base64 + string LoadPng(string imgUid, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW); + + /// + /// Recupera immagine PNG x id item richiesto (async) + /// + /// UID item + /// Environment item (opzionale) + /// Contenuto PNG come stringa base64 + Task LoadPngAsync(string imgUid, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW); + + /// + /// Recupera immagine SVG x id item richiesto + /// + /// UID item + /// Environment item (opzionale) + /// Contenuto SVG come stringa XML + string LoadSvg(string imgUid, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW); + + /// + /// Recupera immagine SVG x id item richiesto (async) + /// + /// UID item + /// Environment item (opzionale) + /// Contenuto SVG come stringa XML + Task LoadSvgAsync(string imgId, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW); + + /// + /// Salva e invia su channel richiesto un update x UID + /// È atteso un refresh per chi sottoscrive il canale + /// + /// UID record + /// Environment + /// True se pubblicato con successo + Task PublishUpdateAsync(string uid, Constants.EXECENVIRONMENTS env); + + /// + /// Calcola URL immagine per richiesta di update SVG + /// + /// Base url IMG server + /// UID elemento/immagine + /// JWD serializzato per calcolo + /// URL per richiesta update + string ReqUpdateSvg(string baseUrl, string imgUID, string serJwd); + + /// + /// Salva e invia su channel BOM redis il doc richiesto + /// + /// UID record + /// Environment + /// Contenuto BOM serializzato + /// True se salvato e pubblicato con successo + Task SaveBomAsync(string uid, Constants.EXECENVIRONMENTS env, string bomContent); + + /// + /// Salvataggio risposta x debug in formato RAW + /// + /// UID record + /// Environment + /// Dati raw + /// True se salvato con successo + Task SaveDebug(string uID, Constants.EXECENVIRONMENTS env, string rawData); + + /// + /// Salva e invia su channel dedicato HML l'elenco degli HardwareModel (conf preferiti) gestiti + /// + /// UID record + /// Environment + /// Dati raw + /// True se salvato e pubblicato con successo + Task SaveHmlAsync(string uid, Constants.EXECENVIRONMENTS env, string rawData); + + /// + /// Salva e invia su channel l'XML delle HW options per il doc richiesto + /// + /// UID record + /// Environment + /// Contenuto XML + /// True se salvato e pubblicato con successo + Task SaveHwOptAsync(string uid, Constants.EXECENVIRONMENTS env, string xmlContent); + + /// + /// Salva immagine PNG su Redis e pubblica notifica sul channel + /// + /// UID immagine + /// Environment + /// Contenuto PNG come stringa base64 + /// True se salvato e pubblicato con successo + bool SavePng(string imgId, Constants.EXECENVIRONMENTS env, string pngContent); + + /// + /// Salva immagine PNG su Redis e pubblica notifica sul channel (async) + /// + /// UID immagine + /// Environment + /// Contenuto PNG come stringa base64 + /// True se salvato e pubblicato con successo + Task SavePngAsync(string imgId, Constants.EXECENVIRONMENTS env, string pngContent); + + /// + /// Salva e invia su channel risultato balance per POR (UID.GroupId.Type) richiesto + /// + /// UID record + /// Environment + /// Contenuto stima serializzato + /// True se salvato e pubblicato con successo + Task SaveProdBalanceAsync(string uid, Constants.EXECENVIRONMENTS env, string estimContent); + + /// + /// Salva e invia su channel risultato stima per POR (UID.GroupId) richiesto + /// + /// UID record + /// Environment + /// Contenuto stima serializzato + /// True se salvato e pubblicato con successo + Task SaveProdEstimateAsync(string uid, Constants.EXECENVIRONMENTS env, string estimContent); + + /// + /// Salva e invia su channel areaProfElem ricevuta + /// + /// UID record + /// Environment + /// Contenuto areaProfElem serializzato + /// True se salvato e pubblicato con successo + Task SaveProfileElemAsync(string uID, Constants.EXECENVIRONMENTS env, string areaProfElem); + + /// + /// Salva e invia su channel profile list gestiti + /// + /// UID record + /// Environment + /// Dati raw + /// True se salvato e pubblicato con successo + Task SaveProfileListAsync(string uid, Constants.EXECENVIRONMENTS env, string rawData); + + /// + /// Salva e invia su channel info Threshold e Data x profili gestiti + /// + /// UID record + /// Environment + /// Info Threshold + /// Info generiche + /// True se salvato e pubblicato con successo + Task SaveProfileThreshAsync(string uid, Constants.EXECENVIRONMENTS env, string rawDataThresh, string rawProfData); + + /// + /// Salva e invia su channel shape per item (UID.GroupId) richiesto + /// + /// UID record + /// Environment + /// Contenuto shape serializzato + /// True se salvato e pubblicato con successo + Task SaveShapeAsync(string uid, Constants.EXECENVIRONMENTS env, string shapeContent); + + /// + /// Salva immagine SVG su Redis e pubblica notifica sul channel + /// + /// UID immagine + /// Environment + /// Contenuto SVG come stringa XML + /// True se salvato e pubblicato con successo + bool SaveSvg(string imgId, Constants.EXECENVIRONMENTS env, string svgContent); + + /// + /// Salva immagine SVG su Redis e pubblica notifica sul channel (async) + /// + /// UID immagine + /// Environment + /// Contenuto SVG come stringa XML + /// True se salvato e pubblicato con successo + Task SaveSvgAsync(string imgId, Constants.EXECENVIRONMENTS env, string svgContent); + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs b/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs index 8e228255..a6f0b435 100644 --- a/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs +++ b/EgwCoreLib.Lux.Data/Services/ImageCacheService.cs @@ -7,11 +7,14 @@ using StackExchange.Redis; namespace EgwCoreLib.Lux.Data.Services { - public class ImageCacheService + public class ImageCacheService : IImageCacheService { #region Public Constructors - public ImageCacheService(IConfiguration config, IRedisService redisService, IConnectionMultiplexer redisConn) + public ImageCacheService( + IConfiguration config, + IRedisService redisService, + IConnectionMultiplexer redisConn) { _config = config; _redisService = redisService; @@ -87,6 +90,34 @@ namespace EgwCoreLib.Lux.Data.Services return response; } + /// + /// Elimina da cache Redis SVG per il doc richiesto + /// + /// + /// + /// + public bool DeleteSvg(string imgId, Constants.EXECENVIRONMENTS env) + { + // salvo img in cache + string currKey = $"{redisBaseKey}:{env}:Img:Svg:{imgId.Replace("/", ":")}"; + var done = _redisService.Delete(currKey); + return done; + } + + /// + /// Elimina da cache Redis SVG per il doc richiesto Async + /// + /// + /// + /// + public async Task DeleteSvgAsync(string imgId, Constants.EXECENVIRONMENTS env) + { + // salvo img in cache + string currKey = $"{redisBaseKey}:{env}:Img:Svg:{imgId.Replace("/", ":")}"; + var done = await _redisService.DeleteAsync(currKey); + return done; + } + /// /// Esegue flush memoria redis dato pat2Flush /// @@ -160,7 +191,7 @@ namespace EgwCoreLib.Lux.Data.Services /// UID elemento/immagine /// Environment item /// - public string ImageUrl(string baseUrl, bool isLive, string imgUID, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW) + public string ImageUrl(string baseUrl, bool isLive, string imgUID, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW) { string tag = isLive ? liveTag : cacheTag; string fType = "undef"; @@ -215,7 +246,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// UID item /// Environment item - public string LoadPng(string imgUid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW) + public string LoadPng(string imgUid, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW) { // recupero img da cache string currKey = $"{redisBaseKey}:{envir}:Img:Png:{imgUid.Replace("/", ":")}"; @@ -228,7 +259,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// UID item /// Environment item - public async Task LoadPngAsync(string imgUid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW) + public async Task LoadPngAsync(string imgUid, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW) { // recupero img da cache string currKey = $"{redisBaseKey}:{envir}:Img:Png:{imgUid.Replace("/", ":")}"; @@ -241,7 +272,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// UID item /// Environment item - public string LoadSvg(string imgUid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW) + public string LoadSvg(string imgUid, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW) { // recupero img da cache string currKey = $"{redisBaseKey}:{envir}:Img:Svg:{imgUid.Replace("/", ":")}"; @@ -254,7 +285,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// UID item /// Environment item - public async Task LoadSvgAsync(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS envir = EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS.WINDOW) + public async Task LoadSvgAsync(string imgId, Constants.EXECENVIRONMENTS envir = Constants.EXECENVIRONMENTS.WINDOW) { // recupero img da cache string currKey = $"{redisBaseKey}:{envir}:Img:Svg:{imgId.Replace("/", ":")}"; @@ -353,7 +384,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// - public async Task SaveHwOptAsync(string uid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string xmlContent) + public async Task SaveHwOptAsync(string uid, Constants.EXECENVIRONMENTS env, string xmlContent) { // salvo img in cache string currKey = $"{redisBaseKey}:{env}:HwOpt:{uid.Replace("/", ":")}"; @@ -371,7 +402,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// contenuto PNG come string base64 /// - public bool SavePng(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string pngContent) + public bool SavePng(string imgId, Constants.EXECENVIRONMENTS env, string pngContent) { // salvo img in cache string currKey = $"{redisBaseKey}:{env}:Img:Png:{imgId.Replace("/", ":")}"; @@ -388,7 +419,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// contenuto PNG come string base64 - public async Task SavePngAsync(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string pngContent) + public async Task SavePngAsync(string imgId, Constants.EXECENVIRONMENTS env, string pngContent) { // salvo img in cache string currKey = $"{redisBaseKey}:{env}:Img:Png:{imgId.Replace("/", ":")}"; @@ -407,7 +438,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// - public async Task SaveProdBalanceAsync(string uid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string estimContent) + public async Task SaveProdBalanceAsync(string uid, Constants.EXECENVIRONMENTS env, string estimContent) { // salvo in cache string currKey = $"{redisBaseKey}:{env}:Balance:{uid}"; @@ -424,7 +455,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// - public async Task SaveProdEstimateAsync(string uid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string estimContent) + public async Task SaveProdEstimateAsync(string uid, Constants.EXECENVIRONMENTS env, string estimContent) { // salvo in cache string currKey = $"{redisBaseKey}:{env}:Estimation:{uid}"; @@ -493,7 +524,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// - public async Task SaveShapeAsync(string uid, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string shapeContent) + public async Task SaveShapeAsync(string uid, Constants.EXECENVIRONMENTS env, string shapeContent) { // salvo img in cache string currKey = $"{redisBaseKey}:{env}:Shape:{uid}"; @@ -504,41 +535,13 @@ namespace EgwCoreLib.Lux.Data.Services return done; } - /// - /// Elimina da cache Redis SVG per il doc richiesto - /// - /// - /// - /// - public bool DeleteSvg(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env) - { - // salvo img in cache - string currKey = $"{redisBaseKey}:{env}:Img:Svg:{imgId.Replace("/", ":")}"; - var done = _redisService.Delete(currKey); - return done; - } - - /// - /// Elimina da cache Redis SVG per il doc richiesto Async - /// - /// - /// - /// - public async Task DeleteSvgAsync(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env) - { - // salvo img in cache - string currKey = $"{redisBaseKey}:{env}:Img:Svg:{imgId.Replace("/", ":")}"; - var done = await _redisService.DeleteAsync(currKey); - return done; - } - /// /// Salva e invia su channel img redis SVG per il doc richiesto /// /// /// /// - public bool SaveSvg(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string svgContent) + public bool SaveSvg(string imgId, Constants.EXECENVIRONMENTS env, string svgContent) { // salvo img in cache string currKey = $"{redisBaseKey}:{env}:Img:Svg:{imgId.Replace("/", ":")}"; @@ -555,7 +558,7 @@ namespace EgwCoreLib.Lux.Data.Services /// /// /// - public async Task SaveSvgAsync(string imgId, EgwMultiEngineManager.Data.Constants.EXECENVIRONMENTS env, string svgContent) + public async Task SaveSvgAsync(string imgId, Constants.EXECENVIRONMENTS env, string svgContent) { // salvo img in cache string currKey = $"{redisBaseKey}:{env}:Img:Svg:{imgId.Replace("/", ":")}"; @@ -568,44 +571,6 @@ namespace EgwCoreLib.Lux.Data.Services #endregion Public Methods - #region Protected Fields - - /// - /// Oggetto per la connessione a Redis utilizzato per operazioni di lettura/scrittura. - /// - protected IConnectionMultiplexer _redisConn = null!; - - /// - /// Database Redis utilizzato per le operazioni di lettura/scrittura - /// nb: ottenuto tramite _redisConn.GetDatabase() - /// - protected IDatabase _redisDb = null!; - - #endregion Protected Fields - - /// -#if false - /// Effettua una generica chiamata ApiRest - /// - /// URL Api di base - /// Richiesta completa - /// Corpo Json trasmesso con richiesta - /// - public async Task CallRestPost(string ApiUrl, string ApiRequest, string JsonBody) - { - RestResponse response; - // cerco online - using (RestClient client = new RestClient(ApiUrl)) - { - var request = new RestRequest(ApiRequest, Method.Post); - string rawData = JsonConvert.SerializeObject(JsonBody); - request.AddJsonBody(rawData); - response = await client.ExecutePostAsync(request); - } - return response; - } -#endif - #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); @@ -615,23 +580,50 @@ namespace EgwCoreLib.Lux.Data.Services private readonly string apiUrl = ""; private readonly string cacheTag = "svgfile"; + private readonly string calcTag = "svgpreview"; + private readonly string chBom = "lux:bom"; + private readonly string chEstimation = "estimation:curr"; + private readonly string chHwList = "lux:hw:list"; + private readonly string chHwOpt = "lux:hw:opt"; + private readonly string chPng = "lux:png:img"; + private readonly string chProd = "lux:prod"; + private readonly string chProfElem = "lux:prof:elem"; + private readonly string chProfList = "lux:prof:list"; + private readonly string chProfThresh = "lux:prof:thresh"; + private readonly string chShape = "shape:curr"; + private readonly string chSvg = "lux:svg:img"; + private readonly string chUpdate = "lux::update"; + private readonly string imgBasePath = ""; + private readonly string liveTag = "svg"; + private IConfiguration _config; + /// + /// Oggetto per la connessione a Redis utilizzato per operazioni di lettura/scrittura. + /// + private IConnectionMultiplexer _redisConn = null!; + + /// + /// Database Redis utilizzato per le operazioni di lettura/scrittura + /// nb: ottenuto tramite _redisConn.GetDatabase() + /// + private IDatabase _redisDb = null!; + private string imageBaseUrl = ""; private string redisBaseKey = "Lux"; diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index 0d84f86c..07ab3aeb 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 1.1.2603.2309 + 1.1.2603.2317 diff --git a/Lux.UI/Components/Compo/OfferMan.razor b/Lux.UI/Components/Compo/OfferMan.razor index 0a3ce7c0..09d282f9 100644 --- a/Lux.UI/Components/Compo/OfferMan.razor +++ b/Lux.UI/Components/Compo/OfferMan.razor @@ -2,7 +2,7 @@
-
+
@foreach (var item in DealersList) { @@ -24,7 +24,7 @@
-
+
+
+
-
- +
+
-
+
- @*
- -
-
- -
*@ -
+ @if (HasChanged()) + { +
+
+
+ +
+
+ +
+ } +
\ No newline at end of file diff --git a/Lux.UI/Components/Compo/OfferMan.razor.cs b/Lux.UI/Components/Compo/OfferMan.razor.cs index 865115a0..0218ad52 100644 --- a/Lux.UI/Components/Compo/OfferMan.razor.cs +++ b/Lux.UI/Components/Compo/OfferMan.razor.cs @@ -1,3 +1,5 @@ +using EgwCoreLib.Lux.Core; +using EgwCoreLib.Lux.Core.Generic; using EgwCoreLib.Lux.Data.DbModel.Sales; using EgwCoreLib.Lux.Data.Services; using EgwCoreLib.Lux.Data.Services.Sales; @@ -18,6 +20,12 @@ namespace Lux.UI.Components.Compo [Parameter] public OfferModel CurrRecord { get; set; } = null!; + /// + /// Evento che indica variazione rispetto ai dati originali + /// + [Parameter] + public EventCallback EC_Changed { get; set; } + /// /// Callback invocato al chiusura della finestra (con valore true per cancellazione). /// @@ -25,7 +33,7 @@ namespace Lux.UI.Components.Compo public EventCallback EC_Close { get; set; } /// - /// Callback invocato al salvataggio con l'offerta aggiornata. + /// Callback invocato alla richiesta di salvataggio con l'offerta aggiornata. /// [Parameter] public EventCallback EC_Updated { get; set; } @@ -39,10 +47,31 @@ namespace Lux.UI.Components.Compo /// protected override async Task OnInitializedAsync() { + setOriginal(); await ReloadData(); await base.OnInitializedAsync(); } + protected override void OnParametersSet() + { + //base.OnParametersSet(); + setOriginal(); + } + +#if false + protected override Task OnParametersSetAsync() + { + bool isChanged = HasChanged(); + var resData = new EditStepDto() + { + SrcStep = Enums.CompileStep.Header, + Changed = isChanged + }; + + return EC_Changed.InvokeAsync(resData); + } +#endif + #endregion Protected Methods #region Private Fields @@ -53,6 +82,7 @@ namespace Lux.UI.Components.Compo private List CustomersList = new List(); private List DealersList = new List(); + private OfferModel? OrigRecord = null; #endregion Private Fields @@ -85,12 +115,50 @@ namespace Lux.UI.Components.Compo return EC_Updated.InvokeAsync(CurrRecord); } + private bool HasChanged() + { + bool answ = false; + if (OrigRecord != null && CurrRecord != null) + { + if (IsChanged(OrigRecord.CustomerID, CurrRecord.CustomerID)) + return true; + if (IsChanged(OrigRecord.DealerID, CurrRecord.DealerID)) + return true; + if (IsChanged(OrigRecord.OffertState, CurrRecord.OffertState)) + return true; + if (IsChanged(OrigRecord.Inserted, CurrRecord.Inserted)) + return true; + if (IsChanged(OrigRecord.ValidUntil, CurrRecord.ValidUntil)) + return true; + if (IsChanged(OrigRecord.Description, CurrRecord.Description)) + return true; + } + return answ; + } + + /// + /// Verifica variazione tramite helper + /// + /// + /// + /// + /// + private bool IsChanged(T original, T edited) => CloneExtensions.IsChanged(original, edited); + private async Task ReloadData() { CustomersList = await CService.GetAllAsync(); DealersList = await DService.GetAllAsync(); } + private void setOriginal() + { + if (CurrRecord != null && OrigRecord == null) + { + OrigRecord = CurrRecord.DeepClone(); + } + } + #endregion Private Methods } } \ No newline at end of file diff --git a/Lux.UI/Components/Pages/Offers.razor b/Lux.UI/Components/Pages/Offers.razor index 0865f19d..51e28ca0 100644 --- a/Lux.UI/Components/Pages/Offers.razor +++ b/Lux.UI/Components/Pages/Offers.razor @@ -13,28 +13,28 @@
- - + +
- - + +
- - + +
- - + +
- - + +
@@ -50,23 +50,23 @@
- @if (currStep == CompileStep.Header) + @if (currStep == Enums.CompileStep.Header) { - + } - else if (currStep == CompileStep.General) + else if (currStep == Enums.CompileStep.General) { } - else if (currStep == CompileStep.Rows) + else if (currStep == Enums.CompileStep.Rows) { } - else if (currStep == CompileStep.Delivery) + else if (currStep == Enums.CompileStep.Delivery) { } - else if (currStep == CompileStep.FinalCheck) + else if (currStep == Enums.CompileStep.FinalCheck) { } diff --git a/Lux.UI/Components/Pages/Offers.razor.cs b/Lux.UI/Components/Pages/Offers.razor.cs index 868632d2..38754b8a 100644 --- a/Lux.UI/Components/Pages/Offers.razor.cs +++ b/Lux.UI/Components/Pages/Offers.razor.cs @@ -15,23 +15,6 @@ namespace Lux.UI.Components.Pages { public partial class Offers { - #region Protected Enums - - /// - /// Stato compilazione offerta - /// - protected enum CompileStep - { - Draft = 0, - Header = 1, - General, - Rows, - Delivery, - FinalCheck - } - - #endregion Protected Enums - #region Protected Properties /// @@ -96,6 +79,7 @@ namespace Lux.UI.Components.Pages private List ListRecords = new List(); + private List ListtChanges = new(); private int numRecord = 10; /// @@ -345,6 +329,27 @@ namespace Lux.UI.Components.Pages UpdateTable(); } + private void SetDirty(EditStepDto updData) + { +#if false + // semodificato imposto colore variato x header + if (updData.Changed) + { + if (!ListtChanges.Contains(updData.SrcStep)) + { + ListtChanges.Add(updData.SrcStep); + } + } + else + { + if (ListtChanges.Contains(updData.SrcStep)) + { + ListtChanges.Remove(updData.SrcStep); + } + } +#endif + } + /// /// Imposta periodo da filtro /// diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index 5a792384..88531093 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 1.1.2603.2310 + 1.1.2603.2317 diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index b3df74fb..e20dcab3 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES -

Versione: 1.1.2603.2310

+

Versione: 1.1.2603.2317


Note di rilascio:
  • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index 6514f5bf..ecd866d3 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -1.1.2603.2310 +1.1.2603.2317 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index ebd53735..9ccb15fb 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 1.1.2603.2310 + 1.1.2603.2317 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false