Aggiunta gestione VAT + conf prod/test
This commit is contained in:
@@ -20,7 +20,7 @@ else
|
||||
@if (CurrFilter.EditEnab)
|
||||
{
|
||||
<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>
|
||||
</button>
|
||||
</th>
|
||||
@@ -28,7 +28,7 @@ else
|
||||
@if (CurrFilter.CloudEnab)
|
||||
{
|
||||
<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>
|
||||
</button>
|
||||
</th>
|
||||
@@ -43,7 +43,7 @@ else
|
||||
<th>Cloud ID</th>
|
||||
@if (CurrFilter.EditEnab)
|
||||
{
|
||||
<td></td>
|
||||
<th></th>
|
||||
}
|
||||
}
|
||||
</tr>
|
||||
@@ -51,7 +51,7 @@ else
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr class="@checkSel(item)">
|
||||
<tr class="@CheckSel(item)">
|
||||
@if (CurrFilter.EditEnab)
|
||||
{
|
||||
<td>
|
||||
@@ -64,7 +64,7 @@ else
|
||||
<td>
|
||||
@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
|
||||
{
|
||||
|
||||
@@ -10,15 +10,6 @@ namespace SHERPA.AD.Components
|
||||
{
|
||||
#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]
|
||||
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]
|
||||
public EventCallback<int> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -153,7 +153,7 @@ namespace SHERPA.AD.Components
|
||||
await SDService.CustomerDelete(currItem);
|
||||
SelRecord = null;
|
||||
await ReloadData();
|
||||
await CliUpdated.InvokeAsync(currItem);
|
||||
await RecUpdated.InvokeAsync(currItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -165,7 +165,7 @@ namespace SHERPA.AD.Components
|
||||
{
|
||||
SelRecord = currItem;
|
||||
await Task.Delay(1);
|
||||
await CliSelected.InvokeAsync(currItem);
|
||||
await RecSelected.InvokeAsync(currItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sincronizzazione di tutti i record che la richiedono
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// </summary>
|
||||
/// <param name="currItem"></param>
|
||||
/// <returns></returns>
|
||||
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
|
||||
/// <param name="currItem"></param>
|
||||
/// <param name="cloudRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> updateDbRecord(CustomerModel currItem, ModelClient cloudRec)
|
||||
private async Task<bool> UpdateDbRecord(CustomerModel currItem, ModelClient cloudRec)
|
||||
{
|
||||
bool fatto = false;
|
||||
currItem.IdExt = $"{cloudRec.Id}";
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -18,22 +18,46 @@ else
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@if (EditEnab)
|
||||
{
|
||||
<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>Iva</th>
|
||||
<th>Descrizione</th>
|
||||
<th>Attivo</th>
|
||||
<th>Split Payment</th>
|
||||
<th>Split Pay</th>
|
||||
@if (SelRecord == null)
|
||||
{
|
||||
<th>Cloud ID</th>
|
||||
@if (EditEnab)
|
||||
{
|
||||
<th></th>
|
||||
}
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ListRecords)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<tr class="@CheckSel(item)">
|
||||
<td class="text-nowrap">
|
||||
@if (EditEnab)
|
||||
{
|
||||
<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
|
||||
{
|
||||
@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>
|
||||
@@ -42,11 +66,12 @@ else
|
||||
{
|
||||
<button class="btn btn-sm btn-success disabled"><i class="fa-solid fa-cloud"></i></button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td class="fs-3">
|
||||
<b>@($"{item.Iva:P2}")</b>
|
||||
</td>
|
||||
<td class="text-nowrap">
|
||||
<td class="text-wrap">
|
||||
<div><b>@item.Descrizione</b></div>
|
||||
</td>
|
||||
<td class="text-nowrap">
|
||||
@@ -55,7 +80,23 @@ else
|
||||
<td class="text-nowrap">
|
||||
<input type="checkbox" disabled checked="@item.SplitPay">
|
||||
</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>
|
||||
}
|
||||
</tbody>
|
||||
|
||||
@@ -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<VatModel?> RecCloned { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<VatModel?> RecSelected { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<VatModel?> RecUpdated { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool SelEnab { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public string TipoDoc { get; set; } = "*";
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> 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<VatModel> ListDeletable { get; set; } = new List<VatModel>();
|
||||
protected List<VatModel> ListRecords { get; set; } = new List<VatModel>();
|
||||
|
||||
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<VatModel> SearchRecords { get; set; } = new List<VatModel>();
|
||||
protected int totalCount { get; set; } = 0;
|
||||
protected string widthMessage { get; set; } = "width: 60%";
|
||||
|
||||
#endregion Protected Properties
|
||||
@@ -68,8 +87,13 @@ namespace SHERPA.AD.Components
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/// <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()
|
||||
{
|
||||
var allRec = await SDService.VATToSync(TipoDoc, Anno, false);
|
||||
if (OnlyNeedSync)
|
||||
List<VatModel> allRec = new List<VatModel>();
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elimina un item Customer
|
||||
/// </summary>
|
||||
@@ -599,6 +599,91 @@ namespace SHERPA.AD.Data
|
||||
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>
|
||||
/// Elenco VAT / CIva (tutti)
|
||||
/// </summary>
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<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>
|
||||
@if (SelRecord != null)
|
||||
{
|
||||
@@ -66,7 +66,3 @@
|
||||
<DataPager PageSize="@numRecord" currPage="@currPage" numRecordChanged="SetNumRec" numPageChanged="SetCurrPage" totalCount="@totalCount" showLoading="@isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -25,12 +25,6 @@ namespace SHERPA.AD.Pages
|
||||
|
||||
protected List<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
</button>
|
||||
</h2>
|
||||
<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 class="accordion-item">
|
||||
|
||||
@@ -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<vSelTipoModel> ListSelTipo { get; set; } = new List<vSelTipoModel>();
|
||||
|
||||
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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -43,13 +43,6 @@ builder.Services.Configure<MailKitEmailSenderOptions>(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();
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>1.0.2303.0219</Version>
|
||||
<Version>1.0.2306.3016</Version>
|
||||
<Copyright>Egalware 2021+</Copyright>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -29,9 +30,9 @@
|
||||
<PackageReference Include="It.FattureInCloud.Sdk" Version="2.0.18" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" 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="StackExchange.Redis" Version="2.6.90" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.6.111" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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;"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;"
|
||||
},
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.13" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" 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>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<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
|
||||
|
||||
public BBM_EFService(IConfiguration configuration, ILogger<BBM_EFService> logger)
|
||||
public BBM_EFService(IConfiguration configuration, ILogger<BBM_EFService> 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());
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
try
|
||||
@@ -463,29 +467,164 @@ namespace SHERPA.BBM.UI.Data
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@@ -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
|
||||
|
||||
/// <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
|
||||
}
|
||||
}
|
||||
@@ -39,41 +39,6 @@
|
||||
<div class="card mb-2">
|
||||
<div class="card-header table-primary h3">@anno</div>
|
||||
<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="col border rounded px-0 mx-2">
|
||||
<div class="d-flex justify-content-between">
|
||||
@@ -99,6 +64,7 @@
|
||||
</div>
|
||||
<div class="px-2 flex-fill h3 text-right">
|
||||
<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>
|
||||
@@ -112,6 +78,7 @@
|
||||
</div>
|
||||
<div class="px-2 flex-fill h3 text-right">
|
||||
<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>
|
||||
@@ -125,6 +92,7 @@
|
||||
</div>
|
||||
<div class="px-2 flex-fill h3 text-right">
|
||||
<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>
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace SHERPA.BBM.UI.Pages
|
||||
{
|
||||
#region Protected Methods
|
||||
|
||||
protected async Task<double> getDraft(int anno)
|
||||
protected async Task<decimal> 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<double> getOrdinato(int anno)
|
||||
protected async Task<decimal> 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<double> getTrattato(int anno)
|
||||
protected async Task<decimal> 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; }
|
||||
|
||||
+99
-46
@@ -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
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
#region Public Methods
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
})
|
||||
.ConfigureLogging(logging =>
|
||||
{
|
||||
logging.ClearProviders();
|
||||
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||
})
|
||||
.UseNLog();
|
||||
// Add services to the container.
|
||||
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
|
||||
.AddNegotiate();
|
||||
|
||||
public static void Main(string[] args)
|
||||
builder.Services.AddAuthorization(options =>
|
||||
{
|
||||
// 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
|
||||
// By default, all incoming requests will be authorized according to the default policy.
|
||||
options.FallbackPolicy = options.DefaultPolicy;
|
||||
});
|
||||
|
||||
// configuration setup
|
||||
ConfigurationManager configuration = builder.Configuration;
|
||||
|
||||
// REDIS setup
|
||||
string connStringRedis = configuration.GetConnectionString("Redis");
|
||||
string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
|
||||
// avvio oggetto shared x redis...
|
||||
var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis);
|
||||
|
||||
// abilitazione x email management con MailKit
|
||||
builder.Services.AddTransient<IEmailSender, MailKitEmailSender>();
|
||||
builder.Services.Configure<MailKitEmailSenderOptions>(options =>
|
||||
{
|
||||
logger.Info("BBM Application Starting Up");
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
catch (Exception exception)
|
||||
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())
|
||||
{
|
||||
logger.Error(exception, "Stopped BBM program because of exception");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
NLog.LogManager.Shutdown();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<UserSecretsId>60fcdaab-6c1e-4bec-9d88-f7727ef1c12c</UserSecretsId>
|
||||
<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>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -155,22 +158,29 @@
|
||||
</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.Common" Version="2.1.2" />
|
||||
<PackageReference Include="ElmahCore.Sql" Version="2.1.2" />
|
||||
<PackageReference Include="EntityFramework" Version="6.4.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.2">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="6.0.13" />
|
||||
<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>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<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.Data.SqlClient" Version="4.8.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SHERPA.BBM.CORE\SHERPA.BBM.CORE.csproj" />
|
||||
<ProjectReference Include="..\SHERPA.Data\SHERPA.Data.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,7 +315,7 @@ namespace SHERPA.Data.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Customers possono essere eliminati (NIENTE doc collegati)
|
||||
/// Elenco Customers che possono essere eliminati (NIENTE doc collegati)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<CustomerModel> CustomersDeletable()
|
||||
@@ -720,6 +720,90 @@ namespace SHERPA.Data.Controllers
|
||||
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>
|
||||
/// Elenco VAT / CIva
|
||||
/// </summary>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NLog" Version="5.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<IISExpressSSLPort />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<LastActiveSolutionConfig>Release|Any CPU</LastActiveSolutionConfig>
|
||||
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
|
||||
Reference in New Issue
Block a user