Files
egtbeamwall/EgtBEAMWALL.DataLayer/Controllers/MagmanController.cs
T
2024-02-06 16:54:03 +01:00

480 lines
20 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;
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 Methods
public void Dispose()
{
commLib = null;
}
/// <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></returns>
public bool MaterialsSyncro(string MatCode = "")
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
using (MaterialsController dbContr = new MaterialsController())
{
// in primis leggo l'elenco materiali dal DB locale
List<MaterialModel> matListDb = dbContr.GetFiltModel(MatCode);
if (matListDb != null)
{
List<MaterialDTO> list2send = matListDb.Select(x => MaterialsController.ConvToDto(x)).ToList();
// preparo pacchetto invio...
answ = commLib.MaterialsSend(list2send);
// se inviato, scarico x merge locale
if (answ)
{
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)
{
foreach (var item in list2MergeDb)
{
_ = dbContr.Upsert(item);
}
}
}
}
}
}
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></returns>
public async Task<bool> MaterialsSyncroAsync(string MatCode = "")
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
using (MaterialsController dbContr = new MaterialsController())
{
// in primis leggo l'elenco materiali dal DB locale
List<MaterialModel> matListDb = dbContr.GetFiltModel(MatCode);
if (matListDb != null)
{
List<MaterialDTO> list2send = matListDb.Select(x => MaterialsController.ConvToDto(x)).ToList();
// preparo pacchetto invio...
answ = await commLib.MaterialsSendAsync(list2send);
// se inviato, scarico x merge locale
if (answ)
{
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)
{
foreach (var item in list2MergeDb)
{
_ = dbContr.Insert(item);
}
}
}
}
}
}
return answ;
}
/// <summary>
/// Esegue registrazione Risorse (RawItems) come CONSUMI effettivi:
/// </summary>
/// <param name="idxProjDbId">DB Id del progetto x cui si inviano i dati</param>
/// <param name="rec2send">
/// Lista items e quantità consumate, se fossero positive vengono cambiate di segno...
/// </param>
/// <returns></returns>
public bool ResourceSendCons(int idxProjDbId, List<RawItemModel> rec2send)
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
answ = ResourcesSync(rec2send);
if (answ)
{
// in primis converto le risorse...
List<ResourceDTO> list2send = rec2send.Select(x => RawItemsController.ConvToResDtoNeg(x)).ToList();
// effettuo invio...
answ = commLib.ResourceSend(idxProjDbId, ProjResState.Consumed, list2send);
}
}
return answ;
}
/// <summary>
/// Esegue registrazione Risorse (RawItems) come CONSUMI effettivi, versione ASYNC:
/// </summary>
/// <param name="idxProjDbId">DB Id del progetto x cui si inviano i dati</param>
/// <param name="rec2send">
/// Lista items e quantità consumate, se fossero positive vengono cambiate di segno...
/// </param>
/// <returns></returns>
public async Task<bool> ResourceSendConsAsync(int idxProjDbId, List<RawItemModel> rec2send)
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
answ = await ResourcesSyncAsync(rec2send);
if (answ)
{
// in primis converto le risorse...
List<ResourceDTO> list2send = rec2send.Select(x => RawItemsController.ConvToResDtoNeg(x)).ToList();
// effettuo invio...
answ = await commLib.ResourceSendAsync(idxProjDbId, ProjResState.Consumed, list2send);
}
}
return answ;
}
/// <summary>
/// Esegue registrazione Risorse (RawItems) come stima:
/// </summary>
/// <param name="idxProjDbId">DB Id del progetto x cui si inviano i dati</param>
/// <param name="rec2send">Lista items con quantità prevista</param>
/// <returns></returns>
public bool ResourceSendEstimate(int idxProjDbId, List<RawItemModel> rec2send)
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
answ = ResourcesSync(rec2send);
if (answ)
{
// in primis converto le risorse...
List<ResourceDTO> list2send = rec2send.Select(x => RawItemsController.ConvToResDto(x)).ToList();
// effettuo invio...
answ = commLib.ResourceSend(idxProjDbId, ProjResState.Estimated, list2send);
}
}
return answ;
}
/// <summary>
/// Esegue registrazione Risorse (RawItems) come stima, versione ASYNC:
/// </summary>
/// <param name="idxProjDbId">DB Id del progetto x cui si inviano i dati</param>
/// <param name="rec2send">Lista items con quantità prevista</param>
/// <returns></returns>
public async Task<bool> ResourceSendEstimateAsync(int idxProjDbId, List<RawItemModel> rec2send)
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
answ = await ResourcesSyncAsync(rec2send);
if (answ)
{
// in primis converto le risorse...
List<ResourceDTO> list2send = rec2send.Select(x => RawItemsController.ConvToResDto(x)).ToList();
// effettuo invio...
answ = await commLib.ResourceSendAsync(idxProjDbId, ProjResState.Estimated, list2send);
}
}
return answ;
}
/// <summary>
/// Esegue sync risorse (Materiali + RawItem) dato elenco MatId:
/// - upload + sync (cloud)
/// - download + sync (locale)
/// </summary>
/// <param name="itemList">
/// Elenco item, saranno inviati x sync (con quantità sovrascritta) SOLO SE RawItemCloudId==0
/// </param>
/// <returns></returns>
public bool ResourcesSync(List<int> MatIdList)
{
bool fatto = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
using (RawItemsController rawItemDbContr = new RawItemsController())
{
// ciclo per ogni materiale indicato
foreach (var item in MatIdList)
{
// recupero elenco rawItem
var currList = rawItemDbContr.GetFiltModel(item);
// effettuo sync...
bool callOk = ResourcesSync(currList);
fatto = fatto && callOk;
}
}
}
return fatto;
}
/// <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>
/// <returns></returns>
public bool ResourcesSync(List<RawItemModel> itemList)
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
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)
{
foreach (var matKVP in dictMat)
{
// invio!
answ = commLib.InventorySend(matKVP.Value.ItemList);
// ora rileggo dati...
if (answ)
{
List<MaterialDTO> list2merge = commLib.InventoryGet(matKVP.Key);
// ciclo sui materiali...
if (list2merge != null)
{
foreach (var item in list2merge)
{
_ = matDbContr.Insert(MaterialsController.ConvToModel(item));
// ora processo 1:1 gli items...
foreach (var rawItem in item.ItemList)
{
rawItemDbContr.Upsert(RawItemsController.ConvToModel(rawItem, true));
}
}
}
}
}
}
}
}
}
return answ;
}
/// <summary>
/// Esegue sync risorse (Materiali + RawItem) dato elenco MatId, versione ASYNC:
/// - upload + sync (cloud)
/// - download + sync (locale)
/// </summary>
/// <param name="itemList">
/// Elenco item, saranno inviati x sync (con quantità sovrascritta) SOLO SE RawItemCloudId
/// == 0
/// </param>
/// <returns></returns>
public async Task<bool> ResourcesSyncAsync(List<int> MatIdList)
{
bool fatto = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
using (RawItemsController rawItemDbContr = new RawItemsController())
{
// ciclo per ogni materiale indicato
foreach (var item in MatIdList)
{
// recupero elenco rawItem
var currList = rawItemDbContr.GetFiltModel(item);
// effettuo sync...
bool callOk = await ResourcesSyncAsync(currList);
fatto = fatto && callOk;
}
}
}
return fatto;
}
/// <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>
/// <returns></returns>
public async Task<bool> ResourcesSyncAsync(List<RawItemModel> itemList)
{
bool answ = false;
// verifico server ok
bool servOk = commLib.CheckRemote();
if (servOk)
{
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)
{
foreach (var matKVP in dictMat)
{
// invio!
answ = await commLib.InventorySendAsync(matKVP.Value.ItemList);
// ora rileggo dati...
if (answ)
{
List<MaterialDTO> list2merge = await commLib.InventoryGetAsync(matKVP.Key);
// ciclo sui materiali...
if (list2merge != null)
{
foreach (var item in list2merge)
{
_ = matDbContr.Insert(MaterialsController.ConvToModel(item));
// ora processo 1:1 gli items...
foreach (var rawItem in item.ItemList)
{
rawItemDbContr.Upsert(RawItemsController.ConvToModel(rawItem, true));
}
}
}
}
}
}
}
}
}
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
}
}