Files
egtbeamwall/EgtBEAMWALL.DataLayer/Controllers/MagmanController.cs
T
2024-03-11 17:11:49 +01:00

1186 lines
51 KiB
C#

using EgtBEAMWALL.DataLayer.DatabaseModels;
using EgwProxy.MagMan;
using EgwProxy.MagMan.DTO;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static EgwProxy.MagMan.RestPayload;
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
}
#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())
{
List<AliasDTO> list2merge = commLib.AliasGet();
// effettuo conversione DTO --> model + merge
List<AliasModel> list2MergeDb = list2merge.Select(x => AliasController.ConvToModel(x, "MatCode")).ToList();
// ciclo...
if (list2MergeDb == null)
{
answ = SyncResult.ERR_AliasMatEmpty;
}
else
{
var updateOk = dbContr.UpsertList(list2MergeDb);
if (updateOk)
{
// 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;
}
}
}
}
}
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())
{
List<AliasDTO> list2merge = await commLib.AliasGetAsync();
// effettuo conversione DTO --> model + merge
List<AliasModel> list2MergeDb = list2merge.Select(x => AliasController.ConvToModel(x, "MatCode")).ToList();
// ciclo...
if (list2MergeDb == null)
{
answ = SyncResult.ERR_AliasMatEmpty;
}
else
{
var updateOk = dbContr.UpsertList(list2MergeDb);
if (updateOk)
{
// 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;
}
}
}
}
}
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>
/// <returns></returns>
public SyncResult CloudSyncro(bool ForceAll, bool SyncQty)
{
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
{
// 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);
}
}
}
}
}
return answ;
}
public void Dispose()
{
commLib = null;
}
/// <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
{
// 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;
}
}
}
}
}
}
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
{
// 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;
}
}
}
}
}
}
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
{
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;
}
}
}
}
}
}
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
{
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;
}
}
}
}
}
}
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
{
// 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;
}
}
}
}
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
{
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);
}
}
}
}
}
// solo se tutto andato bene esito ALL_OK
if (numMat2Write == numMatOk)
{
answ = SyncResult.ALL_OK;
}
}
}
}
}
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>
/// <returns></returns>
public SyncResult ResourcesSync(List<int> MatIdList, bool SyncQty)
{
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);
}
}
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>
/// <returns></returns>
public SyncResult ResourcesSync(List<RawItemModel> itemList, bool SyncQty)
{
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!
//// costruisco elenco materiali da inviare in magazzino (RawItemCloudId==0)
//var rec2sync = itemList.Where(x => x.RawItemCloudId == 0).ToList();
//foreach (var item in rec2sync)
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)
{
int numMatOk = 0;
int numMat2Write = 0;
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), SyncQty);
}
}
}
}
}
}
// solo se tutto andato bene esito ALL_OK
if (numMat2Write == numMatOk)
{
answ = SyncResult.ALL_OK;
}
}
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)
{
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);
}
}
}
}
}
}
// solo se tutto andato bene esito ALL_OK
if (numMat2Write == numMatOk)
{
answ = SyncResult.ALL_OK;
}
}
}
}
}
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 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;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (!servOk)
{
answ = SyncResult.ERR_ServerKo;
}
else
{
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
{
// effettuo invio...
bool resOk = commLib.ResourceSend(ProjCloudId, trackType, list2send);
if (!resOk)
{
answ = SyncResult.ERR_CloudResNotSent;
}
else
{
answ = SyncResult.ALL_OK;
}
}
}
}
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
bool servOk = commLib.CheckRemote();
if (!servOk)
{
answ = SyncResult.ERR_ServerKo;
}
else
{
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
{
// effettuo invio...
bool resOk = await commLib.ResourceSendAsync(ProjCloudId, trackType, list2send);
if (!resOk)
{
answ = SyncResult.ERR_CloudResNotSent;
}
else
{
answ = SyncResult.ALL_OK;
}
}
}
}
return answ;
}
#endregion Private Methods
}
}