From 9d9a6b484b5befc0d78bfe485100c95e343112a5 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 30 Jun 2023 16:48:12 +0200 Subject: [PATCH] Aggiunta gestione VAT + conf prod/test --- SHERPA.AD/Components/CustomerManager.razor | 10 +- SHERPA.AD/Components/CustomerManager.razor.cs | 42 +-- SHERPA.AD/Components/VatDetail.razor | 47 +++ SHERPA.AD/Components/VatDetail.razor.cs | 54 +++ SHERPA.AD/Components/VatManager.razor | 65 +++- SHERPA.AD/Components/VatManager.razor.cs | 144 +++++++- SHERPA.AD/Data/SADDataService.cs | 90 ++++- SHERPA.AD/Data/SelectVat.cs | 68 ++++ SHERPA.AD/Pages/Customers.razor | 6 +- SHERPA.AD/Pages/Customers.razor.cs | 16 +- SHERPA.AD/Pages/SyncFIC.razor | 2 +- SHERPA.AD/Pages/SyncFIC.razor.cs | 34 +- SHERPA.AD/Pages/VAT.razor | 43 ++- SHERPA.AD/Pages/VAT.razor.cs | 150 ++++++++ SHERPA.AD/Program.cs | 7 - SHERPA.AD/SHERPA.AD.csproj | 7 +- SHERPA.AD/appsettings.Production.json | 4 + SHERPA.AD/appsettings.json | 2 + SHERPA.BBM.CORE/SHERPA.BBM.CORE.csproj | 6 +- SHERPA.BBM.CORE/SortCallBack.cs | 2 +- SHERPA.BBM.UI/Components/Sorter.razor | 3 +- SHERPA.BBM.UI/Data/BBM_EFService.cs | 343 ++++++++++++++++-- SHERPA.BBM.UI/Pages/Index.razor | 38 +- SHERPA.BBM.UI/Pages/Index.razor.cs | 17 +- SHERPA.BBM.UI/Program.cs | 151 +++++--- SHERPA.BBM.UI/SHERPA.BBM.UI.csproj | 16 +- SHERPA.BBM.UI/Startup.cs | 101 ------ SHERPA.BBM.UI/appsettings.Production.json | 7 +- SHERPA.BBM.UI/appsettings.json | 16 + SHERPA.Data/Controllers/SInManController.cs | 90 ++++- SHERPA.Data/SHERPA.Data.csproj | 2 +- SHERPA/SHERPA.csproj.user | 2 +- 32 files changed, 1249 insertions(+), 336 deletions(-) create mode 100644 SHERPA.AD/Components/VatDetail.razor create mode 100644 SHERPA.AD/Components/VatDetail.razor.cs create mode 100644 SHERPA.AD/Data/SelectVat.cs create mode 100644 SHERPA.AD/Pages/VAT.razor.cs delete mode 100644 SHERPA.BBM.UI/Startup.cs diff --git a/SHERPA.AD/Components/CustomerManager.razor b/SHERPA.AD/Components/CustomerManager.razor index 95c39ae..6d9c26f 100644 --- a/SHERPA.AD/Components/CustomerManager.razor +++ b/SHERPA.AD/Components/CustomerManager.razor @@ -20,7 +20,7 @@ else @if (CurrFilter.EditEnab) { - @@ -28,7 +28,7 @@ else @if (CurrFilter.CloudEnab) { - @@ -43,7 +43,7 @@ else Cloud ID @if (CurrFilter.EditEnab) { - + } } @@ -51,7 +51,7 @@ else @foreach (var item in ListRecords) { - + @if (CurrFilter.EditEnab) { @@ -64,7 +64,7 @@ else @if (string.IsNullOrEmpty(item.IdExt) && hasToken) { - + } else { diff --git a/SHERPA.AD/Components/CustomerManager.razor.cs b/SHERPA.AD/Components/CustomerManager.razor.cs index d2204fc..5b49639 100644 --- a/SHERPA.AD/Components/CustomerManager.razor.cs +++ b/SHERPA.AD/Components/CustomerManager.razor.cs @@ -10,15 +10,6 @@ namespace SHERPA.AD.Components { #region Public Properties - [Parameter] - public EventCallback CliCloned { get; set; } - - [Parameter] - public EventCallback CliSelected { get; set; } - - [Parameter] - public EventCallback CliUpdated { get; set; } - [Parameter] public SelectCli CurrFilter { get; set; } = new SelectCli(); @@ -34,6 +25,15 @@ namespace SHERPA.AD.Components } } + [Parameter] + public EventCallback RecCloned { get; set; } + + [Parameter] + public EventCallback RecSelected { get; set; } + + [Parameter] + public EventCallback RecUpdated { get; set; } + [Parameter] public EventCallback UpdateCount { get; set; } @@ -113,7 +113,7 @@ namespace SHERPA.AD.Components #region Private Methods - private string checkSel(CustomerModel curItem) + private string CheckSel(CustomerModel curItem) { string answ = ""; if (SelRecord != null) @@ -136,7 +136,7 @@ namespace SHERPA.AD.Components await SDService.CustomerClona(currItem); SelRecord = null; - await CliCloned.InvokeAsync(currItem); + await RecCloned.InvokeAsync(currItem); } /// @@ -153,7 +153,7 @@ namespace SHERPA.AD.Components await SDService.CustomerDelete(currItem); SelRecord = null; await ReloadData(); - await CliUpdated.InvokeAsync(currItem); + await RecUpdated.InvokeAsync(currItem); } /// @@ -165,7 +165,7 @@ namespace SHERPA.AD.Components { SelRecord = currItem; await Task.Delay(1); - await CliSelected.InvokeAsync(currItem); + await RecSelected.InvokeAsync(currItem); } /// @@ -221,17 +221,17 @@ namespace SHERPA.AD.Components await Task.Delay(1); } - private async Task resetSel() + private async Task ResetSel() { SelRecord = null; - await CliSelected.InvokeAsync(null); + await RecSelected.InvokeAsync(null); } /// /// Sincronizzazione di tutti i record che la richiedono /// /// - private async Task syncAll() + private async Task SyncAll() { IsSynching = true; // prendo elenco dei clienti NON in sync e processo 1:1 @@ -240,7 +240,7 @@ namespace SHERPA.AD.Components { foreach (var item in data2sync) { - await syncCurrent(item); + await SyncCurrent(item); } } IsSynching = false; @@ -251,7 +251,7 @@ namespace SHERPA.AD.Components /// /// /// - private async Task syncCurrent(CustomerModel currItem) + private async Task SyncCurrent(CustomerModel currItem) { modalMessage = ""; modalCss = "alert alert-primary"; @@ -273,7 +273,7 @@ namespace SHERPA.AD.Components // se ho trovato il record --> aggiorno sul DB if (cloudRec != null) { - await updateDbRecord(currItem, cloudRec); + await UpdateDbRecord(currItem, cloudRec); } else { @@ -295,7 +295,7 @@ namespace SHERPA.AD.Components // se ho trovato il record --> aggiorno sul DB if (newCloudRec != null) { - await updateDbRecord(currItem, newCloudRec); + await UpdateDbRecord(currItem, newCloudRec); } } } @@ -314,7 +314,7 @@ namespace SHERPA.AD.Components /// /// /// - private async Task updateDbRecord(CustomerModel currItem, ModelClient cloudRec) + private async Task UpdateDbRecord(CustomerModel currItem, ModelClient cloudRec) { bool fatto = false; currItem.IdExt = $"{cloudRec.Id}"; diff --git a/SHERPA.AD/Components/VatDetail.razor b/SHERPA.AD/Components/VatDetail.razor new file mode 100644 index 0000000..db4daa1 --- /dev/null +++ b/SHERPA.AD/Components/VatDetail.razor @@ -0,0 +1,47 @@ +@if (CurrRecord == null) +{ + +} +else +{ +
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+
Salva
+
+
+
Annulla
+
+
+
+
+} \ No newline at end of file diff --git a/SHERPA.AD/Components/VatDetail.razor.cs b/SHERPA.AD/Components/VatDetail.razor.cs new file mode 100644 index 0000000..44d23d3 --- /dev/null +++ b/SHERPA.AD/Components/VatDetail.razor.cs @@ -0,0 +1,54 @@ +using Microsoft.AspNetCore.Components; +using SHERPA.AD.Data; +using SHERPA.Data.DbModels; + +namespace SHERPA.AD.Components +{ + public partial class VatDetail + { + #region Public Properties + + [Parameter] + public VatModel? CurrRecord { get; set; } = null; + + [Parameter] + public EventCallback ReqCancel { get; set; } + + [Parameter] + public EventCallback ReqUpdate { get; set; } + + #endregion Public Properties + + #region Protected Properties + + protected List ListSelGruppi { get; set; } = new List(); + + [Inject] + protected SADDataService SDService { get; set; } = null!; + + #endregion Protected Properties + + #region Protected Methods + + protected override async Task OnInitializedAsync() + { + ListSelGruppi = await SDService.VSelGruppiGetAll(); + } + + #endregion Protected Methods + + #region Private Methods + + private async Task doCancel() + { + await ReqCancel.InvokeAsync(true); + } + + private async Task doSave() + { + await ReqUpdate.InvokeAsync(CurrRecord); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/SHERPA.AD/Components/VatManager.razor b/SHERPA.AD/Components/VatManager.razor index e74b554..1a07072 100644 --- a/SHERPA.AD/Components/VatManager.razor +++ b/SHERPA.AD/Components/VatManager.razor @@ -18,35 +18,60 @@ else - + @if (EditEnab) + { + + + } + else + { + + } Iva Descrizione Attivo - Split Payment - Cloud ID + Split Pay + @if (SelRecord == null) + { + Cloud ID + @if (EditEnab) + { + + } + } @foreach (var item in ListRecords) { - - - @if (item.id_ext < 0 && hasToken) + + + @if (EditEnab) { - + + } else { - + @if (item.id_ext < 0 && hasToken) + { + + } + else + { + + } } @($"{item.Iva:P2}") - +
@item.Descrizione
@@ -55,7 +80,23 @@ else - @item.id_ext + @if (SelRecord == null) + { + @item.id_ext + @if (EditEnab) + { + + @if ((item.id_ext==0) && isDeletable(item.IdxVat)) + { + + } + else + { + + } + + } + } } diff --git a/SHERPA.AD/Components/VatManager.razor.cs b/SHERPA.AD/Components/VatManager.razor.cs index 1ac2a34..d4a0525 100644 --- a/SHERPA.AD/Components/VatManager.razor.cs +++ b/SHERPA.AD/Components/VatManager.razor.cs @@ -1,5 +1,6 @@ using It.FattureInCloud.Sdk.Model; using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; using SHERPA.AD.Data; using SHERPA.Data.DbModels; @@ -12,30 +13,46 @@ namespace SHERPA.AD.Components [Parameter] public int Anno { get; set; } = DateTime.Today.Year; + [Parameter] + public SelectVat CurrFilter { get; set; } = new SelectVat() { CurrPage = 0, NumRecord = 1 }; + [Parameter] public bool EditEnab { get; set; } = false; [Parameter] public bool OnlyNeedSync { get; set; } = false; + [Parameter] + public EventCallback RecCloned { get; set; } + + [Parameter] + public EventCallback RecSelected { get; set; } + + [Parameter] + public EventCallback RecUpdated { get; set; } + [Parameter] public bool SelEnab { get; set; } = false; [Parameter] public string TipoDoc { get; set; } = "*"; + [Parameter] + public EventCallback UpdateCount { get; set; } + #endregion Public Properties #region Protected Properties protected bool IsLoading { get; set; } = false; - protected bool IsSynching { get; set; } = false; + [Inject] + protected IJSRuntime JSRuntime { get; set; } = null!; + + protected List ListDeletable { get; set; } = new List(); protected List ListRecords { get; set; } = new List(); - protected string modalCss { get; set; } = "alert alert-success"; - protected string modalMessage { get; set; } = ""; [Inject] @@ -44,6 +61,8 @@ namespace SHERPA.AD.Components [Inject] protected SADDataService SDService { get; set; } = null!; + protected List SearchRecords { get; set; } = new List(); + protected int totalCount { get; set; } = 0; protected string widthMessage { get; set; } = "width: 60%"; #endregion Protected Properties @@ -68,7 +87,12 @@ namespace SHERPA.AD.Components protected override async Task OnParametersSetAsync() { - await ReloadData(); + if (!CurrFilter.Equals(LastFilter)) + { + SelRecord = null; + LastFilter = CurrFilter.clone(); + await ReloadData(); + } } #endregion Protected Methods @@ -81,21 +105,125 @@ namespace SHERPA.AD.Components set => MService.hasToken = value; } + private SelectVat LastFilter { get; set; } = new SelectVat() { CurrPage = 0, NumRecord = 0 }; + + private VatModel? SelRecord { get; set; } = null; + #endregion Private Properties #region Private Methods + private string CheckSel(VatModel curItem) + { + string answ = ""; + if (SelRecord != null) + { + answ = curItem.IdxVat == SelRecord.IdxVat ? "table-info" : ""; + } + return answ; + } + + /// + /// Clona il record + /// + /// + /// + private async Task DoCloneRec(VatModel currItem) + { + // chiedo verifica + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler DUPLICARE il record selezionato??")) + return; + + await SDService.VATClona(currItem); + SelRecord = null; + await RecCloned.InvokeAsync(currItem); + } + + /// + /// Elimina record + /// + /// + /// + private async Task DoDelRec(VatModel currItem) + { + // chiedo verifica + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler ELIMINARE il record selezionato??")) + return; + + await SDService.VATDelete(currItem); + SelRecord = null; + await ReloadData(); + await RecUpdated.InvokeAsync(currItem); + } + + /// + /// Seleziona record + /// + /// + /// + private async Task DoEditRec(VatModel currItem) + { + SelRecord = currItem; + await Task.Delay(1); + await RecSelected.InvokeAsync(currItem); + } + + /// + /// Indica che è cancellabile (NON HA fatture relative) + /// + /// + /// + private bool isDeletable(int IdxVat) + { + return ListDeletable.Where(x => x.IdxVat == IdxVat).Count() > 0; + } + private async Task ReloadData() { - var allRec = await SDService.VATToSync(TipoDoc, Anno, false); - if (OnlyNeedSync) + List allRec = new List(); + if (EditEnab) { - ListRecords = allRec.Where(x => x.id_ext < 0).ToList(); + allRec = await SDService.VATGetAll(); } else { - ListRecords = allRec; + allRec = await SDService.VATToSync(TipoDoc, Anno, false); } + if (OnlyNeedSync) + { + SearchRecords = allRec.Where(x => x.id_ext < 0).ToList(); + } + else + { + SearchRecords = allRec; + } + // effettuo ricerca LIKE... + if (!string.IsNullOrEmpty(CurrFilter.SearchVal)) + { + SearchRecords = SearchRecords.Where(x => x.Descrizione.ToLower().Contains(CurrFilter.SearchVal.ToLower())).ToList(); + } + // verifico se SOLO attivi... + if (CurrFilter.Active) + { + SearchRecords = SearchRecords.Where(x => x.Enabled).ToList(); + } + // conto! + totalCount = SearchRecords.Count; + // verifico cancellabili + ListDeletable = await SDService.VATDeletable(); + // paginazione! + ListRecords = SearchRecords + .OrderBy(x => x.Descrizione) + .Skip(CurrFilter.NumRecord * (CurrFilter.CurrPage - 1)) + .Take(CurrFilter.NumRecord) + .ToList(); + await UpdateCount.InvokeAsync(totalCount); + } + + private async Task ResetSel() + { + SelRecord = null; + await RecSelected.InvokeAsync(null); } /// diff --git a/SHERPA.AD/Data/SADDataService.cs b/SHERPA.AD/Data/SADDataService.cs index d31a828..0c02f75 100644 --- a/SHERPA.AD/Data/SADDataService.cs +++ b/SHERPA.AD/Data/SADDataService.cs @@ -18,8 +18,7 @@ namespace SHERPA.AD.Data _configuration = configuration; _emailSender = emailSender; // Conf cache - redisConn = redisConnMult;// ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); - //redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); + redisConn = redisConnMult; redisDb = this.redisConn.GetDatabase(); // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ @@ -282,6 +281,7 @@ namespace SHERPA.AD.Data } return answ; } + /// /// Elimina un item Customer /// @@ -599,6 +599,91 @@ namespace SHERPA.AD.Data return answ; } + /// + /// Clona un item VAT + /// + /// + /// + public async Task VATClona(VatModel updItem) + { + bool answ = false; + try + { + answ = dbController.VATClona(updItem); + // invalido la cache... + await FlushRedisCache(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in VATClona:{Environment.NewLine}{exc}"); + } + return answ; + } + + /// + /// Elenco VAT eliminabili + /// + /// + public async Task> VATDeletable() + { + string source = "DB"; + List? dbResult = new List(); + string currKey = $"{rKeyVatDel}"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + string? rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + var tempResult = JsonConvert.DeserializeObject>(rawData); + if (tempResult == null) + { + dbResult = new List(); + } + else + { + dbResult = tempResult; + } + } + else + { + dbResult = dbController.VATDeletable(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + await redisDb.StringSetAsync(currKey, rawData, FastCache); + } + if (dbResult == null) + { + dbResult = new List(); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"VATDeletable | {source} in: {ts.TotalMilliseconds} ms"); + return dbResult; + } + + /// + /// Elimina un item VAT + /// + /// + /// + public async Task VATDelete(VatModel updItem) + { + bool answ = false; + try + { + answ = dbController.VATDelete(updItem); + // invalido la cache... + await FlushRedisCache(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in VATDelete:{Environment.NewLine}{exc}"); + } + return answ; + } + /// /// Elenco VAT / CIva (tutti) /// @@ -923,6 +1008,7 @@ namespace SHERPA.AD.Data protected const string rKeySyncVat = $"{redisBaseAddr}:Cache:VAT:CloudSync"; protected const string rKeyVat = $"{redisBaseAddr}:Cache:VAT:List"; protected const string rKeyVatAll = $"{redisBaseAddr}:Cache:VAT:ALL"; + protected const string rKeyVatDel = $"{redisBaseAddr}:Cache:VAT:Del"; protected static SInManController dbController = null!; protected Random rnd = new Random(); diff --git a/SHERPA.AD/Data/SelectVat.cs b/SHERPA.AD/Data/SelectVat.cs new file mode 100644 index 0000000..7e2db57 --- /dev/null +++ b/SHERPA.AD/Data/SelectVat.cs @@ -0,0 +1,68 @@ +namespace SHERPA.AD.Data +{ + public class SelectVat + { + #region Public Properties + + public bool Active { get; set; } = false; + public int CurrPage { get; set; } = 1; + public int NumRecord { get; set; } = 10; + public bool OnlySync { get; set; } = false; + public string SearchVal { get; set; } = ""; + public bool ShowFilt { get; set; } = true; + + #endregion Public Properties + + #region Public Methods + + public SelectVat clone() + { + SelectVat clonedData = new SelectVat() + { + Active = this.Active, + CurrPage = this.CurrPage, + NumRecord = this.NumRecord, + OnlySync = this.OnlySync, + SearchVal = this.SearchVal, + ShowFilt = this.ShowFilt + }; + return clonedData; + } + + public override bool Equals(object? obj) + { + if (obj == null) + return false; + + if (!(obj is SelectVat item)) + return false; + + if (Active != item.Active) + return false; + + if (CurrPage != item.CurrPage) + return false; + + if (NumRecord != item.NumRecord) + return false; + + if (OnlySync != item.OnlySync) + return false; + + if (SearchVal != item.SearchVal) + return false; + + if (ShowFilt != item.ShowFilt) + return false; + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/SHERPA.AD/Pages/Customers.razor b/SHERPA.AD/Pages/Customers.razor index 9ce193d..ac51de8 100644 --- a/SHERPA.AD/Pages/Customers.razor +++ b/SHERPA.AD/Pages/Customers.razor @@ -52,7 +52,7 @@
- +
@if (SelRecord != null) { @@ -66,7 +66,3 @@
- - - - diff --git a/SHERPA.AD/Pages/Customers.razor.cs b/SHERPA.AD/Pages/Customers.razor.cs index 05e9002..3981d47 100644 --- a/SHERPA.AD/Pages/Customers.razor.cs +++ b/SHERPA.AD/Pages/Customers.razor.cs @@ -25,12 +25,6 @@ namespace SHERPA.AD.Pages protected List ListSelTipo { get; set; } = new List(); - protected bool showAll - { - get => ActFilter.ShowFilt; - set => ActFilter.ShowFilt = value; - } - protected int numRecord { get => ActFilter.NumRecord; @@ -58,6 +52,12 @@ namespace SHERPA.AD.Pages set => ActFilter.CodTipo = value; } + protected bool showAll + { + get => ActFilter.ShowFilt; + set => ActFilter.ShowFilt = value; + } + protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle(); #endregion Protected Properties @@ -149,14 +149,14 @@ namespace SHERPA.AD.Pages SelTipo = "*"; } - private void SetClonedCli(CustomerModel itemSel) + private void SetClonedRec(CustomerModel itemSel) { // imposto filtro toggle + ricerca... toggleSync.isActive = false; SearchVal = itemSel.RagSoc ?? ""; } - private void SetCurrCli(CustomerModel itemSel) + private void SetCurrRec(CustomerModel itemSel) { SelRecord = itemSel; } diff --git a/SHERPA.AD/Pages/SyncFIC.razor b/SHERPA.AD/Pages/SyncFIC.razor index 2d9f946..21741d9 100644 --- a/SHERPA.AD/Pages/SyncFIC.razor +++ b/SHERPA.AD/Pages/SyncFIC.razor @@ -58,7 +58,7 @@
- +
diff --git a/SHERPA.AD/Pages/SyncFIC.razor.cs b/SHERPA.AD/Pages/SyncFIC.razor.cs index b6130a3..7e5ee3b 100644 --- a/SHERPA.AD/Pages/SyncFIC.razor.cs +++ b/SHERPA.AD/Pages/SyncFIC.razor.cs @@ -1,7 +1,7 @@ -using Microsoft.AspNetCore.Components; -using SHERPA.Data.DbModels; -using SHERPA.AD.Data; using EgwCoreLib.Razor; +using Microsoft.AspNetCore.Components; +using SHERPA.AD.Data; +using SHERPA.Data.DbModels; namespace SHERPA.AD.Pages { @@ -9,8 +9,20 @@ namespace SHERPA.AD.Pages { #region Protected Properties + protected SelectCli CliFilter { get; set; } = new SelectCli(); + protected SelectDocExp DocFilter { get; set; } = new SelectDocExp(); protected List ListSelTipo { get; set; } = new List(); + protected bool needSync + { + get => DocFilter.OnlySync; + set + { + DocFilter.OnlySync = value; + CliFilter.OnlySync = value; + } + } + [Inject] protected SADDataService SDService { get; set; } = null!; @@ -34,18 +46,8 @@ namespace SHERPA.AD.Pages } } - protected bool needSync - { - get => DocFilter.OnlySync; - set - { - DocFilter.OnlySync = value; - CliFilter.OnlySync = value; - } - } - - protected SelectDocExp DocFilter { get; set; } = new SelectDocExp(); - protected SelectCli CliFilter { get; set; } = new SelectCli(); + protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle(); + protected SelectVat VatFilter { get; set; } = new SelectVat() { CurrPage = 0, NumRecord = 1000 }; #endregion Protected Properties @@ -69,8 +71,6 @@ namespace SHERPA.AD.Pages SelTipo = "*"; } - protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle(); - protected void updToggSync(Toggler.SelectGlobalToggle newTogg) { needSync = newTogg.isActive; diff --git a/SHERPA.AD/Pages/VAT.razor b/SHERPA.AD/Pages/VAT.razor index 844b0b7..1ec3652 100644 --- a/SHERPA.AD/Pages/VAT.razor +++ b/SHERPA.AD/Pages/VAT.razor @@ -1,5 +1,42 @@ -

VAT

+@page "/VAT" -@code { +VAT Management -} + +
+
+
+
+ Criteri selezione +
+
+
+ +
+
+
+ + + +
+
+
+
+
+
+
+
+ +
+ @if (SelRecord != null) + { +
+ +
+ } +
+
+ +
diff --git a/SHERPA.AD/Pages/VAT.razor.cs b/SHERPA.AD/Pages/VAT.razor.cs new file mode 100644 index 0000000..0cbcdde --- /dev/null +++ b/SHERPA.AD/Pages/VAT.razor.cs @@ -0,0 +1,150 @@ +using EgwCoreLib.Razor; +using Microsoft.AspNetCore.Components; +using SHERPA.AD.Data; +using SHERPA.Data.DbModels; + +namespace SHERPA.AD.Pages +{ + public partial class VAT + { + #region Protected Fields + + protected bool isLoading = false; + + #endregion Protected Fields + + #region Protected Properties + + protected SelectVat ActFilter { get; set; } = new SelectVat(); + + protected int currPage + { + get => ActFilter.CurrPage; + set => ActFilter.CurrPage = value; + } + + protected List ListSelTipo { get; set; } = new List(); + + protected int numRecord + { + get => ActFilter.NumRecord; + set => ActFilter.NumRecord = value; + } + + [Inject] + protected SADDataService SDService { get; set; } = null!; + + protected string SearchVal + { + get => ActFilter.SearchVal; + set => ActFilter.SearchVal = value; + } + + protected bool showAll + { + get => ActFilter.ShowFilt; + set => ActFilter.ShowFilt = value; + } + + protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle(); + + #endregion Protected Properties + + #region Protected Methods + + protected override async Task OnInitializedAsync() + { + toggleSync.leftString = "Tutti"; + toggleSync.rightString = "Solo Attivi"; + ListSelTipo = await SDService.VSelTipoGetAll(); + } + + protected void SetCount(int newNum) + { + if (totalCount != newNum) + { + totalCount = newNum; + } + } + + protected void SetCurrPage(int newNum) + { + SelRecord = null; + currPage = newNum; + } + + protected void SetNumRec(int newNum) + { + SelRecord = null; + numRecord = newNum; + } + + #endregion Protected Methods + + #region Private Properties + + private string mainCss + { + get => SelRecord == null ? "col-12" : "col-8 pe-0"; + } + + private VatModel? SelRecord { get; set; } = null; + private int totalCount { get; set; } = 0; + + #endregion Private Properties + + #region Private Methods + + /// + /// Processa task cancel edit + /// + private async Task doEditCancel(bool reload) + { + if (reload) + { + isLoading = true; + SelRecord = null; + await Task.Delay(1); + isLoading = false; + } + await Task.Delay(1); + } + + /// + /// Processa task update record + /// + private async Task doEditSave(VatModel itemSel) + { + isLoading = true; + await SDService.VATUpdate(itemSel); + SelRecord = null; + isLoading = false; + await Task.Delay(1); + } + + private void ResetSearch() + { + SearchVal = ""; + } + + private void SetClonedRec(VatModel itemSel) + { + // imposto filtro toggle + ricerca... + SelRecord = itemSel; + SearchVal = itemSel.Descrizione ?? ""; + } + + private void SetCurrRec(VatModel itemSel) + { + SelRecord = itemSel; + } + + private void updToggSync(Toggler.SelectGlobalToggle newTogg) + { + currPage = 1; + ActFilter.Active = newTogg.isActive; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/SHERPA.AD/Program.cs b/SHERPA.AD/Program.cs index 566b819..5d5df20 100644 --- a/SHERPA.AD/Program.cs +++ b/SHERPA.AD/Program.cs @@ -43,13 +43,6 @@ builder.Services.Configure(options => options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"]; }); -//builder.Services.AddStackExchangeRedisCache(options => -//{ -// options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 15, EndPoints = { { "localhost", 6379 } } }; -// options.InstanceName = "SHERPA:ADM:"; -//}); - - // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); diff --git a/SHERPA.AD/SHERPA.AD.csproj b/SHERPA.AD/SHERPA.AD.csproj index 22de369..f99ebb1 100644 --- a/SHERPA.AD/SHERPA.AD.csproj +++ b/SHERPA.AD/SHERPA.AD.csproj @@ -4,7 +4,8 @@ net6.0 enable enable - 1.0.2303.0219 + 1.0.2306.3016 + Egalware 2021+ @@ -29,9 +30,9 @@ - + - + diff --git a/SHERPA.AD/appsettings.Production.json b/SHERPA.AD/appsettings.Production.json index 8990500..a008268 100644 --- a/SHERPA.AD/appsettings.Production.json +++ b/SHERPA.AD/appsettings.Production.json @@ -11,5 +11,9 @@ "Name": "SHERPA Invoice Management", "ShortName": "SHERPA IM", "JumpUrl": "https://office.egalware.com/SHERPA-AD/index" + }, + "ConnectionStrings": { + "Redis": "localhost:6379,DefaultDatabase=4,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + "Sherpa.Fatt": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;" } } diff --git a/SHERPA.AD/appsettings.json b/SHERPA.AD/appsettings.json index 6fb58b6..a2a1290 100644 --- a/SHERPA.AD/appsettings.json +++ b/SHERPA.AD/appsettings.json @@ -8,6 +8,8 @@ "AllowedHosts": "*", "CodApp": "SHERPA", "ConnectionStrings": { + //"Redis": "localhost:6379,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + //"Sherpa.Fatt": "Data Source=SQL2016DEV;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;" "Redis": "localhost:6379,DefaultDatabase=4,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", "Sherpa.Fatt": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;" }, diff --git a/SHERPA.BBM.CORE/SHERPA.BBM.CORE.csproj b/SHERPA.BBM.CORE/SHERPA.BBM.CORE.csproj index c83d4de..eb50f25 100644 --- a/SHERPA.BBM.CORE/SHERPA.BBM.CORE.csproj +++ b/SHERPA.BBM.CORE/SHERPA.BBM.CORE.csproj @@ -6,9 +6,9 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SHERPA.BBM.CORE/SortCallBack.cs b/SHERPA.BBM.CORE/SortCallBack.cs index fb13733..6e80e66 100644 --- a/SHERPA.BBM.CORE/SortCallBack.cs +++ b/SHERPA.BBM.CORE/SortCallBack.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace SHERPA.BBM.CORE { - public class SortCallBack + public class SortCallBack { public bool IsAscending { get; set; } = true; diff --git a/SHERPA.BBM.UI/Components/Sorter.razor b/SHERPA.BBM.UI/Components/Sorter.razor index 32a9a3e..f3bf218 100644 --- a/SHERPA.BBM.UI/Components/Sorter.razor +++ b/SHERPA.BBM.UI/Components/Sorter.razor @@ -38,7 +38,8 @@ { get { - return isCurrent ? "btn-primary" : "btn-outline-secondary"; + return isCurrent ? "text-primary" : "text-secondary opacity-25"; + //return isCurrent ? "btn-primary" : "btn-outline-secondary"; } } diff --git a/SHERPA.BBM.UI/Data/BBM_EFService.cs b/SHERPA.BBM.UI/Data/BBM_EFService.cs index 0182509..102b63e 100644 --- a/SHERPA.BBM.UI/Data/BBM_EFService.cs +++ b/SHERPA.BBM.UI/Data/BBM_EFService.cs @@ -1,38 +1,30 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using Newtonsoft.Json; +using NLog; +using StackExchange.Redis; +using System.Diagnostics; namespace SHERPA.BBM.UI.Data { public class BBM_EFService : IDisposable { - #region Private Fields - - private static IConfiguration _configuration = null!; - private static ILogger _logger; - - #endregion Private Fields - - #region Protected Fields - - protected static string connStringBBM = ""; - protected static string connStringFatt = ""; - - protected static CORE.Controllers.BBMController dbController; - - #endregion Protected Fields - #region Public Constructors - public BBM_EFService(IConfiguration configuration, ILogger logger) + public BBM_EFService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult) { _logger = logger; _configuration = configuration; connStringBBM = _configuration.GetConnectionString("Sherpa.BBM"); connStringFatt = _configuration.GetConnectionString("Sherpa.Fatt"); + // Conf cache + redisConn = redisConnMult; + redisDb = this.redisConn.GetDatabase(); + + // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ + JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + //_logger.LogInformation($"ConnString: {connString}"); if (string.IsNullOrEmpty(connStringBBM) || string.IsNullOrEmpty(connStringFatt)) { @@ -41,12 +33,6 @@ namespace SHERPA.BBM.UI.Data else { dbController = new CORE.Controllers.BBMController(_configuration); -#if false - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"DbController OK"); - sb.AppendLine($"CST: {dbController.CustomersCount()} | CNT: {dbController.CountersCount()} | BSK: {dbController.BasketsCount()} | NGT: {dbController.NegotiationsCount()} | DOC: {dbController.DocsCount()} | ITM: {dbController.ItemsCount()} | RES: {dbController.ResourcesCount()}"); - _logger.LogInformation(sb.ToString()); -#endif } } @@ -385,6 +371,24 @@ namespace SHERPA.BBM.UI.Data return Task.FromResult(dbController.NegotYears()); } + /// + /// Remove for single hash record + /// + /// Chiave redis della Hashlist + /// Chiave nella HashList + /// Esito rimozione + public async Task RedHashRemove(RedisKey currKey, string chiave) + { + bool fatto = false; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + fatto = await redisDb.HashDeleteAsync(currKey, chiave); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"RedHashRemove | {currKey} | in: {ts.TotalMilliseconds} ms"); + return fatto; + } + public void ResourceAdd(CORE.DbModels.ResourcesModel newItem) { try @@ -463,29 +467,164 @@ namespace SHERPA.BBM.UI.Data dbController.rollBackEntity(item); } - public Task SumTotDraft(int anno) + public Task SumTotDraft(int anno) { - return Task.FromResult(dbController.SumTotDraft(anno)); + string source = "DB"; + decimal dbResult = 0; + string currKey = $"{rKeyResoconti}:{anno}:SumTotDraft"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + //string? rawData = await redisDb.StringGetAsync(currKey); + string? rawData = redisDb.StringGet(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + try + { + dbResult = JsonConvert.DeserializeObject(rawData); + } + catch + { } + } + else + { + dbResult = (decimal)dbController.SumTotDraft(anno); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDb.StringSet(currKey, rawData, LongCache); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"SumTotDraft | {source} in: {ts.TotalMilliseconds} ms"); + return Task.FromResult(dbResult); + //return Task.FromResult(dbController.SumTotDraft(anno)); } public Task SumTotImporto(int anno) { - return Task.FromResult(dbController.SumTotImporto(anno)); + string source = "DB"; + decimal dbResult = 0; + string currKey = $"{rKeyResoconti}:{anno}:SumTotImporto"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + //string? rawData = await redisDb.StringGetAsync(currKey); + string? rawData = redisDb.StringGet(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + try + { + dbResult = JsonConvert.DeserializeObject(rawData); + } + catch + { } + } + else + { + dbResult = dbController.SumTotImporto(anno); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDb.StringSet(currKey, rawData, LongCache); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"SumTotImporto | {source} in: {ts.TotalMilliseconds} ms"); + return Task.FromResult(dbResult); + //return Task.FromResult(dbController.SumTotImporto(anno)); } public Task SumTotIncasso(int anno) { - return Task.FromResult(dbController.SumTotIncasso(anno)); + string source = "DB"; + decimal dbResult = 0; + string currKey = $"{rKeyResoconti}:{anno}:SumTotIncasso"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + //string? rawData = await redisDb.StringGetAsync(currKey); + string? rawData = redisDb.StringGet(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + try + { + dbResult = JsonConvert.DeserializeObject(rawData); + } + catch + { } + } + else + { + dbResult = dbController.SumTotIncasso(anno); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDb.StringSet(currKey, rawData, LongCache); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"SumTotIncasso | {source} in: {ts.TotalMilliseconds} ms"); + return Task.FromResult(dbResult); + //return Task.FromResult(dbController.SumTotIncasso(anno)); } - public Task SumTotOrdinato(int anno) + public Task SumTotOrdinato(int anno) { - return Task.FromResult(dbController.SumTotOrdinato(anno)); + string source = "DB"; + decimal dbResult = 0; + string currKey = $"{rKeyResoconti}:{anno}:SumTotOrdinato"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + //string? rawData = await redisDb.StringGetAsync(currKey); + string? rawData = redisDb.StringGet(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + try + { + dbResult = JsonConvert.DeserializeObject(rawData); + } + catch + { } + } + else + { + dbResult = (decimal)dbController.SumTotOrdinato(anno); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDb.StringSet(currKey, rawData, LongCache); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"SumTotOrdinato | {source} in: {ts.TotalMilliseconds} ms"); + return Task.FromResult(dbResult); + //return Task.FromResult(dbController.SumTotOrdinato(anno)); } - public Task SumTotTrattato(int anno) + public Task SumTotTrattato(int anno) { - return Task.FromResult(dbController.SumTotTrattato(anno)); + string source = "DB"; + decimal dbResult = 0; + string currKey = $"{rKeyResoconti}:{anno}:SumTotTrattato"; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + //string? rawData = await redisDb.StringGetAsync(currKey); + string? rawData = redisDb.StringGet(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + try + { + dbResult = JsonConvert.DeserializeObject(rawData); + } + catch + { } + } + else + { + dbResult = (decimal)dbController.SumTotTrattato(anno); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDb.StringSet(currKey, rawData, LongCache); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Debug($"SumTotTrattato | {source} in: {ts.TotalMilliseconds} ms"); + return Task.FromResult(dbResult); + //return Task.FromResult(dbController.SumTotTrattato(anno)); } public void TagDelete(CORE.DbModels.TagModel currRecord) @@ -539,5 +678,135 @@ namespace SHERPA.BBM.UI.Data } #endregion Public Methods + + #region Protected Fields + + protected const string redisBaseAddr = "SHERPA:BBM-UI"; + + protected const string rKeyResoconti = $"{redisBaseAddr}:Cache:Resoconti"; + + protected static string connStringBBM = ""; + + protected static string connStringFatt = ""; + + protected static CORE.Controllers.BBMController dbController = null!; + + protected Random rnd = new Random(); + + #endregion Protected Fields + + #region Protected Methods + + /// + /// Effettua upsert in HasList redis + /// + /// Chiave redis della Hashlist + /// Chiave nella HashList + /// Valore da salvare + /// Num record nella HashList + protected async Task RedHashUpsert(RedisKey currKey, string chiave, string valore) + { + long numReq = 0; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + await redisDb.HashSetAsync(currKey, chiave, valore); + numReq = await redisDb.HashLengthAsync(currKey); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"RedHashUpsert | {currKey} | in: {ts.TotalMilliseconds} ms"); + return numReq; + } + + #endregion Protected Methods + + #region Private Fields + + private static IConfiguration _configuration = null!; + private static ILogger _logger = null!; + private static JsonSerializerSettings? JSSettings; + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + /// + /// Durata cache lunga IN SECONDI + /// + private int cacheTtlLong = 60 * 5; + + /// + /// Durata cache breve IN SECONDI + /// + private int cacheTtlShort = 60 * 1; + + /// + /// Oggetto per connessione a REDIS + /// + private IConnectionMultiplexer redisConn; + + //ISubscriber sub = redis.GetSubscriber(); + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + private IDatabase redisDb = null!; + + #endregion Private Fields + + #region Private Properties + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan FastCache + { + get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan LongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan UltraLongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); + } + + #endregion Private Properties + + #region Private Methods + + /// + /// Esegue flush memoria redis dato pattern + /// + /// + /// + private async Task ExecFlushRedisPattern(RedisValue pattern) + { + bool answ = false; + var listEndpoints = redisConn.GetEndPoints(); + foreach (var endPoint in listEndpoints) + { + //var server = redisConnAdmin.GetServer(listEndpoints[0]); + var server = redisConn.GetServer(endPoint); + if (server != null) + { + var keyList = server.Keys(redisDb.Database, pattern); + foreach (var item in keyList) + { + await redisDb.KeyDeleteAsync(item); + } + answ = true; + } + } + + return answ; + } + + #endregion Private Methods } } \ No newline at end of file diff --git a/SHERPA.BBM.UI/Pages/Index.razor b/SHERPA.BBM.UI/Pages/Index.razor index 5ab311a..6628257 100644 --- a/SHERPA.BBM.UI/Pages/Index.razor +++ b/SHERPA.BBM.UI/Pages/Index.razor @@ -39,41 +39,6 @@
@anno
- @*
-
-
-
Trattative
-
- @(getTrattato(anno).Result.ToString("C2")) -
+ @(getDraft(anno).Result.ToString("C2"))
-
-
-
-
-
-
Ordinato
-
- @(getOrdinato(anno).Result.ToString("C2")) -
-
-
-
-
-
Fatturato
-
- @(getImporto(anno).Result.ToString("C2")) -
-
-
-
-
-
Incassato
-
- @(getIncasso(anno).Result.ToString("C2")) -
-
-
-
*@
@@ -99,6 +64,7 @@
@(getOrdinato(anno).Result.ToString("C2")) +
@((getOrdinato(anno).Result / getTrattato(anno).Result).ToString("P1"))
@@ -112,6 +78,7 @@
@(getImporto(anno).Result.ToString("C2")) +
@((getImporto(anno).Result / getOrdinato(anno).Result).ToString("P1"))
@@ -125,6 +92,7 @@
@(getIncasso(anno).Result.ToString("C2")) +
@((getIncasso(anno).Result / getImporto(anno).Result).ToString("P1"))
diff --git a/SHERPA.BBM.UI/Pages/Index.razor.cs b/SHERPA.BBM.UI/Pages/Index.razor.cs index 84c28f5..71fcc6c 100644 --- a/SHERPA.BBM.UI/Pages/Index.razor.cs +++ b/SHERPA.BBM.UI/Pages/Index.razor.cs @@ -10,9 +10,9 @@ namespace SHERPA.BBM.UI.Pages { #region Protected Methods - protected async Task getDraft(int anno) + protected async Task getDraft(int anno) { - double valore = 0; + decimal valore = 0; try { valore = await BBMService.SumTotDraft(anno); @@ -46,9 +46,9 @@ namespace SHERPA.BBM.UI.Pages return valore; } - protected async Task getOrdinato(int anno) + protected async Task getOrdinato(int anno) { - double valore = 0; + decimal valore = 0; try { valore = await BBMService.SumTotOrdinato(anno); @@ -58,9 +58,9 @@ namespace SHERPA.BBM.UI.Pages return valore; } - protected async Task getTrattato(int anno) + protected async Task getTrattato(int anno) { - double valore = 0; + decimal valore = 0; try { valore = await BBMService.SumTotTrattato(anno); @@ -70,6 +70,7 @@ namespace SHERPA.BBM.UI.Pages return valore; } + protected override async Task OnInitializedAsync() { await Task.Delay(1); @@ -86,10 +87,10 @@ namespace SHERPA.BBM.UI.Pages private int Anno { get; set; } = DateTime.Today.Year; [Inject] - private BBM_EFService BBMService { get; set; } + private BBM_EFService BBMService { get; set; } = null!; [Inject] - private MessageService MessageService { get; set; } + private MessageService MessageService { get; set; } = null!; [Inject] private BBM_SelectData SelectData { get; set; } diff --git a/SHERPA.BBM.UI/Program.cs b/SHERPA.BBM.UI/Program.cs index ac16013..3f9f11a 100644 --- a/SHERPA.BBM.UI/Program.cs +++ b/SHERPA.BBM.UI/Program.cs @@ -1,54 +1,107 @@ -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using NLog.Web; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Authentication.Negotiate; +using Microsoft.AspNetCore.Identity.UI.Services; +using SHERPA.BBM.UI.Data; +using SHERPA.Data; +using StackExchange.Redis; +using Microsoft.AspNetCore.Localization; +using System.Globalization; +using Blazored.LocalStorage; +using Blazored.SessionStorage; +using Microsoft.AspNetCore.Builder; +using ElmahCore.Mvc; -namespace SHERPA.BBM.UI +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) + .AddNegotiate(); + +builder.Services.AddAuthorization(options => { - public class Program - { - #region Public Methods + // By default, all incoming requests will be authorized according to the default policy. + options.FallbackPolicy = options.DefaultPolicy; +}); - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }) - .ConfigureLogging(logging => - { - logging.ClearProviders(); - logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); - }) - .UseNLog(); +// configuration setup +ConfigurationManager configuration = builder.Configuration; - public static void Main(string[] args) - { - // inclusione NLog: - // https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5 - // https://codewithmukesh.com/blog/logging-with-nlog-in-aspnet-core/ - var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger(); - try - { - logger.Info("BBM Application Starting Up"); - CreateHostBuilder(args).Build().Run(); - } - catch (Exception exception) - { - logger.Error(exception, "Stopped BBM program because of exception"); - throw; - } - finally - { - NLog.LogManager.Shutdown(); - } - } +// REDIS setup +string connStringRedis = configuration.GetConnectionString("Redis"); +string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); +// avvio oggetto shared x redis... +var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); - #endregion Public Methods - } -} \ No newline at end of file +// abilitazione x email management con MailKit +builder.Services.AddTransient(); +builder.Services.Configure(options => +{ + options.Host_Address = configuration["ExternalProviders:MailKit:SMTP:Address"]; + options.Host_Port = Convert.ToInt32(configuration["ExternalProviders:MailKit:SMTP:Port"]); + options.Host_Username = configuration["ExternalProviders:MailKit:SMTP:Account"]; + options.Host_Password = configuration["ExternalProviders:MailKit:SMTP:Password"]; + options.Sender_EMail = configuration["ExternalProviders:MailKit:SMTP:SenderEmail"]; + options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"]; +}); + +// Add services to the container. + +// Elmah +builder.Services.AddElmah(); +//string elmaConn = "Data Source=SQL2016DEV;Initial Catalog=Elmah;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=SHERPA.BBM;"; +//services.AddElmah(options => +//{ +// options.ConnectionString = elmaConn; +//}); +builder.Services.AddLocalization(); +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(); +builder.Services.AddSingleton(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddHttpContextAccessor(); +builder.Services.AddSingleton(redisMultiplexer); + +builder.Services.AddBlazoredLocalStorage(); +builder.Services.AddBlazoredSessionStorage(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UsePathBase(configuration["BaseAppPath"]); + +// cultura IT... +var supportedCultures = new[]{ + new CultureInfo("it-IT") + }; +app.UseRequestLocalization(new RequestLocalizationOptions +{ + DefaultRequestCulture = new RequestCulture("it-IT"), + SupportedCultures = supportedCultures, + FallBackToParentCultures = false +}); +CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT"); + +// Registrazione Elmah: +// https://github.com/ElmahCore/ElmahCore +app.UseElmah(); + +app.UseHttpsRedirection(); +app.UseStaticFiles(); +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +app.Run(); diff --git a/SHERPA.BBM.UI/SHERPA.BBM.UI.csproj b/SHERPA.BBM.UI/SHERPA.BBM.UI.csproj index 9a9b2f5..59e6409 100644 --- a/SHERPA.BBM.UI/SHERPA.BBM.UI.csproj +++ b/SHERPA.BBM.UI/SHERPA.BBM.UI.csproj @@ -4,7 +4,10 @@ net6.0 60fcdaab-6c1e-4bec-9d88-f7727ef1c12c wwwroot\favicon.ico - 1.0.2302.2819 + 1.0.2306.3016 + enable + enable + Egalware 2021+ @@ -155,22 +158,29 @@ + + - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/SHERPA.BBM.UI/Startup.cs b/SHERPA.BBM.UI/Startup.cs deleted file mode 100644 index 152ef95..0000000 --- a/SHERPA.BBM.UI/Startup.cs +++ /dev/null @@ -1,101 +0,0 @@ -using ElmahCore.Mvc; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Localization; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using SHERPA.BBM.UI.Data; -using System.Globalization; - -namespace SHERPA.BBM.UI -{ - public class Startup - { - #region Public Constructors - - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - #endregion Public Constructors - - #region Public Properties - - public IConfiguration Configuration { get; } - - #endregion Public Properties - - #region Public Methods - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - // cultura IT... - var supportedCultures = new[]{ - new CultureInfo("it-IT") - }; - app.UseRequestLocalization(new RequestLocalizationOptions - { - DefaultRequestCulture = new RequestCulture("it-IT"), - SupportedCultures = supportedCultures, - FallBackToParentCultures = false - }); - CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT"); - - - app.UsePathBase(Configuration["BaseAppPath"]); - - // Registrazione Elmah: - // https://github.com/ElmahCore/ElmahCore - app.UseElmah(); - - app.UseHttpsRedirection(); - app.UseStaticFiles(); - - app.UseRouting(); - - app.UseEndpoints(endpoints => - { - endpoints.MapBlazorHub(); - endpoints.MapFallbackToPage("/_Host"); - }); - } - - // This method gets called by the runtime. Use this method to add services to the container. - // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 - public void ConfigureServices(IServiceCollection services) - { - - // Elmah - services.AddElmah(); - //string elmaConn = "Data Source=SQL2016DEV;Initial Catalog=Elmah;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=SHERPA.BBM;"; - //services.AddElmah(options => - //{ - // options.ConnectionString = elmaConn; - //}); - - services.AddLocalization(); - - services.AddRazorPages(); - services.AddServerSideBlazor(); - services.AddSingleton(); - services.AddScoped(); - services.AddScoped(); - } - - #endregion Public Methods - } -} \ No newline at end of file diff --git a/SHERPA.BBM.UI/appsettings.Production.json b/SHERPA.BBM.UI/appsettings.Production.json index 3c16911..be0887e 100644 --- a/SHERPA.BBM.UI/appsettings.Production.json +++ b/SHERPA.BBM.UI/appsettings.Production.json @@ -8,5 +8,10 @@ } }, "AllowedHosts": "*", - "BaseAppPath": "/BBM/" + "BaseAppPath": "/BBM/", + "ConnectionStrings": { + "Redis": "localhost:6379,DefaultDatabase=4,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + "Sherpa.BBM": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.BBM;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;", + "Sherpa.Fatt": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;" + } } \ No newline at end of file diff --git a/SHERPA.BBM.UI/appsettings.json b/SHERPA.BBM.UI/appsettings.json index 2f37b81..bdc6f75 100644 --- a/SHERPA.BBM.UI/appsettings.json +++ b/SHERPA.BBM.UI/appsettings.json @@ -9,7 +9,23 @@ "AllowedHosts": "*", "BaseAppPath": "/", "ConnectionStrings": { + //"Redis": "localhost:6379,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + //"Sherpa.BBM": "Data Source=SQL2016DEV;Initial Catalog=SHERPA.BBM;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;", + //"Sherpa.Fatt": "Data Source=SQL2016DEV;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;" + "Redis": "localhost:6379,DefaultDatabase=4,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", "Sherpa.BBM": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.BBM;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;", "Sherpa.Fatt": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;" + }, + "ExternalProviders": { + "MailKit": { + "SMTP": { + "Address": "smtp-mail.outlook.com", + "Port": "587", + "Account": "steamwarebot@outlook.it", + "Password": "siamoInViaNazionale93", + "SenderEmail": "steamwarebot@outlook.it", + "SenderName": "Steamware Email BOT" + } + } } } \ No newline at end of file diff --git a/SHERPA.Data/Controllers/SInManController.cs b/SHERPA.Data/Controllers/SInManController.cs index 1b46bca..efaf480 100644 --- a/SHERPA.Data/Controllers/SInManController.cs +++ b/SHERPA.Data/Controllers/SInManController.cs @@ -100,7 +100,7 @@ namespace SHERPA.Data.Controllers { // elimina eventuali scadenze... var scad2Del = dbCtx.DbSetScadenze.Where(x => x.IdFatt == FattId).FirstOrDefault(); - if(scad2Del != null) + if (scad2Del != null) { dbCtx.DbSetScadenze.Remove(scad2Del); } @@ -252,7 +252,7 @@ namespace SHERPA.Data.Controllers Pec = updItem.Pec, PIva = updItem.PIva, Provincia = updItem.Provincia, - RagSoc = $"__COPIA - {updItem.RagSoc} - COPIA" , + RagSoc = $"__COPIA - {updItem.RagSoc} - COPIA", Valuta = updItem.Valuta, Via = updItem.Via }; @@ -315,7 +315,7 @@ namespace SHERPA.Data.Controllers } /// - /// Elenco Customers possono essere eliminati (NIENTE doc collegati) + /// Elenco Customers che possono essere eliminati (NIENTE doc collegati) /// /// public List CustomersDeletable() @@ -720,6 +720,90 @@ namespace SHERPA.Data.Controllers return done; } + /// + /// Clona un item Customer + /// + /// + /// + public bool VATClona(VatModel updItem) + { + bool done = false; + using (SHERPAFattContext dbCtx = new SHERPAFattContext(_configuration)) + { + try + { + // clono il record + VatModel newRec = new VatModel() + { + Descrizione = $"CLONE - {updItem.Descrizione}", + Enabled = true, + Iva = updItem.Iva, + SplitPay = updItem.SplitPay, + id_ext = 0 + }; + + dbCtx.DbSetVat.Add(newRec); + dbCtx.SaveChanges(); + done = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in VATClona{Environment.NewLine}{exc}"); + } + } + return done; + } + + /// + /// Elenco VAT che possono essere eliminati (NIENTE doc collegati) + /// + /// + public List VATDeletable() + { + List dbResult = new List(); + using (SHERPAFattContext dbCtx = new SHERPAFattContext(_configuration)) + { + dbResult = dbCtx + .DbSetVat + .Where(x => (x.RigheFattNav.Count == 0)) + .ToList(); + } + return dbResult; + } + + /// + /// Elimina un item Customer + /// + /// + /// + public bool VATDelete(VatModel updItem) + { + bool done = false; + using (SHERPAFattContext dbCtx = new SHERPAFattContext(_configuration)) + { + try + { + var item2del = dbCtx + .DbSetVat + .Where(x => x.IdxVat == updItem.IdxVat) + .FirstOrDefault(); + if (item2del != null) + { + dbCtx + .DbSetVat + .Remove(item2del); + dbCtx.SaveChanges(); + done = true; + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in VATDelete{Environment.NewLine}{exc}"); + } + } + return done; + } + /// /// Elenco VAT / CIva /// diff --git a/SHERPA.Data/SHERPA.Data.csproj b/SHERPA.Data/SHERPA.Data.csproj index 86d8cab..b77932b 100644 --- a/SHERPA.Data/SHERPA.Data.csproj +++ b/SHERPA.Data/SHERPA.Data.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/SHERPA/SHERPA.csproj.user b/SHERPA/SHERPA.csproj.user index f0fc58d..d7dbf8f 100644 --- a/SHERPA/SHERPA.csproj.user +++ b/SHERPA/SHERPA.csproj.user @@ -10,7 +10,7 @@ - Release|Any CPU + Debug|Any CPU