5d835509c1
- Update x display SOLO dei tipoDoc x FIC (no fatturare, fgurative...)
468 lines
16 KiB
C#
468 lines
16 KiB
C#
using It.FattureInCloud.Sdk.Model;
|
|
using Microsoft.AspNetCore.Components;
|
|
using SHERPA.AD.Data;
|
|
using SHERPA.Data;
|
|
using SHERPA.Data.DbModels;
|
|
using SHERPA.Data.Services;
|
|
|
|
namespace SHERPA.AD.Components
|
|
{
|
|
public partial class AccDocManager
|
|
{
|
|
#region Public Properties
|
|
|
|
[Parameter]
|
|
public bool CloudEnab { get; set; } = false;
|
|
|
|
[Parameter]
|
|
public SelectDocExp CurrFilter { get; set; } = new SelectDocExp();
|
|
|
|
[Parameter]
|
|
public int CurrPage { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<vDocsExplModel?> DocSelected { get; set; }
|
|
|
|
[Parameter]
|
|
public bool EditEnab { get; set; } = false;
|
|
|
|
[Parameter]
|
|
public EventCallback<SelectDocExp> FiltUpdated { get; set; }
|
|
|
|
[Parameter]
|
|
public int NumRecord { get; set; } = 10;
|
|
|
|
[Parameter]
|
|
public EventCallback<bool> PagerResetReq { get; set; }
|
|
|
|
[Parameter]
|
|
public bool SelEnab { get; set; } = false;
|
|
|
|
[Parameter]
|
|
public bool ShowCosti { get; set; } = false;
|
|
|
|
[Parameter]
|
|
public bool ShowPagamenti { get; set; } = true;
|
|
|
|
[Parameter]
|
|
public bool ShowOnlySync { get; set; } = false;
|
|
|
|
[Parameter]
|
|
public EventCallback<int> UpdateCount { get; set; }
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Protected Properties
|
|
|
|
[Inject]
|
|
protected MessageService AppMServ { get; set; } = null!;
|
|
|
|
protected bool IsLoading { get; set; }
|
|
protected bool IsSynching { get; set; }
|
|
protected int lastCurrPage { get; set; } = 1;
|
|
protected SelectDocExp LastFilter { get; set; } = new SelectDocExp();
|
|
protected int lastNumRecord { get; set; } = 10;
|
|
protected List<vDocsExplModel>? ListRecords { get; set; } = null;
|
|
|
|
protected string modalCss { get; set; } = "alert alert-success";
|
|
|
|
protected string modalMessage { get; set; } = "";
|
|
|
|
[Inject]
|
|
protected MessageService MService { get; set; } = null!;
|
|
|
|
[Inject]
|
|
protected SADDataService SDService { get; set; } = null!;
|
|
|
|
protected List<vDocsExplModel>? SearchRecords { get; set; }
|
|
protected int totalCount { get; set; } = 0;
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Protected Methods
|
|
|
|
protected string checkSel(vDocsExplModel curItem)
|
|
{
|
|
string answ = "";
|
|
if (SelRecord != null)
|
|
{
|
|
answ = curItem.idxDoc == SelRecord.idxDoc ? "table-info" : "";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
protected async Task closeModal()
|
|
{
|
|
await Task.Delay(1);
|
|
IsSynching = false;
|
|
modalMessage = "";
|
|
modalCss = "alert alert-primary";
|
|
await ReloadData(true);
|
|
}
|
|
|
|
protected List<BarPlot.DataItem> ListaValCosti(vDocsExplModel selItem)
|
|
{
|
|
List<BarPlot.DataItem> answ = new List<BarPlot.DataItem>();
|
|
var totValue = (double)(selItem.netto);
|
|
// aggiungo gli items...
|
|
answ.Add(new BarPlot.DataItem()
|
|
{
|
|
Label = "Costi",
|
|
Value = (double)selItem.CostiAss,
|
|
MaxValue = (double)totValue,
|
|
Css = "bg-secondary",
|
|
Tooltip = $"Costi Assorbiti: {selItem.CostiAss:C2} / {totValue:C2}"
|
|
});
|
|
answ.Add(new BarPlot.DataItem()
|
|
{
|
|
Label = "Margin",
|
|
Value = (double)(selItem.netto - selItem.CostiAss),
|
|
MaxValue = (double)totValue,
|
|
Css = "bg-success",
|
|
Tooltip = $"Margin: {selItem.netto - selItem.CostiAss:C2} / {totValue:C2}"
|
|
});
|
|
return answ;
|
|
}
|
|
|
|
protected List<BarPlot.DataItem> ListaValPagamenti(vDocsExplModel selItem)
|
|
{
|
|
List<BarPlot.DataItem> answ = new List<BarPlot.DataItem>();
|
|
var totValue = (double)(selItem.totPagato + selItem.totScadenze);
|
|
// aggiungo gli items...
|
|
answ.Add(new BarPlot.DataItem()
|
|
{
|
|
Label = "Pagato",
|
|
Value = (double)selItem.totPagato,
|
|
MaxValue = (double)totValue,
|
|
Css = "bg-success",
|
|
Tooltip = $"Pagato: {selItem.totPagato:C2} / {totValue:C2}"
|
|
});
|
|
answ.Add(new BarPlot.DataItem()
|
|
{
|
|
Label = "Da Pagare",
|
|
Value = (double)selItem.totScadenze,
|
|
MaxValue = (double)totValue,
|
|
Css = "bg-danger",
|
|
Tooltip = $"Scadenze: {selItem.totScadenze:C2} / {totValue:C2}"
|
|
});
|
|
return answ;
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
// test token locale
|
|
var tokenData = await MService.getUserTokenAsync();
|
|
hasToken = tokenData != null;
|
|
}
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
LastFilter.Anno = -1;
|
|
}
|
|
|
|
protected override async Task OnParametersSetAsync()
|
|
{
|
|
await Task.Delay(1);
|
|
bool needReload = false;
|
|
var oldRec = SelRecord;
|
|
// verifico eventuali richieste di tenere record selezionato
|
|
bool keepSel = CurrFilter.KeepSelected;
|
|
//reset
|
|
CurrFilter.KeepSelected = false;
|
|
// verifica filtro
|
|
if (!LastFilter.Equals(CurrFilter))
|
|
{
|
|
LastFilter = CurrFilter.clone();
|
|
needReload = true;
|
|
}
|
|
// verifica pagina
|
|
if (lastCurrPage != CurrPage)
|
|
{
|
|
lastCurrPage = CurrPage;
|
|
needReload = true;
|
|
}
|
|
// verifica num record pagina
|
|
if (lastNumRecord != NumRecord)
|
|
{
|
|
lastNumRecord = NumRecord;
|
|
needReload = true;
|
|
}
|
|
// deve ricaricare?
|
|
if (needReload)
|
|
{
|
|
SelRecord = null;
|
|
await ReloadData(false);
|
|
if (keepSel)
|
|
{
|
|
SelRecord = oldRec;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected async Task ReloadData(bool setChanged)
|
|
{
|
|
IsLoading = true;
|
|
ListRecords = null;
|
|
await Task.Delay(1);
|
|
var allRec = await SDService.VDocExplGetFilt(CurrFilter);
|
|
// filtro secondo condizione sync cloud
|
|
if(ShowOnlySync)
|
|
{
|
|
allRec = allRec.Where(x => x.CanSync).ToList();
|
|
}
|
|
if (CurrFilter.OnlySync)
|
|
{
|
|
SearchRecords = allRec.Where(x => string.IsNullOrEmpty(x.id_ext) || (x.Changed > 0)).ToList();
|
|
}
|
|
else
|
|
{
|
|
SearchRecords = allRec;
|
|
}
|
|
totalCount = SearchRecords.Count;
|
|
ListRecords = SearchRecords.Skip(NumRecord * (CurrPage - 1)).Take(NumRecord).ToList();
|
|
await UpdateCount.InvokeAsync(totalCount);
|
|
await Task.Delay(1);
|
|
if (setChanged)
|
|
{
|
|
await InvokeAsync(() => StateHasChanged());
|
|
}
|
|
IsLoading = false;
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Private Properties
|
|
|
|
private bool hasToken
|
|
{
|
|
get => MService.hasToken;
|
|
set => MService.hasToken = value;
|
|
}
|
|
|
|
private vDocsExplModel? SelRecord { get; set; } = null;
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Private Methods
|
|
|
|
private async Task<ModelClient?> checkSyncClient(int idxCli)
|
|
{
|
|
ModelClient? foundRec = null;
|
|
// cerco codice cliente
|
|
CustomerModel? currItem = await SDService.CustomersGetByKey(idxCli);
|
|
if (currItem != null)
|
|
{
|
|
// prova a cercare il customer...
|
|
var (searchResult, cloudRecSearch) = await MService.cloudClientSearch(currItem);
|
|
// se ho trovato il record --> aggiorno sul DB
|
|
if (cloudRecSearch != null)
|
|
{
|
|
await cliUpdateDbRecord(currItem, cloudRecSearch);
|
|
foundRec = cloudRecSearch;
|
|
}
|
|
else
|
|
{
|
|
// se non trovato DEVO creare...
|
|
var (createResult, cloudRecCreate) = await MService.cloudClientCreate(currItem);
|
|
// se ho trovato il record --> aggiorno sul DB
|
|
if (cloudRecCreate != null)
|
|
{
|
|
await cliUpdateDbRecord(currItem, cloudRecCreate);
|
|
foundRec = cloudRecCreate;
|
|
}
|
|
}
|
|
}
|
|
return foundRec;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue update record su DB dai dati cloud (id Ext...)
|
|
/// </summary>
|
|
/// <param name="currItem"></param>
|
|
/// <param name="cloudRec"></param>
|
|
/// <returns></returns>
|
|
private async Task<bool> cliUpdateDbRecord(CustomerModel currItem, ModelClient cloudRec)
|
|
{
|
|
bool fatto = false;
|
|
currItem.IdExt = $"{cloudRec.Id}";
|
|
// salvo sul DB
|
|
fatto = await SDService.CustomerUpdate(currItem);
|
|
return fatto;
|
|
}
|
|
|
|
private async Task ResetSel()
|
|
{
|
|
SelRecord = null;
|
|
await DocSelected.InvokeAsync(null);
|
|
}
|
|
|
|
private void selCliente(vDocsExplModel selItem)
|
|
{
|
|
CurrFilter.IdxCli = selItem.idxCli;
|
|
FiltUpdated.InvokeAsync(CurrFilter);
|
|
}
|
|
|
|
private void selGruppo(vDocsExplModel selItem)
|
|
{
|
|
CurrFilter.IdxGruppo = selItem.idxGruppo;
|
|
FiltUpdated.InvokeAsync(CurrFilter);
|
|
}
|
|
|
|
private void selTipo(vDocsExplModel selItem)
|
|
{
|
|
CurrFilter.IdxTipo = selItem.IdxTipo;
|
|
FiltUpdated.InvokeAsync(CurrFilter);
|
|
}
|
|
|
|
private async Task showDetail(vDocsExplModel selItem)
|
|
{
|
|
SelRecord = selItem;
|
|
await DocSelected.InvokeAsync(selItem);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sincronizzazione di tutti i record che la richiedono
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private async Task syncAll()
|
|
{
|
|
IsSynching = true;
|
|
if (ListRecords != null)
|
|
{
|
|
// prendo elenco dei clienti NON in sync e processo 1:1
|
|
var data2sync = ListRecords.Where(x => string.IsNullOrEmpty(x.id_ext) || (x.Changed > 0)).ToList();
|
|
if (data2sync != null && data2sync.Count > 0)
|
|
{
|
|
foreach (var item in data2sync)
|
|
{
|
|
await syncCurrent(item);
|
|
}
|
|
}
|
|
}
|
|
IsSynching = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sincronizzazioner bidirezionale dati cliente locale e su cloud
|
|
/// </summary>
|
|
/// <param name="currItem"></param>
|
|
/// <returns></returns>
|
|
private async Task syncCurrent(vDocsExplModel currItem)
|
|
{
|
|
bool closeModal = false;
|
|
modalMessage = "";
|
|
modalCss = "alert alert-primary";
|
|
IsSynching = true;
|
|
// in primis verifico sync dati cliente
|
|
var currCust = await checkSyncClient(currItem.idxCli);
|
|
if (currCust != null)
|
|
{
|
|
// recupero doc (vengo da versione expl...)
|
|
var (searchResult, cloudRec) = await MService.cloudDocSearch(currItem);
|
|
// verifico sia avvenuto con successo..
|
|
if (!searchResult.success)
|
|
{
|
|
modalCss = "alert alert-danger";
|
|
modalMessage = $"Errore in fase di ricerca: {searchResult.message}";
|
|
if (!string.IsNullOrEmpty(searchResult.description))
|
|
{
|
|
modalMessage += $" | {searchResult.description}";
|
|
}
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
else
|
|
{
|
|
// recupero righe....
|
|
List<RigheFattModel> righeDoc = new List<RigheFattModel>();
|
|
var currAccDoc = await SDService.AccoDocGetByKey(currItem.idxDoc);
|
|
if (currAccDoc != null)
|
|
{
|
|
righeDoc = currAccDoc.RigheFattNav.ToList();
|
|
}
|
|
// se ho trovato il record e mi mancasse in locale--> aggiorno sul DB
|
|
if (cloudRec != null)
|
|
{
|
|
int cloudDocId = cloudRec.Id ?? 0;
|
|
// carico come aggiornamento
|
|
var (addResult, updCloudRec) = await MService.cloudDocUpdate(currItem, currCust, righeDoc, cloudDocId);
|
|
// verifico sia avvenuto con successo..
|
|
if (!addResult.success)
|
|
{
|
|
modalCss = "alert alert-danger";
|
|
modalMessage = $"Errore in fase di update record remoto: {addResult.message}";
|
|
if (!string.IsNullOrEmpty(addResult.description))
|
|
{
|
|
modalMessage += $" | {addResult.description}";
|
|
}
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
else
|
|
{
|
|
// infine --> aggiorno sul DB
|
|
if (updCloudRec != null)
|
|
{
|
|
await updateDbRecord(currItem, updCloudRec);
|
|
closeModal = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// se non trovato DEVO creare...
|
|
var (addResult, newCloudRec) = await MService.cloudDocCreate(currItem, currCust, righeDoc);
|
|
// infine --> aggiorno sul DB verifico sia avvenuto con successo..
|
|
if (!addResult.success)
|
|
{
|
|
modalCss = "alert alert-danger";
|
|
modalMessage = $"Errore in fase di creazione record remoto: {addResult.message}";
|
|
if (!string.IsNullOrEmpty(addResult.description))
|
|
{
|
|
modalMessage += $" | {addResult.description}";
|
|
}
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
else
|
|
{
|
|
if (newCloudRec != null)
|
|
{
|
|
await updateDbRecord(currItem, newCloudRec);
|
|
closeModal = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (closeModal)
|
|
{
|
|
await Task.Delay(1);
|
|
IsSynching = false;
|
|
await ReloadData(true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue update record su DB dai dati cloud (id Ext...)
|
|
/// </summary>
|
|
/// <param name="currItem"></param>
|
|
/// <param name="cloudRec"></param>
|
|
/// <returns></returns>
|
|
private async Task<bool> updateDbRecord(vDocsExplModel currItem, IssuedDocument cloudRec)
|
|
{
|
|
bool fatto = false;
|
|
var currAccDoc = await SDService.AccoDocGetByKey(currItem.idxDoc);
|
|
if (currAccDoc != null)
|
|
{
|
|
currAccDoc.Token = $"{cloudRec.Id}";
|
|
currAccDoc.NewId = $"{cloudRec.Id}";
|
|
currAccDoc.DtEvent = DateTime.Now;
|
|
// reset del campo "modificato"
|
|
currAccDoc.Changed = 0;
|
|
// salvo sul DB
|
|
fatto = await SDService.AccDocUpdate(currAccDoc);
|
|
}
|
|
return fatto;
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |