1650 lines
73 KiB
C#
1650 lines
73 KiB
C#
using EgtBEAMWALL.DataLayer.DatabaseModels;
|
|
using EgwProxy.MagMan;
|
|
using EgwProxy.MagMan.DTO;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace EgtBEAMWALL.DataLayer.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Gestione Sync MagMan (DB locale/online)
|
|
/// </summary>
|
|
public class MagmanController : IDisposable
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Init controller gestione MagmanSync
|
|
/// </summary>
|
|
/// <param name="serverUrl">URL del server</param>
|
|
/// <param name="authToken">Token di autorizzazione</param>
|
|
public MagmanController(string ServerAddress, string AuthToken)
|
|
{
|
|
commLib = new DataSyncro(ServerAddress, AuthToken);
|
|
bool servOk = commLib.CheckRemote();
|
|
Log.Info($"Avviato MagmanController | server: {ServerAddress} | timeout: standard (500ms)| CheckRemote OK: {servOk}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Init controller gestione MagmanSync
|
|
/// </summary>
|
|
/// <param name="serverUrl">URL del server</param>
|
|
/// <param name="authToken">Token di autorizzazione</param>
|
|
/// <param name="timeout">Timeout chiamate in ms</param>
|
|
public MagmanController(string ServerAddress, string AuthToken, int timeout)
|
|
{
|
|
commLib = new DataSyncro(ServerAddress, AuthToken, timeout);
|
|
bool servOk = commLib.CheckRemote();
|
|
Log.Info($"Avviato MagmanController | server: {ServerAddress} | timeout: {timeout}ms | CheckRemote OK: {servOk}");
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Enums
|
|
|
|
/// <summary>
|
|
/// Enum del risultato della sincronizzazione
|
|
/// 0: ALL_OK
|
|
/// </summary>
|
|
public enum SyncResult
|
|
{
|
|
ALL_OK = 0,
|
|
ERR_ND,
|
|
ERR_ServerKo,
|
|
ERR_CloudMatNotSent,
|
|
ERR_CloudResNotSent,
|
|
ERR_SrcMatNotFound,
|
|
ERR_MergeMatEmpty,
|
|
ERR_CloudMatEmpty,
|
|
ERR_Res2SendEmpty,
|
|
ERR_InvSendError,
|
|
ERR_AliasMatEmpty,
|
|
ERR_CloudAliasNotSent,
|
|
ERR_ProjIdNotFound,
|
|
ERR_ProjNotSync,
|
|
RES_CheckChanged,
|
|
RES_CheckEqual,
|
|
RES_CheckND,
|
|
ERR_AllProjSyncUncomplete,
|
|
ERR_LogMaccSyncUncomplete
|
|
}
|
|
|
|
#endregion Public Enums
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Esegue sync Alias:
|
|
/// - download + sync (locale)
|
|
/// - upload + sync (cloud)
|
|
/// </summary>
|
|
/// <returns>Risultato sincronizzazione</returns>
|
|
public SyncResult AliasSyncro()
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (AliasController dbContr = new AliasController())
|
|
{
|
|
try
|
|
{
|
|
List<AliasDTO> list2merge = commLib.AliasGet();
|
|
// 2024.04.04 effettuo conversione DTO --> model + merge x attivi
|
|
List<AliasModel> list2MergeDb = list2merge.Where(x => x.IsActive).Select(x => AliasController.ConvToModel(x, "MatCode")).ToList();
|
|
// 2024.04.04 prendo quelli con cancellazione logica che devo poi eliminare
|
|
// in locale...
|
|
List<AliasModel> list2DeleteDb = list2merge.Where(x => x.IsActive == false).Select(x => AliasController.ConvToModel(x, "MatCode")).ToList();
|
|
// ciclo...
|
|
if (list2MergeDb == null)
|
|
{
|
|
answ = SyncResult.ERR_AliasMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
// inizio con eventuale eliminazione...
|
|
var deleteOk = dbContr.DeleteList(list2DeleteDb);
|
|
// ora merge
|
|
var updateOk = dbContr.UpsertList(list2MergeDb);
|
|
if (updateOk || deleteOk)
|
|
{
|
|
// in primis leggo l'elenco materiali dal DB locale
|
|
List<AliasModel> listDb = dbContr.GetFilt("MatCode");
|
|
List<AliasDTO> list2send = listDb.Select(x => AliasController.ConvToDto(x)).ToList();
|
|
// preparo pacchetto invio...
|
|
bool okMat = commLib.AliasSend(list2send);
|
|
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudAliasNotSent;
|
|
}
|
|
else
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync Alias in modalità asincrona:
|
|
/// - download + sync (locale)
|
|
/// - upload + sync (cloud)
|
|
/// </summary>
|
|
/// <param name="MatCode">Se "" esegue per tutti, altrimenti limitatamente al MatCode cercato</param>
|
|
/// <returns>Risultato sincronizzazione</returns>
|
|
public async Task<SyncResult> AliasSyncroAsync()
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (AliasController dbContr = new AliasController())
|
|
{
|
|
try
|
|
{
|
|
List<AliasDTO> list2merge = await commLib.AliasGetAsync();
|
|
// 2024.04.04 effettuo conversione DTO --> model + merge x attivi
|
|
List<AliasModel> list2MergeDb = list2merge.Where(x => x.IsActive).Select(x => AliasController.ConvToModel(x, "MatCode")).ToList();
|
|
// 2024.04.04 prendo quelli con cancellazione logica che devo poi eliminare
|
|
// in locale...
|
|
List<AliasModel> list2DeleteDb = list2merge.Where(x => x.IsActive == false).Select(x => AliasController.ConvToModel(x, "MatCode")).ToList();
|
|
// ciclo...
|
|
if (list2merge == null)
|
|
{
|
|
answ = SyncResult.ERR_AliasMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
// inizio con eventuale eliminazione...
|
|
var deleteOk = dbContr.DeleteList(list2DeleteDb);
|
|
// ora merge
|
|
var updateOk = dbContr.UpsertList(list2MergeDb);
|
|
if (updateOk || deleteOk)
|
|
{
|
|
// in primis leggo l'elenco materiali dal DB locale
|
|
List<AliasModel> listDb = dbContr.GetFilt("MatCode");
|
|
List<AliasDTO> list2send = listDb.Select(x => AliasController.ConvToDto(x)).ToList();
|
|
// preparo pacchetto invio...
|
|
bool okMat = await commLib.AliasSendAsync(list2send);
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudAliasNotSent;
|
|
}
|
|
else
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync dei dati LogMacchina su cloud:
|
|
/// - upload
|
|
/// - cicla secondo parametri indicati
|
|
/// </summary>
|
|
/// <param name="batchSize">num record da inviare in ogni singolo batch (std: 50)</param>
|
|
/// <param name="num2send">num max di record da inviare (std: 1000)</param>
|
|
/// <returns></returns>
|
|
public SyncResult CloudLogMaccSyncro(int batchSize = 50, int num2send = 1000)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
int numSent = 0;
|
|
using (LogMachineController lmDbContr = new LogMachineController())
|
|
{
|
|
bool okSend = false;
|
|
// elenco record da inviare...
|
|
List<LogMachineModel> recList = lmDbContr.GetUnsentAsc(num2send);
|
|
// controllo ci sia qulcosa da inviare...
|
|
if (recList.Count > 0)
|
|
{
|
|
// fintanto che ce ne sono procedo...
|
|
while (numSent < num2send)
|
|
{
|
|
var currList = recList
|
|
.Skip(numSent)
|
|
.Take(batchSize)
|
|
.ToList();
|
|
// converto il blocco
|
|
var listDto = currList
|
|
.Select(x => LogMachineController.ConvToItemDto(x))
|
|
.ToList();
|
|
// invio!
|
|
okSend = commLib.LogMachineSend(listDto);
|
|
if (okSend)
|
|
{
|
|
// registro dati inviati...
|
|
lmDbContr.SetDtSent(currList);
|
|
Log.Info($"Inviati {batchSize}rec | {numSent} --> {numSent + batchSize}");
|
|
numSent += batchSize;
|
|
}
|
|
// altrimenti esco con errore...
|
|
else
|
|
{
|
|
Log.Info($"Errore in invio: {batchSize}rec | inviati {numSent} di {recList.Count}");
|
|
// registro errore
|
|
answ = SyncResult.ERR_LogMaccSyncUncomplete;
|
|
// condizione uscita
|
|
numSent = num2send + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync dei CloudId x Materiali e RawItems:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="ForceAll">
|
|
/// true = Indica di forzare il sync di tutto, false = SOLAMENTE per i nuovi materiali (MatCloudId==0)
|
|
/// </param>
|
|
/// <param name="SyncQty">True: sincronizza quantità, False = NON sincronizza quantità</param>
|
|
/// <param name="BlockSend">
|
|
/// True: effettua 1 sola chiamata upload e 1 sola download per il sync
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public SyncResult CloudSyncro(bool ForceAll, bool SyncQty, bool BlockSend)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
List<int> MatIdList = new List<int>();
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController matDbContr = new MaterialsController())
|
|
{
|
|
// elenco materiali (completo)
|
|
var matListDb = matDbContr.GetFiltModel("");
|
|
if (matListDb == null)
|
|
{
|
|
answ = SyncResult.ERR_SrcMatNotFound;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// se non è forzato a tutti --> filtro solo quelli nuovi
|
|
if (!ForceAll)
|
|
{
|
|
matListDb = matListDb.Where(x => x.MatCloudId == 0).ToList();
|
|
}
|
|
// eseguo il sync!
|
|
List<MaterialDTO> list2send = matListDb.Select(x => MaterialsController.ConvToDto(x)).ToList();
|
|
// preparo pacchetto invio...
|
|
bool okMat = commLib.MaterialsSend(list2send);
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudMatNotSent;
|
|
}
|
|
else
|
|
{
|
|
// recupero elenco materiali (ALL)
|
|
List<MaterialDTO> list2merge = commLib.MaterialsGet();
|
|
// effettuo conversione DTO --> model + merge
|
|
List<MaterialModel> list2MergeDb = list2merge.Select(x => MaterialsController.ConvToModel(x)).ToList();
|
|
// ciclo...
|
|
if (list2MergeDb == null)
|
|
{
|
|
answ = SyncResult.ERR_MergeMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
int numOk = 0;
|
|
int num2Write = list2MergeDb.Count();
|
|
foreach (var item in list2MergeDb)
|
|
{
|
|
var newId = matDbContr.Upsert(item);
|
|
if (newId > 0)
|
|
{
|
|
numOk++;
|
|
// aggiungo ID x successivo sync dei RawItems del materiale...
|
|
MatIdList.Add(newId);
|
|
}
|
|
}
|
|
// se non fosse tutto ok --> loggo
|
|
if (num2Write != numOk)
|
|
{
|
|
Log.Error($"Errore sync Materiali | num2Write: {num2Write} | numOk: {numOk}");
|
|
}
|
|
else
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
// eseguo sync dell'elenco RawItems
|
|
answ = ResourcesSync(MatIdList, SyncQty, BlockSend);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
commLib = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Forza sincronizzazione invii non completati...
|
|
/// </summary>
|
|
/// <returns>Restituisce esito resync, ALL OK solo se ha fatto tutti gli invii necessari</returns>
|
|
public SyncResult ForceSyncroSend()
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
ProjResState projType = ProjResState.Consumed;
|
|
// recupero da DB eventuale elenco dati da sincronizzare
|
|
using (MagmanSyncController msContr = new MagmanSyncController())
|
|
{
|
|
var list2resend = msContr.GetUnsentFilt("", DateTime.Now.AddDays(1), 1000);
|
|
if (list2resend == null || list2resend.Count == 0)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
else
|
|
{
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// eseguo re-invio 1:1...
|
|
List<ResourceDTO> list2send = new List<ResourceDTO>();
|
|
foreach (var record in list2resend)
|
|
{
|
|
list2send = JsonConvert.DeserializeObject<List<ResourceDTO>>(record.Payload);
|
|
if (Enum.TryParse(record.SyncType, out projType))
|
|
{
|
|
// effettuo invio...
|
|
bool resOk = commLib.ResourceSend(record.CloudId, projType, record.DtReq, list2send);
|
|
if (!resOk)
|
|
{
|
|
answ = SyncResult.ERR_CloudResNotSent;
|
|
}
|
|
else
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
// registro su DB dataora conclusione invio
|
|
msContr.SetCompleted(record.SyncId, DateTime.Now);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync Materiale:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="MatId">Id LOCALE del materiale da sincronizzare</param>
|
|
/// <returns></returns>
|
|
public SyncResult MaterialsSyncro(int MatId)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController matDbContr = new MaterialsController())
|
|
{
|
|
// elenco materiali (completo)
|
|
var matRecord = matDbContr.FindByDbIdModel(MatId);
|
|
if (matRecord == null)
|
|
{
|
|
answ = SyncResult.ERR_SrcMatNotFound;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// eseguo il sync!
|
|
List<MaterialDTO> list2send = new List<MaterialDTO>() { MaterialsController.ConvToDto(matRecord) };
|
|
// preparo pacchetto invio...
|
|
bool okMat = commLib.MaterialsSend(list2send);
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudMatNotSent;
|
|
}
|
|
else
|
|
{
|
|
// recupero elenco materiali (ALL)
|
|
List<MaterialDTO> list2merge = commLib.MaterialsGet();
|
|
// effettuo conversione DTO --> model + merge
|
|
List<MaterialModel> list2MergeDb = list2merge.Select(x => MaterialsController.ConvToModel(x)).ToList();
|
|
// ciclo...
|
|
if (list2MergeDb == null)
|
|
{
|
|
answ = SyncResult.ERR_MergeMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
int numOk = 0;
|
|
int num2Write = list2MergeDb.Count();
|
|
foreach (var item in list2MergeDb)
|
|
{
|
|
var newId = matDbContr.Upsert(item);
|
|
if (newId > 0)
|
|
{
|
|
numOk++;
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (num2Write == numOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync Materiali:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="onlyNew">Indica di forzare il sync SOLAMENTE per i nuovi materiali (MatCloudId==0)</param>
|
|
/// <returns></returns>
|
|
[Obsolete("MaterialsSyncro is deprecated, please use CloudSyncro", true)]
|
|
public SyncResult MaterialsSyncro(bool onlyNew)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController matDbContr = new MaterialsController())
|
|
{
|
|
// elenco materiali (completo)
|
|
var matListDb = matDbContr.GetFiltModel("");
|
|
if (matListDb == null)
|
|
{
|
|
answ = SyncResult.ERR_SrcMatNotFound;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// se non è forzato a tutti --> filtro solo quelli nuovi
|
|
if (onlyNew)
|
|
{
|
|
matListDb = matListDb.Where(x => x.MatCloudId == 0).ToList();
|
|
}
|
|
// eseguo il sync!
|
|
List<MaterialDTO> list2send = matListDb.Select(x => MaterialsController.ConvToDto(x)).ToList();
|
|
// preparo pacchetto invio...
|
|
bool okMat = commLib.MaterialsSend(list2send);
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudMatNotSent;
|
|
}
|
|
else
|
|
{
|
|
// recupero elenco materiali (ALL)
|
|
List<MaterialDTO> list2merge = commLib.MaterialsGet();
|
|
// effettuo conversione DTO --> model + merge
|
|
List<MaterialModel> list2MergeDb = list2merge.Select(x => MaterialsController.ConvToModel(x)).ToList();
|
|
// ciclo...
|
|
if (list2MergeDb == null)
|
|
{
|
|
answ = SyncResult.ERR_MergeMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
int numOk = 0;
|
|
int num2Write = list2MergeDb.Count();
|
|
foreach (var item in list2MergeDb)
|
|
{
|
|
var newId = matDbContr.Upsert(item);
|
|
if (newId > 0)
|
|
{
|
|
numOk++;
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (num2Write == numOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync materiali:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="MatCode">Se "" esegue per tutti, altrimenti limitatamente al MatCode cercato</param>
|
|
/// <returns>Risultato sincronizzazione</returns>
|
|
[Obsolete("MaterialsSyncro is deprecated, please use CloudSyncro", true)]
|
|
public SyncResult MaterialsSyncro(string MatCode = "")
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController dbContr = new MaterialsController())
|
|
{
|
|
// in primis leggo l'elenco materiali dal DB locale
|
|
List<MaterialModel> matListDb = dbContr.GetFiltModel(MatCode);
|
|
if (matListDb == null)
|
|
{
|
|
answ = SyncResult.ERR_SrcMatNotFound;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
List<MaterialDTO> list2send = matListDb.Select(x => MaterialsController.ConvToDto(x)).ToList();
|
|
// preparo pacchetto invio...
|
|
bool okMat = commLib.MaterialsSend(list2send);
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudMatNotSent;
|
|
}
|
|
else
|
|
{
|
|
List<MaterialDTO> list2merge = commLib.MaterialsGet();
|
|
// se filtro x materiale processo solo quello...
|
|
if (!string.IsNullOrEmpty(MatCode))
|
|
{
|
|
list2merge = list2merge.Where(x => x.MatCode == MatCode).ToList();
|
|
}
|
|
// effettuo conversione DTO --> model + merge
|
|
List<MaterialModel> list2MergeDb = list2merge.Select(x => MaterialsController.ConvToModel(x)).ToList();
|
|
// ciclo...
|
|
if (list2MergeDb == null)
|
|
{
|
|
answ = SyncResult.ERR_MergeMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
int numOk = 0;
|
|
int num2Write = list2MergeDb.Count();
|
|
foreach (var item in list2MergeDb)
|
|
{
|
|
var newId = dbContr.Upsert(item);
|
|
if (newId > 0)
|
|
{
|
|
numOk++;
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (num2Write == numOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync materiali in modalità asincrona:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="MatCode">Se "" esegue per tutti, altrimenti limitatamente al MatCode cercato</param>
|
|
/// <returns>Risultato sincronizzazione</returns>
|
|
[Obsolete("MaterialsSyncro is deprecated, please use CloudSyncro", true)]
|
|
public async Task<SyncResult> MaterialsSyncroAsync(string MatCode = "")
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController dbContr = new MaterialsController())
|
|
{
|
|
// in primis leggo l'elenco materiali dal DB locale
|
|
List<MaterialModel> matListDb = dbContr.GetFiltModel(MatCode);
|
|
if (matListDb == null)
|
|
{
|
|
answ = SyncResult.ERR_SrcMatNotFound;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
List<MaterialDTO> list2send = matListDb.Select(x => MaterialsController.ConvToDto(x)).ToList();
|
|
// preparo pacchetto invio...
|
|
bool okMat = await commLib.MaterialsSendAsync(list2send);
|
|
// se inviato, scarico x merge locale
|
|
if (!okMat)
|
|
{
|
|
answ = SyncResult.ERR_CloudMatNotSent;
|
|
}
|
|
else
|
|
{
|
|
List<MaterialDTO> list2merge = await commLib.MaterialsGetAsync();
|
|
// se filtro x materiale processo solo quello...
|
|
if (!string.IsNullOrEmpty(MatCode))
|
|
{
|
|
list2merge = list2merge.Where(x => x.MatCode == MatCode).ToList();
|
|
}
|
|
// effettuo conversione DTO --> model + merge
|
|
List<MaterialModel> list2MergeDb = list2merge.Select(x => MaterialsController.ConvToModel(x)).ToList();
|
|
// ciclo...
|
|
if (list2MergeDb == null)
|
|
{
|
|
answ = SyncResult.ERR_MergeMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
int numOk = 0;
|
|
int num2Write = list2MergeDb.Count();
|
|
foreach (var item in list2MergeDb)
|
|
{
|
|
var newId = dbContr.Upsert(item);
|
|
if (newId > 0)
|
|
{
|
|
numOk++;
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (num2Write == numOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync dei dati PROJ su cloud (se NON sincronizzati):
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SyncResult ProjAllSyncro()
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
int numSent = 0;
|
|
using (ProdController lmDbContr = new ProdController())
|
|
{
|
|
bool syncEnabled = true;
|
|
// elenco record da inviare...
|
|
List<ProdModel> recList = lmDbContr.GetUnsentAsc();
|
|
// controllo ci sia qulcosa da inviare...
|
|
if (recList.Count > 0)
|
|
{
|
|
foreach (var item in recList)
|
|
{
|
|
if (syncEnabled)
|
|
{
|
|
answ = ProjSyncro(item.ProdId);
|
|
if (answ != SyncResult.ALL_OK)
|
|
{
|
|
// disabilito altri sync
|
|
syncEnabled = false;
|
|
// loggo
|
|
Log.Error($"ProjAllSyncro | Errore in sincornizzazione progetto: prodId: {item.ProdId} | prodDbId: {item.ProdDbId} record");
|
|
// salvo errore
|
|
answ = SyncResult.ERR_AllProjSyncUncomplete;
|
|
}
|
|
else
|
|
{
|
|
numSent++;
|
|
}
|
|
}
|
|
}
|
|
// loggo completato
|
|
Log.Info($"ProjAllSyncro | Eseguita sincronizzazione di {numSent}/{recList.Count} record");
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync di un SINGOLO PROD (cloud proj):
|
|
/// - legge il progetto locale + upload x sync (verso cloud)
|
|
/// - riceve ID cloud e aggiorna in locale...
|
|
/// </summary>
|
|
/// <param name="ProdId">Id del Prod da sincronizzare (invio dati con eventuale fix ProjCloudId)</param>
|
|
/// <returns>Risultato sincronizzazione</returns>
|
|
public SyncResult ProjSyncro(int ProdId)
|
|
{
|
|
int cloudId = 0;
|
|
SyncResult answ = ProjSyncro(ProdId, ref cloudId);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync di un SINGOLO PROD (cloud proj):
|
|
/// - legge il progetto locale + upload x sync (verso cloud)
|
|
/// - riceve ID cloud e aggiorna in locale...
|
|
/// </summary>
|
|
/// <param name="ProdId">Id del Prod da sincronizzare (invio dati con eventuale fix ProjCloudId)</param>
|
|
/// <param name="ProjCloudId">
|
|
/// Id del Prod in rete (eventualmente creato) che verrà RESTITUITO x reference
|
|
/// </param>
|
|
/// <returns>Risultato sincronizzazione</returns>
|
|
public SyncResult ProjSyncro(int ProdId, ref int ProjCloudId)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (ProdController dbContr = new ProdController())
|
|
{
|
|
// in primis recupero item
|
|
var currRec = dbContr.FindByProdId(ProdId);
|
|
if (currRec == null)
|
|
{
|
|
answ = SyncResult.ERR_ProjIdNotFound;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// preparo obj da inviare...
|
|
var projDto = ProdController.ConvToDto(currRec);
|
|
// invio e recupero ID...
|
|
ProjCloudId = commLib.ProjectSend(projDto);
|
|
// se inviato, faccio upgrade locale...
|
|
if (ProjCloudId == 0)
|
|
{
|
|
answ = SyncResult.ERR_ProjNotSync;
|
|
}
|
|
else
|
|
{
|
|
// verifico SE SIA da scrivere cloud ID...
|
|
if (ProjCloudId != currRec.ProjCloudId)
|
|
{
|
|
dbContr.UpdateCloudId(ProdId, ProjCloudId);
|
|
}
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue registrazione Risorse (RawItems) come CONSUMI effettivi:
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">
|
|
/// Elenco RawPart come dizionario quantità consumate [nId, qty]. nID = id del db LOCALE
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public SyncResult ResourceSendCons(int ProjCloudId, Dictionary<int, int> rec2send)
|
|
{
|
|
SyncResult answ = ResourceSendTrack(ProjCloudId, rec2send, ProjResState.Consumed, -1);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue registrazione Risorse (RawItems) come CONSUMI effettivi, versione ASYNC:
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">
|
|
/// Elenco RawPart come dizionario quantità consumate [nId, qty]. nID = id del db LOCALE
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public async Task<SyncResult> ResourceSendConsAsync(int ProjCloudId, Dictionary<int, int> rec2send)
|
|
{
|
|
SyncResult answ = await ResourceSendTrackAsync(ProjCloudId, rec2send, ProjResState.Consumed, -1);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue registrazione Risorse (RawItems) come stima:
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">
|
|
/// Elenco RawPart come dizionario quantità consumate [nId, qty]. nID = id del db LOCALE
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public SyncResult ResourceSendEstimate(int ProjCloudId, Dictionary<int, int> rec2send)
|
|
{
|
|
SyncResult answ = ResourceSendTrack(ProjCloudId, rec2send, ProjResState.Estimated, 1);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue registrazione Risorse (RawItems) come stima, versione ASYNC:
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">
|
|
/// Elenco RawPart come dizionario quantità consumate [nId, qty]. nID = id del db LOCALE
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public async Task<SyncResult> ResourceSendEstimateAsync(int ProjCloudId, Dictionary<int, int> rec2send)
|
|
{
|
|
SyncResult answ = await ResourceSendTrackAsync(ProjCloudId, rec2send, ProjResState.Estimated, 1);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync forzato risorse (Materiali + RawItem):
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SyncResult ResourcesForceSyncAll()
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController matDbContr = new MaterialsController())
|
|
{
|
|
using (RawItemsController rawItemDbContr = new RawItemsController())
|
|
{
|
|
// elenco di tutti i materiali
|
|
var matListAll = commLib.MaterialsGet();
|
|
if (matListAll == null || matListAll.Count == 0)
|
|
{
|
|
answ = SyncResult.ERR_CloudMatEmpty;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
int numMatOk = 0;
|
|
int numMat2Write = 0;
|
|
// ciclo 1:1 materiali + inventario
|
|
foreach (var mat in matListAll)
|
|
{
|
|
List<MaterialDTO> list2merge = commLib.InventoryGet(mat.MatCloudId);
|
|
// ciclo sui materiali...
|
|
if (list2merge != null)
|
|
{
|
|
numMat2Write += list2merge.Count();
|
|
foreach (var item in list2merge)
|
|
{
|
|
var newId = matDbContr.Insert(MaterialsController.ConvToModel(item));
|
|
if (newId > 0)
|
|
{
|
|
numMatOk++;
|
|
// ora processo 1:1 gli items...
|
|
foreach (var rawItem in item.ItemList)
|
|
{
|
|
rawItemDbContr.Upsert(RawItemsController.ConvToModel(rawItem, true), false, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (numMat2Write == numMatOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync risorse RawItem dato elenco MatId:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="MatIdList">
|
|
/// Elenco Id dei materiali (DB LOCALE): saranno inviati x sync (con quantità sovrascritta)
|
|
/// SOLO SE RawItemCloudId == 0
|
|
/// </param>
|
|
/// <param name="SyncQty">True: sincronizza quantità, False = NON sincronizza quantità</param>
|
|
/// <param name="BlockSend">
|
|
/// True: effettua 1 sola chiamata upload e 1 sola download per il sync
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public SyncResult ResourcesSync(List<int> MatIdList, bool SyncQty, bool BlockSend)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (RawItemsController rawItemDbContr = new RawItemsController())
|
|
{
|
|
List<RawItemModel> rawItemList = new List<RawItemModel>();
|
|
// ciclo per ogni materiale indicato
|
|
foreach (var item in MatIdList)
|
|
{
|
|
// recupero elenco rawItem
|
|
List<RawItemModel> currList = rawItemDbContr.GetFiltModel(item);
|
|
if (currList == null || currList.Count == 0)
|
|
{
|
|
answ = SyncResult.ERR_Res2SendEmpty;
|
|
}
|
|
else
|
|
{
|
|
// verifico se e cosa aggiungere...
|
|
foreach (var rawItem in currList)
|
|
{
|
|
if (!rawItemList.Contains(rawItem))
|
|
{
|
|
rawItemList.Add(rawItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// effettuo sync alla fine...
|
|
answ = ResourcesSync(rawItemList, SyncQty, BlockSend);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync risorse (Materiali + RawItem):
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="itemList">
|
|
/// Elenco item, saranno inviati x sync (con quantità sovrascritta) SOLO SE RawItemCloudId==0
|
|
/// </param>
|
|
/// <param name="SyncQty">True: sincronizza quantità, False = NON sincronizza quantità</param>
|
|
/// <param name="BlockSend">
|
|
/// True: effettua 1 sola chiamata upload e 1 sola download per il sync
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public SyncResult ResourcesSync(List<RawItemModel> itemList, bool SyncQty, bool BlockSend)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController matDbContr = new MaterialsController())
|
|
{
|
|
using (RawItemsController rawItemDbContr = new RawItemsController())
|
|
{
|
|
// per prima cosa invio dati
|
|
Dictionary<int, MaterialDTO> dictMat = new Dictionary<int, MaterialDTO>();
|
|
// 2024.02.17 --> invio tutti!
|
|
foreach (var item in itemList)
|
|
{
|
|
// verifico se mancasse il materiale nel caso lo aggiungo...
|
|
if (!dictMat.ContainsKey(item.MatId))
|
|
{
|
|
var rigaMat = matDbContr.FindByDbIdModel(item.MatId);
|
|
if (rigaMat != null)
|
|
{
|
|
var rigaMatDto = MaterialsController.ConvToDto(rigaMat);
|
|
dictMat.Add(item.MatId, rigaMatDto);
|
|
}
|
|
}
|
|
// a questo punto aggiungo item nel DTO del dictionary
|
|
dictMat[item.MatId].ItemList.Add(RawItemsController.ConvToItemDto(item));
|
|
}
|
|
// per ogni materiale faccio invio + rilettura/sync...
|
|
if (dictMat != null && dictMat.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
int numMatOk = 0;
|
|
int numMat2Write = 0;
|
|
// 2024.03.12 verifico se fare chiamata in blocco x sync prima UP
|
|
// verso cloud poi DOWN verso DB
|
|
if (BlockSend)
|
|
{
|
|
List<ItemDTO> list2send = new List<ItemDTO>();
|
|
// preparo tutti gli items x un unico invio
|
|
foreach (var matKVP in dictMat)
|
|
{
|
|
list2send.AddRange(matKVP.Value.ItemList);
|
|
}
|
|
// faccio 1 sola chiamata UPLOAD per TUTTI gli items...
|
|
bool invOk = commLib.InventorySend(list2send);
|
|
// ora rileggo dati...
|
|
if (!invOk)
|
|
{
|
|
answ = SyncResult.ERR_InvSendError;
|
|
}
|
|
else
|
|
{
|
|
// faccio 1 sola chiamata DOWNLOAD per TUTTI i materiali...
|
|
List<MaterialDTO> listAll = commLib.InventoryGet(0);
|
|
// ciclo sui materiali...
|
|
if (listAll != null)
|
|
{
|
|
numMat2Write += listAll.Count();
|
|
foreach (var item in listAll)
|
|
{
|
|
var matLocalId = matDbContr.Insert(MaterialsController.ConvToModel(item));
|
|
if (matLocalId > 0)
|
|
{
|
|
// inserisco il materiale locale negli items...
|
|
item.MatLocalId = matLocalId;
|
|
numMatOk++;
|
|
// ora processo 1:1 gli items...
|
|
foreach (var rawItem in item.ItemList)
|
|
{
|
|
// sovrascrivo materaile anche x ogni RawItem
|
|
rawItem.MatLocalId = matLocalId;
|
|
rawItemDbContr.Upsert(RawItemsController.ConvToModel(rawItem, true), false, SyncQty);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var matKVP in dictMat)
|
|
{
|
|
// invio!
|
|
bool invOk = commLib.InventorySend(matKVP.Value.ItemList);
|
|
// ora rileggo dati...
|
|
if (!invOk)
|
|
{
|
|
answ = SyncResult.ERR_InvSendError;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
List<MaterialDTO> list2merge = commLib.InventoryGet(matKVP.Value.MatCloudId);
|
|
// ciclo sui materiali...
|
|
if (list2merge != null)
|
|
{
|
|
numMat2Write += list2merge.Count();
|
|
foreach (var item in list2merge)
|
|
{
|
|
var matLocalId = matDbContr.Insert(MaterialsController.ConvToModel(item));
|
|
if (matLocalId > 0)
|
|
{
|
|
// inserisco il materiale locale negli items...
|
|
item.MatLocalId = matLocalId;
|
|
numMatOk++;
|
|
// ora processo 1:1 gli items...
|
|
foreach (var rawItem in item.ItemList)
|
|
{
|
|
// sovrascrivo materaile anche x ogni RawItem
|
|
rawItem.MatLocalId = matLocalId;
|
|
rawItemDbContr.Upsert(RawItemsController.ConvToModel(rawItem, true), false, SyncQty);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (numMat2Write == numMatOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// nessun materiale da sincronizzare --> ok!
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync risorse (Materiali + RawItem) dato elenco MatId, versione ASYNC:
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="MatIdList">
|
|
/// Elenco Id dei materiali (DB LOCALE): saranno inviati x sync (con quantità sovrascritta)
|
|
/// SOLO SE RawItemCloudId == 0
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public async Task<SyncResult> ResourcesSyncAsync(List<int> MatIdList)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (RawItemsController rawItemDbContr = new RawItemsController())
|
|
{
|
|
// ciclo per ogni materiale indicato
|
|
foreach (var item in MatIdList)
|
|
{
|
|
// recupero elenco rawItem
|
|
var currList = rawItemDbContr.GetFiltModel(item);
|
|
if (currList == null || currList.Count == 0)
|
|
{
|
|
answ = SyncResult.ERR_Res2SendEmpty;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// effettuo sync...
|
|
answ = await ResourcesSyncAsync(currList);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue sync risorse (Materiali + RawItem):
|
|
/// - upload + sync (cloud)
|
|
/// - download + sync (locale)
|
|
/// </summary>
|
|
/// <param name="itemList">
|
|
/// Elenco item dal DB locale saranno inviati x sync (con quantità sovrascritta) SOLO SE
|
|
/// RawItemCloudId == 0
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public async Task<SyncResult> ResourcesSyncAsync(List<RawItemModel> itemList)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
using (MaterialsController matDbContr = new MaterialsController())
|
|
{
|
|
using (RawItemsController rawItemDbContr = new RawItemsController())
|
|
{
|
|
// per prima cosa invio dati
|
|
Dictionary<int, MaterialDTO> dictMat = new Dictionary<int, MaterialDTO>();
|
|
// costruisco elenco materiali da inviare in magazzino (se RawItemCloudId==
|
|
// 0) ...
|
|
var rec2sync = itemList.Where(x => x.RawItemCloudId == 0).ToList();
|
|
foreach (var item in rec2sync)
|
|
{
|
|
// verifico se mancasse il materiale nel caso lo aggiungo...
|
|
if (!dictMat.ContainsKey(item.MatId))
|
|
{
|
|
var rigaMat = matDbContr.FindByDbIdModel(item.MatId);
|
|
if (rigaMat != null)
|
|
{
|
|
var rigaMatDto = MaterialsController.ConvToDto(rigaMat);
|
|
dictMat.Add(item.MatId, rigaMatDto);
|
|
}
|
|
}
|
|
// a questo punto aggiungo item nel DTO del dictionary
|
|
dictMat[item.MatId].ItemList.Add(RawItemsController.ConvToItemDto(item));
|
|
}
|
|
// per ogni materiale faccio invio + rilettura/sync...
|
|
if (dictMat != null && dictMat.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
int numMatOk = 0;
|
|
int numMat2Write = 0;
|
|
foreach (var matKVP in dictMat)
|
|
{
|
|
// invio!
|
|
bool invOk = await commLib.InventorySendAsync(matKVP.Value.ItemList);
|
|
// ora rileggo dati...
|
|
if (!invOk)
|
|
{
|
|
answ = SyncResult.ERR_InvSendError;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
List<MaterialDTO> list2merge = await commLib.InventoryGetAsync(matKVP.Key);
|
|
// ciclo sui materiali...
|
|
if (list2merge != null)
|
|
{
|
|
numMat2Write += list2merge.Count();
|
|
foreach (var item in list2merge)
|
|
{
|
|
var newId = matDbContr.Insert(MaterialsController.ConvToModel(item));
|
|
if (newId > 0)
|
|
{
|
|
numMatOk++;
|
|
// ora processo 1:1 gli items...
|
|
foreach (var rawItem in item.ItemList)
|
|
{
|
|
rawItemDbContr.Upsert(RawItemsController.ConvToModel(rawItem, true), false, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// solo se tutto andato bene esito ALL_OK
|
|
if (numMat2Write == numMatOk)
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Private Fields
|
|
|
|
private DataSyncro commLib = null;
|
|
|
|
/// <summary>
|
|
/// Istanza logger
|
|
/// </summary>
|
|
private NLog.Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Effettua verifica risorse
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">Elenco RawPart come dizionario quantità consumate [nId, qty]</param>
|
|
/// <param name="trackType">tipologia dato inviato</param>
|
|
/// <param name="sign">segno da applicare alle quantità dsa inviare</param>
|
|
/// <returns>Restitusice errore comunicazione oppure se le risorse siano uguali o cambiate</returns>
|
|
private SyncResult ResourceCheckChanged(int ProjCloudId, Dictionary<int, int> rec2send, ProjResState trackType, int sign)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
using (RawItemsController dbContr = new RawItemsController())
|
|
{
|
|
List<ResourceDTO> list2send = new List<ResourceDTO>();
|
|
// recupero elenco risorse da lista int delle chiavi...
|
|
var allResources = dbContr.GetFiltModel(0);
|
|
// ciclo tra risorse richieste...
|
|
foreach (var item in rec2send)
|
|
{
|
|
var currRes = allResources.Find(x => x.RawItemId == item.Key);
|
|
list2send.Add(new ResourceDTO() { RawItemLocalId = item.Key, RawItemCloudId = currRes.RawItemCloudId, Qty = sign * Math.Abs(item.Value) });
|
|
}
|
|
//if (list2send == null || list2send.Count == 0)
|
|
if (list2send == null)
|
|
{
|
|
answ = SyncResult.ERR_Res2SendEmpty;
|
|
}
|
|
else
|
|
{
|
|
string payload = JsonConvert.SerializeObject(list2send);
|
|
DateTime adesso = DateTime.Now;
|
|
// registro su DB invio..
|
|
MagmanSyncModel newRec = new MagmanSyncModel()
|
|
{
|
|
CloudId = ProjCloudId,
|
|
SyncType = $"{trackType}",
|
|
DtReq = adesso,
|
|
Payload = payload
|
|
};
|
|
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// effettuo invio...
|
|
int resChk = commLib.ResourceCheck(ProjCloudId, trackType, adesso, list2send);
|
|
switch (resChk)
|
|
{
|
|
case 1:
|
|
answ = SyncResult.RES_CheckEqual;
|
|
break;
|
|
|
|
case 2:
|
|
answ = SyncResult.RES_CheckChanged;
|
|
break;
|
|
|
|
case 0:
|
|
default:
|
|
answ = SyncResult.RES_CheckND;
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua invio track risorse
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">Elenco RawPart come dizionario quantità consumate [nId, qty]</param>
|
|
/// <param name="trackType">tipologia dato inviato</param>
|
|
/// <param name="sign">segno da applicare alle quantità dsa inviare</param>
|
|
/// <returns></returns>
|
|
private SyncResult ResourceSendTrack(int ProjCloudId, Dictionary<int, int> rec2send, ProjResState trackType, int sign)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
using (RawItemsController dbContr = new RawItemsController())
|
|
{
|
|
List<ResourceDTO> list2send = new List<ResourceDTO>();
|
|
// recupero elenco risorse da lista int delle chiavi...
|
|
var allResources = dbContr.GetFiltModel(0);
|
|
// ciclo tra risorse richieste...
|
|
foreach (var item in rec2send)
|
|
{
|
|
var currRes = allResources.Find(x => x.RawItemId == item.Key);
|
|
list2send.Add(new ResourceDTO() { RawItemLocalId = item.Key, RawItemCloudId = currRes.RawItemCloudId, Qty = sign * Math.Abs(item.Value) });
|
|
}
|
|
//if (list2send == null || list2send.Count == 0)
|
|
if (list2send == null)
|
|
{
|
|
answ = SyncResult.ERR_Res2SendEmpty;
|
|
}
|
|
else
|
|
{
|
|
int syncId = 0;
|
|
string payload = JsonConvert.SerializeObject(list2send);
|
|
DateTime adesso = DateTime.Now;
|
|
// registro su DB invio..
|
|
MagmanSyncModel newRec = new MagmanSyncModel()
|
|
{
|
|
CloudId = ProjCloudId,
|
|
SyncType = $"{trackType}",
|
|
DtReq = adesso,
|
|
Payload = payload
|
|
};
|
|
// salvo sul DB
|
|
using (MagmanSyncController msContr = new MagmanSyncController())
|
|
{
|
|
syncId = msContr.Insert(newRec);
|
|
// se si tratta di STIMA cancello EVENTUALI record precedenti non inviati
|
|
if (trackType == ProjResState.Estimated)
|
|
{
|
|
// elimino eventuali eventi rimasti fino a 1 sec precedente
|
|
msContr.DeleteUnsentFilt(ProjCloudId, $"{trackType}", adesso.AddSeconds(-1));
|
|
}
|
|
// verifico server ok
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// effettuo invio...
|
|
bool resOk = commLib.ResourceSend(ProjCloudId, trackType, adesso, list2send);
|
|
if (!resOk)
|
|
{
|
|
answ = SyncResult.ERR_CloudResNotSent;
|
|
}
|
|
else
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
// registro su DB dataora conclusione invio
|
|
msContr.SetCompleted(syncId, DateTime.Now);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua invio track risorse
|
|
/// </summary>
|
|
/// <param name="ProjCloudId">DB Id del progetto x cui si inviano i dati</param>
|
|
/// <param name="rec2send">Elenco RawPart come dizionario quantità consumate [nId, qty]</param>
|
|
/// <param name="trackType">tipologia dato inviato</param>
|
|
/// <param name="sign">segno da applicare alle quantità dsa inviare</param>
|
|
/// <returns></returns>
|
|
private async Task<SyncResult> ResourceSendTrackAsync(int ProjCloudId, Dictionary<int, int> rec2send, ProjResState trackType, int sign)
|
|
{
|
|
SyncResult answ = SyncResult.ERR_ND;
|
|
// verifico server ok
|
|
using (RawItemsController dbContr = new RawItemsController())
|
|
{
|
|
List<ResourceDTO> list2send = new List<ResourceDTO>();
|
|
// recupero elenco risorse da lista int delle chiavi...
|
|
var allResources = dbContr.GetFiltModel(0);
|
|
// ciclo tra risorse richieste...
|
|
foreach (var item in rec2send)
|
|
{
|
|
var currRes = allResources.Find(x => x.RawItemId == item.Key);
|
|
list2send.Add(new ResourceDTO() { RawItemLocalId = item.Key, RawItemCloudId = currRes.RawItemCloudId, Qty = sign * Math.Abs(item.Value) });
|
|
}
|
|
if (list2send == null || list2send.Count == 0)
|
|
{
|
|
answ = SyncResult.ERR_Res2SendEmpty;
|
|
}
|
|
else
|
|
{
|
|
int syncId = 0;
|
|
string payload = JsonConvert.SerializeObject(list2send);
|
|
// registro su DB invio..
|
|
MagmanSyncModel newRec = new MagmanSyncModel()
|
|
{
|
|
CloudId = ProjCloudId,
|
|
SyncType = $"{trackType}",
|
|
DtReq = DateTime.Now,
|
|
Payload = payload
|
|
};
|
|
// salvo sul DB
|
|
using (MagmanSyncController msContr = new MagmanSyncController())
|
|
{
|
|
syncId = msContr.Insert(newRec);
|
|
|
|
bool servOk = commLib.CheckRemote();
|
|
if (!servOk)
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
// effettuo invio...
|
|
bool resOk = await commLib.ResourceSendAsync(ProjCloudId, trackType, list2send);
|
|
if (!resOk)
|
|
{
|
|
answ = SyncResult.ERR_CloudResNotSent;
|
|
}
|
|
else
|
|
{
|
|
answ = SyncResult.ALL_OK;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
answ = SyncResult.ERR_ServerKo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |