Aggiunta gestione VAT + conf prod/test

This commit is contained in:
Samuele Locatelli
2023-06-30 16:48:12 +02:00
parent 86e1762246
commit 9d9a6b484b
32 changed files with 1249 additions and 336 deletions
+5 -5
View File
@@ -20,7 +20,7 @@ else
@if (CurrFilter.EditEnab) @if (CurrFilter.EditEnab)
{ {
<th> <th>
<button class="btn btn-primary btn-sm" @onclick="() => resetSel()" title="Reset selezione"> <button class="btn btn-primary btn-sm" @onclick="() => ResetSel()" title="Reset selezione">
<i class="fa-solid fa-rotate-right"></i> <i class="fa-solid fa-rotate-right"></i>
</button> </button>
</th> </th>
@@ -28,7 +28,7 @@ else
@if (CurrFilter.CloudEnab) @if (CurrFilter.CloudEnab)
{ {
<th> <th>
<button class="btn btn-success btn-sm" @onclick="() => syncAll()" title="Sync ALL"> <button class="btn btn-success btn-sm" @onclick="() => SyncAll()" title="Sync ALL">
<i class="fa-solid fa-cloud-arrow-up"></i> <i class="fa-solid fa-cloud-arrow-up"></i>
</button> </button>
</th> </th>
@@ -43,7 +43,7 @@ else
<th>Cloud ID</th> <th>Cloud ID</th>
@if (CurrFilter.EditEnab) @if (CurrFilter.EditEnab)
{ {
<td></td> <th></th>
} }
} }
</tr> </tr>
@@ -51,7 +51,7 @@ else
<tbody> <tbody>
@foreach (var item in ListRecords) @foreach (var item in ListRecords)
{ {
<tr class="@checkSel(item)"> <tr class="@CheckSel(item)">
@if (CurrFilter.EditEnab) @if (CurrFilter.EditEnab)
{ {
<td> <td>
@@ -64,7 +64,7 @@ else
<td> <td>
@if (string.IsNullOrEmpty(item.IdExt) && hasToken) @if (string.IsNullOrEmpty(item.IdExt) && hasToken)
{ {
<button class="btn btn-sm btn-success" title="Sync Record" @onclick="() => syncCurrent(item)"><i class="fa-solid fa-cloud-arrow-up"></i></button> <button class="btn btn-sm btn-success" title="Sync Record" @onclick="() => SyncCurrent(item)"><i class="fa-solid fa-cloud-arrow-up"></i></button>
} }
else else
{ {
+21 -21
View File
@@ -10,15 +10,6 @@ namespace SHERPA.AD.Components
{ {
#region Public Properties #region Public Properties
[Parameter]
public EventCallback<CustomerModel?> CliCloned { get; set; }
[Parameter]
public EventCallback<CustomerModel?> CliSelected { get; set; }
[Parameter]
public EventCallback<CustomerModel?> CliUpdated { get; set; }
[Parameter] [Parameter]
public SelectCli CurrFilter { get; set; } = new SelectCli(); public SelectCli CurrFilter { get; set; } = new SelectCli();
@@ -34,6 +25,15 @@ namespace SHERPA.AD.Components
} }
} }
[Parameter]
public EventCallback<CustomerModel?> RecCloned { get; set; }
[Parameter]
public EventCallback<CustomerModel?> RecSelected { get; set; }
[Parameter]
public EventCallback<CustomerModel?> RecUpdated { get; set; }
[Parameter] [Parameter]
public EventCallback<int> UpdateCount { get; set; } public EventCallback<int> UpdateCount { get; set; }
@@ -113,7 +113,7 @@ namespace SHERPA.AD.Components
#region Private Methods #region Private Methods
private string checkSel(CustomerModel curItem) private string CheckSel(CustomerModel curItem)
{ {
string answ = ""; string answ = "";
if (SelRecord != null) if (SelRecord != null)
@@ -136,7 +136,7 @@ namespace SHERPA.AD.Components
await SDService.CustomerClona(currItem); await SDService.CustomerClona(currItem);
SelRecord = null; SelRecord = null;
await CliCloned.InvokeAsync(currItem); await RecCloned.InvokeAsync(currItem);
} }
/// <summary> /// <summary>
@@ -153,7 +153,7 @@ namespace SHERPA.AD.Components
await SDService.CustomerDelete(currItem); await SDService.CustomerDelete(currItem);
SelRecord = null; SelRecord = null;
await ReloadData(); await ReloadData();
await CliUpdated.InvokeAsync(currItem); await RecUpdated.InvokeAsync(currItem);
} }
/// <summary> /// <summary>
@@ -165,7 +165,7 @@ namespace SHERPA.AD.Components
{ {
SelRecord = currItem; SelRecord = currItem;
await Task.Delay(1); await Task.Delay(1);
await CliSelected.InvokeAsync(currItem); await RecSelected.InvokeAsync(currItem);
} }
/// <summary> /// <summary>
@@ -221,17 +221,17 @@ namespace SHERPA.AD.Components
await Task.Delay(1); await Task.Delay(1);
} }
private async Task resetSel() private async Task ResetSel()
{ {
SelRecord = null; SelRecord = null;
await CliSelected.InvokeAsync(null); await RecSelected.InvokeAsync(null);
} }
/// <summary> /// <summary>
/// Sincronizzazione di tutti i record che la richiedono /// Sincronizzazione di tutti i record che la richiedono
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task syncAll() private async Task SyncAll()
{ {
IsSynching = true; IsSynching = true;
// prendo elenco dei clienti NON in sync e processo 1:1 // prendo elenco dei clienti NON in sync e processo 1:1
@@ -240,7 +240,7 @@ namespace SHERPA.AD.Components
{ {
foreach (var item in data2sync) foreach (var item in data2sync)
{ {
await syncCurrent(item); await SyncCurrent(item);
} }
} }
IsSynching = false; IsSynching = false;
@@ -251,7 +251,7 @@ namespace SHERPA.AD.Components
/// </summary> /// </summary>
/// <param name="currItem"></param> /// <param name="currItem"></param>
/// <returns></returns> /// <returns></returns>
private async Task syncCurrent(CustomerModel currItem) private async Task SyncCurrent(CustomerModel currItem)
{ {
modalMessage = ""; modalMessage = "";
modalCss = "alert alert-primary"; modalCss = "alert alert-primary";
@@ -273,7 +273,7 @@ namespace SHERPA.AD.Components
// se ho trovato il record --> aggiorno sul DB // se ho trovato il record --> aggiorno sul DB
if (cloudRec != null) if (cloudRec != null)
{ {
await updateDbRecord(currItem, cloudRec); await UpdateDbRecord(currItem, cloudRec);
} }
else else
{ {
@@ -295,7 +295,7 @@ namespace SHERPA.AD.Components
// se ho trovato il record --> aggiorno sul DB // se ho trovato il record --> aggiorno sul DB
if (newCloudRec != null) if (newCloudRec != null)
{ {
await updateDbRecord(currItem, newCloudRec); await UpdateDbRecord(currItem, newCloudRec);
} }
} }
} }
@@ -314,7 +314,7 @@ namespace SHERPA.AD.Components
/// <param name="currItem"></param> /// <param name="currItem"></param>
/// <param name="cloudRec"></param> /// <param name="cloudRec"></param>
/// <returns></returns> /// <returns></returns>
private async Task<bool> updateDbRecord(CustomerModel currItem, ModelClient cloudRec) private async Task<bool> UpdateDbRecord(CustomerModel currItem, ModelClient cloudRec)
{ {
bool fatto = false; bool fatto = false;
currItem.IdExt = $"{cloudRec.Id}"; currItem.IdExt = $"{cloudRec.Id}";
+47
View File
@@ -0,0 +1,47 @@
@if (CurrRecord == null)
{
<LoadingData></LoadingData>
}
else
{
<div class="row g-1">
<div class="col-12">
<div class="form-floating">
<input type="text" class="form-control" placeholder="Descrizione" @bind="@CurrRecord.Descrizione">
<label>Descrizione</label>
</div>
</div>
<div class="col-4">
<div class="form-floating">
<input type="number" min="0" max="1" class="form-control" placeholder="VAT" @bind="@CurrRecord.Iva">
<label>VAT</label>
</div>
</div>
<div class="col-4">
<div class="form-floating">
<div class="form-control form-check form-switch ps-5">
<input type="checkbox" class="form-check-input" placeholder="Attivo" @bind="@CurrRecord.Enabled">
</div>
<label>Attivo</label>
</div>
</div>
<div class="col-4">
<div class="form-floating">
<div class="form-control form-check form-switch ps-5">
<input type="checkbox" class="form-check-input" placeholder="Split Payment" @bind="@CurrRecord.SplitPay">
</div>
<label>Split Payment</label>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="d-grid gap-2 col-6">
<div class="btn btn-success" @onclick="() => doSave()"><i class="fa-solid fa-floppy-disk"></i> Salva</div>
</div>
<div class="d-grid gap-2 col-6">
<div class="btn btn-warning" @onclick="() => doCancel()"><i class="fa-solid fa-xmark"></i> Annulla</div>
</div>
</div>
</div>
</div>
}
+54
View File
@@ -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<bool> ReqCancel { get; set; }
[Parameter]
public EventCallback<VatModel> ReqUpdate { get; set; }
#endregion Public Properties
#region Protected Properties
protected List<vSelGruppiModel> ListSelGruppi { get; set; } = new List<vSelGruppiModel>();
[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
}
}
+53 -12
View File
@@ -18,35 +18,60 @@ else
<thead> <thead>
<tr> <tr>
<th> <th>
<button class="btn btn-success btn-sm" @onclick="() => syncAll()" title="Sync ALL"> @if (EditEnab)
<i class="fa-solid fa-cloud-arrow-up"></i> {
</button> <button class="btn btn-primary btn-sm" @onclick="() => ResetSel()" title="Sync ALL">
<i class="fas fa-sync-alt"></i>
</button>
}
else
{
<button class="btn btn-success btn-sm" @onclick="() => syncAll()" title="Sync ALL">
<i class="fa-solid fa-cloud-arrow-up"></i>
</button>
}
</th> </th>
<th>Iva</th> <th>Iva</th>
<th>Descrizione</th> <th>Descrizione</th>
<th>Attivo</th> <th>Attivo</th>
<th>Split Payment</th> <th>Split Pay</th>
<th>Cloud ID</th> @if (SelRecord == null)
{
<th>Cloud ID</th>
@if (EditEnab)
{
<th></th>
}
}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var item in ListRecords) @foreach (var item in ListRecords)
{ {
<tr> <tr class="@CheckSel(item)">
<td> <td class="text-nowrap">
@if (item.id_ext < 0 && hasToken) @if (EditEnab)
{ {
<button class="btn btn-sm btn-success" title="Sync Record" @onclick="() => syncCurrent(item)"><i class="fa-solid fa-cloud-arrow-up"></i></button> <button class="btn btn-sm btn-info" title="Clona Record" @onclick="() => DoCloneRec(item)"><i class="fa-solid fa-wand-magic"></i></button>
<button class="btn btn-sm btn-primary" title="Edit Record" @onclick="() => DoEditRec(item)"><i class="fas fa-edit"></i></button>
} }
else else
{ {
<button class="btn btn-sm btn-success disabled"><i class="fa-solid fa-cloud"></i></button> @if (item.id_ext < 0 && hasToken)
{
<button class="btn btn-sm btn-success" title="Sync Record" @onclick="() => syncCurrent(item)"><i class="fa-solid fa-cloud-arrow-up"></i></button>
}
else
{
<button class="btn btn-sm btn-success disabled"><i class="fa-solid fa-cloud"></i></button>
}
} }
</td> </td>
<td class="fs-3"> <td class="fs-3">
<b>@($"{item.Iva:P2}")</b> <b>@($"{item.Iva:P2}")</b>
</td> </td>
<td class="text-nowrap"> <td class="text-wrap">
<div><b>@item.Descrizione</b></div> <div><b>@item.Descrizione</b></div>
</td> </td>
<td class="text-nowrap"> <td class="text-nowrap">
@@ -55,7 +80,23 @@ else
<td class="text-nowrap"> <td class="text-nowrap">
<input type="checkbox" disabled checked="@item.SplitPay"> <input type="checkbox" disabled checked="@item.SplitPay">
</td> </td>
<td>@item.id_ext</td> @if (SelRecord == null)
{
<td>@item.id_ext</td>
@if (EditEnab)
{
<td>
@if ((item.id_ext==0) && isDeletable(item.IdxVat))
{
<button class="btn btn-sm btn-danger" title="Sync Record" @onclick="() => DoDelRec(item)"><i class="fa-solid fa-trash"></i></button>
}
else
{
<button class="btn btn-sm btn-danger disabled"><i class="fa-solid fa-trash"></i></button>
}
</td>
}
}
</tr> </tr>
} }
</tbody> </tbody>
+136 -8
View File
@@ -1,5 +1,6 @@
using It.FattureInCloud.Sdk.Model; using It.FattureInCloud.Sdk.Model;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using SHERPA.AD.Data; using SHERPA.AD.Data;
using SHERPA.Data.DbModels; using SHERPA.Data.DbModels;
@@ -12,30 +13,46 @@ namespace SHERPA.AD.Components
[Parameter] [Parameter]
public int Anno { get; set; } = DateTime.Today.Year; public int Anno { get; set; } = DateTime.Today.Year;
[Parameter]
public SelectVat CurrFilter { get; set; } = new SelectVat() { CurrPage = 0, NumRecord = 1 };
[Parameter] [Parameter]
public bool EditEnab { get; set; } = false; public bool EditEnab { get; set; } = false;
[Parameter] [Parameter]
public bool OnlyNeedSync { get; set; } = false; public bool OnlyNeedSync { get; set; } = false;
[Parameter]
public EventCallback<VatModel?> RecCloned { get; set; }
[Parameter]
public EventCallback<VatModel?> RecSelected { get; set; }
[Parameter]
public EventCallback<VatModel?> RecUpdated { get; set; }
[Parameter] [Parameter]
public bool SelEnab { get; set; } = false; public bool SelEnab { get; set; } = false;
[Parameter] [Parameter]
public string TipoDoc { get; set; } = "*"; public string TipoDoc { get; set; } = "*";
[Parameter]
public EventCallback<int> UpdateCount { get; set; }
#endregion Public Properties #endregion Public Properties
#region Protected Properties #region Protected Properties
protected bool IsLoading { get; set; } = false; protected bool IsLoading { get; set; } = false;
protected bool IsSynching { get; set; } = false; protected bool IsSynching { get; set; } = false;
[Inject]
protected IJSRuntime JSRuntime { get; set; } = null!;
protected List<VatModel> ListDeletable { get; set; } = new List<VatModel>();
protected List<VatModel> ListRecords { get; set; } = new List<VatModel>(); protected List<VatModel> ListRecords { get; set; } = new List<VatModel>();
protected string modalCss { get; set; } = "alert alert-success"; protected string modalCss { get; set; } = "alert alert-success";
protected string modalMessage { get; set; } = ""; protected string modalMessage { get; set; } = "";
[Inject] [Inject]
@@ -44,6 +61,8 @@ namespace SHERPA.AD.Components
[Inject] [Inject]
protected SADDataService SDService { get; set; } = null!; protected SADDataService SDService { get; set; } = null!;
protected List<VatModel> SearchRecords { get; set; } = new List<VatModel>();
protected int totalCount { get; set; } = 0;
protected string widthMessage { get; set; } = "width: 60%"; protected string widthMessage { get; set; } = "width: 60%";
#endregion Protected Properties #endregion Protected Properties
@@ -68,7 +87,12 @@ namespace SHERPA.AD.Components
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
await ReloadData(); if (!CurrFilter.Equals(LastFilter))
{
SelRecord = null;
LastFilter = CurrFilter.clone();
await ReloadData();
}
} }
#endregion Protected Methods #endregion Protected Methods
@@ -81,21 +105,125 @@ namespace SHERPA.AD.Components
set => MService.hasToken = value; set => MService.hasToken = value;
} }
private SelectVat LastFilter { get; set; } = new SelectVat() { CurrPage = 0, NumRecord = 0 };
private VatModel? SelRecord { get; set; } = null;
#endregion Private Properties #endregion Private Properties
#region Private Methods #region Private Methods
private string CheckSel(VatModel curItem)
{
string answ = "";
if (SelRecord != null)
{
answ = curItem.IdxVat == SelRecord.IdxVat ? "table-info" : "";
}
return answ;
}
/// <summary>
/// Clona il record
/// </summary>
/// <param name="currItem"></param>
/// <returns></returns>
private async Task DoCloneRec(VatModel currItem)
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler DUPLICARE il record selezionato??"))
return;
await SDService.VATClona(currItem);
SelRecord = null;
await RecCloned.InvokeAsync(currItem);
}
/// <summary>
/// Elimina record
/// </summary>
/// <param name="currItem"></param>
/// <returns></returns>
private async Task DoDelRec(VatModel currItem)
{
// chiedo verifica
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sicuro di voler ELIMINARE il record selezionato??"))
return;
await SDService.VATDelete(currItem);
SelRecord = null;
await ReloadData();
await RecUpdated.InvokeAsync(currItem);
}
/// <summary>
/// Seleziona record
/// </summary>
/// <param name="currItem"></param>
/// <returns></returns>
private async Task DoEditRec(VatModel currItem)
{
SelRecord = currItem;
await Task.Delay(1);
await RecSelected.InvokeAsync(currItem);
}
/// <summary>
/// Indica che è cancellabile (NON HA fatture relative)
/// </summary>
/// <param name="IdxCli"></param>
/// <returns></returns>
private bool isDeletable(int IdxVat)
{
return ListDeletable.Where(x => x.IdxVat == IdxVat).Count() > 0;
}
private async Task ReloadData() private async Task ReloadData()
{ {
var allRec = await SDService.VATToSync(TipoDoc, Anno, false); List<VatModel> allRec = new List<VatModel>();
if (OnlyNeedSync) if (EditEnab)
{ {
ListRecords = allRec.Where(x => x.id_ext < 0).ToList(); allRec = await SDService.VATGetAll();
} }
else 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);
} }
/// <summary> /// <summary>
+88 -2
View File
@@ -18,8 +18,7 @@ namespace SHERPA.AD.Data
_configuration = configuration; _configuration = configuration;
_emailSender = emailSender; _emailSender = emailSender;
// Conf cache // Conf cache
redisConn = redisConnMult;// ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); redisConn = redisConnMult;
//redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis"));
redisDb = this.redisConn.GetDatabase(); 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/ // 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; return answ;
} }
/// <summary> /// <summary>
/// Elimina un item Customer /// Elimina un item Customer
/// </summary> /// </summary>
@@ -599,6 +599,91 @@ namespace SHERPA.AD.Data
return answ; return answ;
} }
/// <summary>
/// Clona un item VAT
/// </summary>
/// <param name="updItem"></param>
/// <returns></returns>
public async Task<bool> 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;
}
/// <summary>
/// Elenco VAT eliminabili
/// </summary>
/// <returns></returns>
public async Task<List<VatModel>> VATDeletable()
{
string source = "DB";
List<VatModel>? dbResult = new List<VatModel>();
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<List<VatModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<VatModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.VATDeletable();
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, FastCache);
}
if (dbResult == null)
{
dbResult = new List<VatModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"VATDeletable | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
/// <summary>
/// Elimina un item VAT
/// </summary>
/// <param name="updItem"></param>
/// <returns></returns>
public async Task<bool> 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;
}
/// <summary> /// <summary>
/// Elenco VAT / CIva (tutti) /// Elenco VAT / CIva (tutti)
/// </summary> /// </summary>
@@ -923,6 +1008,7 @@ namespace SHERPA.AD.Data
protected const string rKeySyncVat = $"{redisBaseAddr}:Cache:VAT:CloudSync"; protected const string rKeySyncVat = $"{redisBaseAddr}:Cache:VAT:CloudSync";
protected const string rKeyVat = $"{redisBaseAddr}:Cache:VAT:List"; protected const string rKeyVat = $"{redisBaseAddr}:Cache:VAT:List";
protected const string rKeyVatAll = $"{redisBaseAddr}:Cache:VAT:ALL"; protected const string rKeyVatAll = $"{redisBaseAddr}:Cache:VAT:ALL";
protected const string rKeyVatDel = $"{redisBaseAddr}:Cache:VAT:Del";
protected static SInManController dbController = null!; protected static SInManController dbController = null!;
protected Random rnd = new Random(); protected Random rnd = new Random();
+68
View File
@@ -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
}
}
+1 -5
View File
@@ -52,7 +52,7 @@
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="@mainCss"> <div class="@mainCss">
<CustomerManager CurrFilter="@ActFilter" CliSelected="SetCurrCli" CliCloned="SetClonedCli" ForceReload="@isLoading" UpdateCount="SetCount"></CustomerManager> <CustomerManager CurrFilter="@ActFilter" RecSelected="SetCurrRec" RecCloned="SetClonedRec" ForceReload="@isLoading" UpdateCount="SetCount"></CustomerManager>
</div> </div>
@if (SelRecord != null) @if (SelRecord != null)
{ {
@@ -66,7 +66,3 @@
<DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetCurrPage" totalCount="@totalCount" showLoading="@isLoading" /> <DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetCurrPage" totalCount="@totalCount" showLoading="@isLoading" />
</div> </div>
</div> </div>
+8 -8
View File
@@ -25,12 +25,6 @@ namespace SHERPA.AD.Pages
protected List<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>(); protected List<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>();
protected bool showAll
{
get => ActFilter.ShowFilt;
set => ActFilter.ShowFilt = value;
}
protected int numRecord protected int numRecord
{ {
get => ActFilter.NumRecord; get => ActFilter.NumRecord;
@@ -58,6 +52,12 @@ namespace SHERPA.AD.Pages
set => ActFilter.CodTipo = value; set => ActFilter.CodTipo = value;
} }
protected bool showAll
{
get => ActFilter.ShowFilt;
set => ActFilter.ShowFilt = value;
}
protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle(); protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle();
#endregion Protected Properties #endregion Protected Properties
@@ -149,14 +149,14 @@ namespace SHERPA.AD.Pages
SelTipo = "*"; SelTipo = "*";
} }
private void SetClonedCli(CustomerModel itemSel) private void SetClonedRec(CustomerModel itemSel)
{ {
// imposto filtro toggle + ricerca... // imposto filtro toggle + ricerca...
toggleSync.isActive = false; toggleSync.isActive = false;
SearchVal = itemSel.RagSoc ?? ""; SearchVal = itemSel.RagSoc ?? "";
} }
private void SetCurrCli(CustomerModel itemSel) private void SetCurrRec(CustomerModel itemSel)
{ {
SelRecord = itemSel; SelRecord = itemSel;
} }
+1 -1
View File
@@ -58,7 +58,7 @@
</button> </button>
</h2> </h2>
<div id="accColl02" class="accordion-collapse collapse p-2" aria-labelledby="accHeadTwo" data-bs-parent="#accCloudSync"> <div id="accColl02" class="accordion-collapse collapse p-2" aria-labelledby="accHeadTwo" data-bs-parent="#accCloudSync">
<VatManager Anno="@SelAnno" TipoDoc="@SelTipo" OnlyNeedSync="@needSync"></VatManager> <VatManager Anno="@SelAnno" TipoDoc="@SelTipo" OnlyNeedSync="@needSync" CurrFilter="@VatFilter"></VatManager>
</div> </div>
</div> </div>
<div class="accordion-item"> <div class="accordion-item">
+17 -17
View File
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Components;
using SHERPA.Data.DbModels;
using SHERPA.AD.Data;
using EgwCoreLib.Razor; using EgwCoreLib.Razor;
using Microsoft.AspNetCore.Components;
using SHERPA.AD.Data;
using SHERPA.Data.DbModels;
namespace SHERPA.AD.Pages namespace SHERPA.AD.Pages
{ {
@@ -9,8 +9,20 @@ namespace SHERPA.AD.Pages
{ {
#region Protected Properties #region Protected Properties
protected SelectCli CliFilter { get; set; } = new SelectCli();
protected SelectDocExp DocFilter { get; set; } = new SelectDocExp();
protected List<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>(); protected List<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>();
protected bool needSync
{
get => DocFilter.OnlySync;
set
{
DocFilter.OnlySync = value;
CliFilter.OnlySync = value;
}
}
[Inject] [Inject]
protected SADDataService SDService { get; set; } = null!; protected SADDataService SDService { get; set; } = null!;
@@ -34,18 +46,8 @@ namespace SHERPA.AD.Pages
} }
} }
protected bool needSync protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle();
{ protected SelectVat VatFilter { get; set; } = new SelectVat() { CurrPage = 0, NumRecord = 1000 };
get => DocFilter.OnlySync;
set
{
DocFilter.OnlySync = value;
CliFilter.OnlySync = value;
}
}
protected SelectDocExp DocFilter { get; set; } = new SelectDocExp();
protected SelectCli CliFilter { get; set; } = new SelectCli();
#endregion Protected Properties #endregion Protected Properties
@@ -69,8 +71,6 @@ namespace SHERPA.AD.Pages
SelTipo = "*"; SelTipo = "*";
} }
protected Toggler.SelectGlobalToggle toggleSync { get; set; } = new Toggler.SelectGlobalToggle();
protected void updToggSync(Toggler.SelectGlobalToggle newTogg) protected void updToggSync(Toggler.SelectGlobalToggle newTogg)
{ {
needSync = newTogg.isActive; needSync = newTogg.isActive;
+40 -3
View File
@@ -1,5 +1,42 @@
<h3>VAT</h3> @page "/VAT"
@code { <PageTitle>VAT Management</PageTitle>
}
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between">
<div class="text-uppercase">
<b>Criteri selezione</b>
</div>
<div class="d-flex flex-row-reverse">
<div>
<Toggler SelFilter="toggleSync" FilterChanged="updToggSync"></Toggler>
</div>
<div class="d-flex flex-row-reverse">
<div class="input-group input-group-sm mb-1">
<label class="input-group-text" title="Anno">Cerca</label>
<input class="form-control text-end" @bind="@SearchVal" type="text" title="Ricerca Libera" placeholder="[R]icerca" accesskey="r">
<button class="btn btn-secondary" @onclick="ResetSearch"><i class="fa-solid fa-rotate-right"></i></button>
</div>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="@mainCss">
<VatManager Anno="0" TipoDoc="*" OnlyNeedSync="false" EditEnab="true" SelEnab="true" CurrFilter="@ActFilter" UpdateCount="SetCount" RecSelected="SetCurrRec" RecCloned="SetClonedRec"></VatManager>
</div>
@if (SelRecord != null)
{
<div class="col-4 ps-1">
<VatDetail CurrRecord="@SelRecord" ReqUpdate="doEditSave" ReqCancel="doEditCancel"></VatDetail>
</div>
}
</div>
</div>
<div class="card-footer py-1">
<DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetCurrPage" totalCount="@totalCount" showLoading="@isLoading" />
</div>
</div>
+150
View File
@@ -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<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>();
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
/// <summary>
/// Processa task cancel edit
/// </summary>
private async Task doEditCancel(bool reload)
{
if (reload)
{
isLoading = true;
SelRecord = null;
await Task.Delay(1);
isLoading = false;
}
await Task.Delay(1);
}
/// <summary>
/// Processa task update record
/// </summary>
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
}
}
-7
View File
@@ -43,13 +43,6 @@ builder.Services.Configure<MailKitEmailSenderOptions>(options =>
options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"]; 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. // Add services to the container.
builder.Services.AddRazorPages(); builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor(); builder.Services.AddServerSideBlazor();
+4 -3
View File
@@ -4,7 +4,8 @@
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Version>1.0.2303.0219</Version> <Version>1.0.2306.3016</Version>
<Copyright>Egalware 2021+</Copyright>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -29,9 +30,9 @@
<PackageReference Include="It.FattureInCloud.Sdk" Version="2.0.18" /> <PackageReference Include="It.FattureInCloud.Sdk" Version="2.0.18" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.13" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.13" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.13" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.13" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.1.1" /> <PackageReference Include="NLog" Version="5.1.1" />
<PackageReference Include="StackExchange.Redis" Version="2.6.90" /> <PackageReference Include="StackExchange.Redis" Version="2.6.111" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+4
View File
@@ -11,5 +11,9 @@
"Name": "SHERPA Invoice Management", "Name": "SHERPA Invoice Management",
"ShortName": "SHERPA IM", "ShortName": "SHERPA IM",
"JumpUrl": "https://office.egalware.com/SHERPA-AD/index" "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;"
} }
} }
+2
View File
@@ -8,6 +8,8 @@
"AllowedHosts": "*", "AllowedHosts": "*",
"CodApp": "SHERPA", "CodApp": "SHERPA",
"ConnectionStrings": { "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", "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;" "Sherpa.Fatt": "Data Source=W2019-SQL-STEAM;Initial Catalog=SHERPA.Fatt;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=Sherpa.BBM;"
}, },
+3 -3
View File
@@ -6,9 +6,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.13" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.13">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
+1 -1
View File
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace SHERPA.BBM.CORE namespace SHERPA.BBM.CORE
{ {
public class SortCallBack public class SortCallBack
{ {
public bool IsAscending { get; set; } = true; public bool IsAscending { get; set; } = true;
+2 -1
View File
@@ -38,7 +38,8 @@
{ {
get get
{ {
return isCurrent ? "btn-primary" : "btn-outline-secondary"; return isCurrent ? "text-primary" : "text-secondary opacity-25";
//return isCurrent ? "btn-primary" : "btn-outline-secondary";
} }
} }
+306 -37
View File
@@ -1,38 +1,30 @@
using Microsoft.Extensions.Configuration; using Newtonsoft.Json;
using Microsoft.Extensions.Logging; using NLog;
using System; using StackExchange.Redis;
using System.Collections.Generic; using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace SHERPA.BBM.UI.Data namespace SHERPA.BBM.UI.Data
{ {
public class BBM_EFService : IDisposable public class BBM_EFService : IDisposable
{ {
#region Private Fields
private static IConfiguration _configuration = null!;
private static ILogger<BBM_EFService> _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 #region Public Constructors
public BBM_EFService(IConfiguration configuration, ILogger<BBM_EFService> logger) public BBM_EFService(IConfiguration configuration, ILogger<BBM_EFService> logger, IConnectionMultiplexer redisConnMult)
{ {
_logger = logger; _logger = logger;
_configuration = configuration; _configuration = configuration;
connStringBBM = _configuration.GetConnectionString("Sherpa.BBM"); connStringBBM = _configuration.GetConnectionString("Sherpa.BBM");
connStringFatt = _configuration.GetConnectionString("Sherpa.Fatt"); 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}"); //_logger.LogInformation($"ConnString: {connString}");
if (string.IsNullOrEmpty(connStringBBM) || string.IsNullOrEmpty(connStringFatt)) if (string.IsNullOrEmpty(connStringBBM) || string.IsNullOrEmpty(connStringFatt))
{ {
@@ -41,12 +33,6 @@ namespace SHERPA.BBM.UI.Data
else else
{ {
dbController = new CORE.Controllers.BBMController(_configuration); 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()); return Task.FromResult(dbController.NegotYears());
} }
/// <summary>
/// Remove for single hash record
/// </summary>
/// <param name="currKey">Chiave redis della Hashlist</param>
/// <param name="chiave">Chiave nella HashList</param>
/// <returns>Esito rimozione</returns>
public async Task<bool> 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) public void ResourceAdd(CORE.DbModels.ResourcesModel newItem)
{ {
try try
@@ -463,29 +467,164 @@ namespace SHERPA.BBM.UI.Data
dbController.rollBackEntity(item); dbController.rollBackEntity(item);
} }
public Task<double> SumTotDraft(int anno) public Task<decimal> 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<decimal>(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<decimal> SumTotImporto(int anno) public Task<decimal> 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<decimal>(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<decimal> SumTotIncasso(int anno) public Task<decimal> 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<decimal>(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<double> SumTotOrdinato(int anno) public Task<decimal> 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<decimal>(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<double> SumTotTrattato(int anno) public Task<decimal> 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<decimal>(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) public void TagDelete(CORE.DbModels.TagModel currRecord)
@@ -539,5 +678,135 @@ namespace SHERPA.BBM.UI.Data
} }
#endregion Public Methods #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
/// <summary>
/// Effettua upsert in HasList redis
/// </summary>
/// <param name="currKey">Chiave redis della Hashlist</param>
/// <param name="chiave">Chiave nella HashList</param>
/// <param name="valore">Valore da salvare</param>
/// <returns>Num record nella HashList</returns>
protected async Task<long> 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<BBM_EFService> _logger = null!;
private static JsonSerializerSettings? JSSettings;
private static Logger Log = LogManager.GetCurrentClassLogger();
/// <summary>
/// Durata cache lunga IN SECONDI
/// </summary>
private int cacheTtlLong = 60 * 5;
/// <summary>
/// Durata cache breve IN SECONDI
/// </summary>
private int cacheTtlShort = 60 * 1;
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private IConnectionMultiplexer redisConn;
//ISubscriber sub = redis.GetSubscriber();
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
#endregion Private Fields
#region Private Properties
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan FastCache
{
get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan LongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan UltraLongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
}
#endregion Private Properties
#region Private Methods
/// <summary>
/// Esegue flush memoria redis dato pattern
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
private async Task<bool> 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
} }
} }
+3 -35
View File
@@ -39,41 +39,6 @@
<div class="card mb-2"> <div class="card mb-2">
<div class="card-header table-primary h3">@anno</div> <div class="card-header table-primary h3">@anno</div>
<div class="card-body"> <div class="card-body">
@*<div class="row h2 text-center">
<div class="col-6">
<div class="card">
<div class="card-header small">Trattative</div>
<div class="card-body" style="min-height: 7rem;">
@(getTrattato(anno).Result.ToString("C2"))
<div class="small" title="Offerte preliminari non vincolanti"><sub>+ @(getDraft(anno).Result.ToString("C2"))</sub></div>
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-header small">Ordinato</div>
<div class="card-body" style="min-height: 7rem;">
@(getOrdinato(anno).Result.ToString("C2"))
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-header small">Fatturato</div>
<div class="card-body" style="min-height: 7rem;">
@(getImporto(anno).Result.ToString("C2"))
</div>
</div>
</div>
<div class="col-6">
<div class="card">
<div class="card-header small">Incassato</div>
<div class="card-body" style="min-height: 7rem;">
@(getIncasso(anno).Result.ToString("C2"))
</div>
</div>
</div>
</div>*@
<div class="row"> <div class="row">
<div class="col border rounded px-0 mx-2"> <div class="col border rounded px-0 mx-2">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@@ -99,6 +64,7 @@
</div> </div>
<div class="px-2 flex-fill h3 text-right"> <div class="px-2 flex-fill h3 text-right">
<b>@(getOrdinato(anno).Result.ToString("C2"))</b> <b>@(getOrdinato(anno).Result.ToString("C2"))</b>
<div class="small" title="Conversione in Ordini"><sub>@((getOrdinato(anno).Result / getTrattato(anno).Result).ToString("P1"))</sub></div>
</div> </div>
</div> </div>
</div> </div>
@@ -112,6 +78,7 @@
</div> </div>
<div class="px-2 flex-fill h3 text-right"> <div class="px-2 flex-fill h3 text-right">
<b>@(getImporto(anno).Result.ToString("C2"))</b> <b>@(getImporto(anno).Result.ToString("C2"))</b>
<div class="small" title="Ordini Fatturati"><sub>@((getImporto(anno).Result / getOrdinato(anno).Result).ToString("P1"))</sub></div>
</div> </div>
</div> </div>
</div> </div>
@@ -125,6 +92,7 @@
</div> </div>
<div class="px-2 flex-fill h3 text-right"> <div class="px-2 flex-fill h3 text-right">
<b>@(getIncasso(anno).Result.ToString("C2"))</b> <b>@(getIncasso(anno).Result.ToString("C2"))</b>
<div class="small" title="Fatture Incassate"><sub>@((getIncasso(anno).Result / getImporto(anno).Result).ToString("P1"))</sub></div>
</div> </div>
</div> </div>
</div> </div>
+9 -8
View File
@@ -10,9 +10,9 @@ namespace SHERPA.BBM.UI.Pages
{ {
#region Protected Methods #region Protected Methods
protected async Task<double> getDraft(int anno) protected async Task<decimal> getDraft(int anno)
{ {
double valore = 0; decimal valore = 0;
try try
{ {
valore = await BBMService.SumTotDraft(anno); valore = await BBMService.SumTotDraft(anno);
@@ -46,9 +46,9 @@ namespace SHERPA.BBM.UI.Pages
return valore; return valore;
} }
protected async Task<double> getOrdinato(int anno) protected async Task<decimal> getOrdinato(int anno)
{ {
double valore = 0; decimal valore = 0;
try try
{ {
valore = await BBMService.SumTotOrdinato(anno); valore = await BBMService.SumTotOrdinato(anno);
@@ -58,9 +58,9 @@ namespace SHERPA.BBM.UI.Pages
return valore; return valore;
} }
protected async Task<double> getTrattato(int anno) protected async Task<decimal> getTrattato(int anno)
{ {
double valore = 0; decimal valore = 0;
try try
{ {
valore = await BBMService.SumTotTrattato(anno); valore = await BBMService.SumTotTrattato(anno);
@@ -70,6 +70,7 @@ namespace SHERPA.BBM.UI.Pages
return valore; return valore;
} }
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
await Task.Delay(1); await Task.Delay(1);
@@ -86,10 +87,10 @@ namespace SHERPA.BBM.UI.Pages
private int Anno { get; set; } = DateTime.Today.Year; private int Anno { get; set; } = DateTime.Today.Year;
[Inject] [Inject]
private BBM_EFService BBMService { get; set; } private BBM_EFService BBMService { get; set; } = null!;
[Inject] [Inject]
private MessageService MessageService { get; set; } private MessageService MessageService { get; set; } = null!;
[Inject] [Inject]
private BBM_SelectData SelectData { get; set; } private BBM_SelectData SelectData { get; set; }
+102 -49
View File
@@ -1,54 +1,107 @@
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration; using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Identity.UI.Services;
using NLog.Web; using SHERPA.BBM.UI.Data;
using System; using SHERPA.Data;
using System.Collections.Generic; using StackExchange.Redis;
using System.Linq; using Microsoft.AspNetCore.Localization;
using System.Threading.Tasks; 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 // By default, all incoming requests will be authorized according to the default policy.
{ options.FallbackPolicy = options.DefaultPolicy;
#region Public Methods });
public static IHostBuilder CreateHostBuilder(string[] args) => // configuration setup
Host.CreateDefaultBuilder(args) ConfigurationManager configuration = builder.Configuration;
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
})
.UseNLog();
public static void Main(string[] args) // REDIS setup
{ string connStringRedis = configuration.GetConnectionString("Redis");
// inclusione NLog: string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
// https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5 // avvio oggetto shared x redis...
// https://codewithmukesh.com/blog/logging-with-nlog-in-aspnet-core/ var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis);
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();
}
}
#endregion Public Methods // abilitazione x email management con MailKit
} builder.Services.AddTransient<IEmailSender, MailKitEmailSender>();
} builder.Services.Configure<MailKitEmailSenderOptions>(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<SqlErrorLog>(options =>
//{
// options.ConnectionString = elmaConn;
//});
builder.Services.AddLocalization();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<BBM_EFService>();
builder.Services.AddScoped<BBM_SelectData>();
builder.Services.AddScoped<MessageService>();
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<IConnectionMultiplexer>(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();
+13 -3
View File
@@ -4,7 +4,10 @@
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<UserSecretsId>60fcdaab-6c1e-4bec-9d88-f7727ef1c12c</UserSecretsId> <UserSecretsId>60fcdaab-6c1e-4bec-9d88-f7727ef1c12c</UserSecretsId>
<ApplicationIcon>wwwroot\favicon.ico</ApplicationIcon> <ApplicationIcon>wwwroot\favicon.ico</ApplicationIcon>
<Version>1.0.2302.2819</Version> <Version>1.0.2306.3016</Version>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Copyright>Egalware 2021+</Copyright>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -155,22 +158,29 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.SessionStorage" Version="2.3.0" />
<PackageReference Include="ElmahCore" Version="2.1.2" /> <PackageReference Include="ElmahCore" Version="2.1.2" />
<PackageReference Include="ElmahCore.Common" Version="2.1.2" /> <PackageReference Include="ElmahCore.Common" Version="2.1.2" />
<PackageReference Include="ElmahCore.Sql" Version="2.1.2" /> <PackageReference Include="ElmahCore.Sql" Version="2.1.2" />
<PackageReference Include="EntityFramework" Version="6.4.4" /> <PackageReference Include="EntityFramework" Version="6.4.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2"> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.13">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.2.1" /> <PackageReference Include="NLog.Web.AspNetCore" Version="5.2.1" />
<PackageReference Include="StackExchange.Redis" Version="2.6.111" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\SHERPA.BBM.CORE\SHERPA.BBM.CORE.csproj" /> <ProjectReference Include="..\SHERPA.BBM.CORE\SHERPA.BBM.CORE.csproj" />
<ProjectReference Include="..\SHERPA.Data\SHERPA.Data.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
-101
View File
@@ -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<SqlErrorLog>(options =>
//{
// options.ConnectionString = elmaConn;
//});
services.AddLocalization();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<BBM_EFService>();
services.AddScoped<BBM_SelectData>();
services.AddScoped<MessageService>();
}
#endregion Public Methods
}
}
+6 -1
View File
@@ -8,5 +8,10 @@
} }
}, },
"AllowedHosts": "*", "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;"
}
} }
+16
View File
@@ -9,7 +9,23 @@
"AllowedHosts": "*", "AllowedHosts": "*",
"BaseAppPath": "/", "BaseAppPath": "/",
"ConnectionStrings": { "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.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;" "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"
}
}
} }
} }
+87 -3
View File
@@ -100,7 +100,7 @@ namespace SHERPA.Data.Controllers
{ {
// elimina eventuali scadenze... // elimina eventuali scadenze...
var scad2Del = dbCtx.DbSetScadenze.Where(x => x.IdFatt == FattId).FirstOrDefault(); var scad2Del = dbCtx.DbSetScadenze.Where(x => x.IdFatt == FattId).FirstOrDefault();
if(scad2Del != null) if (scad2Del != null)
{ {
dbCtx.DbSetScadenze.Remove(scad2Del); dbCtx.DbSetScadenze.Remove(scad2Del);
} }
@@ -252,7 +252,7 @@ namespace SHERPA.Data.Controllers
Pec = updItem.Pec, Pec = updItem.Pec,
PIva = updItem.PIva, PIva = updItem.PIva,
Provincia = updItem.Provincia, Provincia = updItem.Provincia,
RagSoc = $"__COPIA - {updItem.RagSoc} - COPIA" , RagSoc = $"__COPIA - {updItem.RagSoc} - COPIA",
Valuta = updItem.Valuta, Valuta = updItem.Valuta,
Via = updItem.Via Via = updItem.Via
}; };
@@ -315,7 +315,7 @@ namespace SHERPA.Data.Controllers
} }
/// <summary> /// <summary>
/// Elenco Customers possono essere eliminati (NIENTE doc collegati) /// Elenco Customers che possono essere eliminati (NIENTE doc collegati)
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public List<CustomerModel> CustomersDeletable() public List<CustomerModel> CustomersDeletable()
@@ -720,6 +720,90 @@ namespace SHERPA.Data.Controllers
return done; return done;
} }
/// <summary>
/// Clona un item Customer
/// </summary>
/// <param name="updItem"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Elenco VAT che possono essere eliminati (NIENTE doc collegati)
/// </summary>
/// <returns></returns>
public List<VatModel> VATDeletable()
{
List<VatModel> dbResult = new List<VatModel>();
using (SHERPAFattContext dbCtx = new SHERPAFattContext(_configuration))
{
dbResult = dbCtx
.DbSetVat
.Where(x => (x.RigheFattNav.Count == 0))
.ToList();
}
return dbResult;
}
/// <summary>
/// Elimina un item Customer
/// </summary>
/// <param name="updItem"></param>
/// <returns></returns>
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;
}
/// <summary> /// <summary>
/// Elenco VAT / CIva /// Elenco VAT / CIva
/// </summary> /// </summary>
+1 -1
View File
@@ -30,7 +30,7 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.1.1" /> <PackageReference Include="NLog" Version="5.1.1" />
</ItemGroup> </ItemGroup>
+1 -1
View File
@@ -10,7 +10,7 @@
<IISExpressSSLPort /> <IISExpressSSLPort />
<IISExpressUseClassicPipelineMode /> <IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile /> <UseGlobalApplicationHostFile />
<LastActiveSolutionConfig>Release|Any CPU</LastActiveSolutionConfig> <LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
</PropertyGroup> </PropertyGroup>
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>