571 lines
26 KiB
C#
571 lines
26 KiB
C#
using EgwCApp.Core;
|
|
using Newtonsoft.Json;
|
|
using static EgwCApp.Core.UstdData;
|
|
using static EgwCApp.Core.WharehouseData;
|
|
|
|
namespace EgwCApp.ExcImport
|
|
{
|
|
public class ImportProc
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Init oggetto per import
|
|
/// </summary>
|
|
/// <param name="confFileName"></param>
|
|
public ImportProc(string confFileName)
|
|
{
|
|
if (!string.IsNullOrEmpty(confFileName))
|
|
{
|
|
fileConfName = confFileName;
|
|
}
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Decodifica configurazione
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool decodeConfig()
|
|
{
|
|
bool answ = false;
|
|
if (!string.IsNullOrEmpty(fileConfName))
|
|
{
|
|
// deserializzo config
|
|
if (!File.Exists(fileConfName))
|
|
{
|
|
Console.WriteLine($"Error: ConfigFile not found | {fileConfName}");
|
|
}
|
|
else
|
|
{
|
|
string rawData = File.ReadAllText(fileConfName);
|
|
// se ho contenuto procedo
|
|
if (string.IsNullOrEmpty(rawData))
|
|
{
|
|
Console.WriteLine($"Error: ConfigFile empty! | {fileConfName}");
|
|
}
|
|
else
|
|
{
|
|
// deserializzo
|
|
taskConfig = JsonConvert.DeserializeObject<ConfigFile>(rawData);
|
|
answ = taskConfig != null;
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue import (se possibile)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool doProcess()
|
|
{
|
|
bool answ = false;
|
|
if (taskConfig != null)
|
|
{
|
|
// verifico esista il file...
|
|
if (string.IsNullOrEmpty(taskConfig.FileInPath) && File.Exists(taskConfig.FileInPath))
|
|
{
|
|
// manca file ingresso!!! esco!
|
|
}
|
|
else
|
|
{
|
|
// verifico il tipo di process necessario...
|
|
switch (taskConfig.Type)
|
|
{
|
|
case ImportType.CSV:
|
|
fileReturnData = File.ReadAllText(taskConfig.FileInPath);
|
|
answ = true;
|
|
break;
|
|
|
|
case ImportType.Excel:
|
|
fileReturnData = processExcelImport(taskConfig.FileInPath, taskConfig.ReturnDataType);
|
|
answ = true;
|
|
break;
|
|
|
|
case ImportType.ND:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esecuzione ritorno informazioni secondo configurazione...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool doReturn()
|
|
{
|
|
bool answ = false;
|
|
if (taskConfig != null)
|
|
{
|
|
// verifico il tipo di return necessario...
|
|
switch (taskConfig.Return)
|
|
{
|
|
case ReturnMode.Console:
|
|
Console.WriteLine(fileReturnData);
|
|
answ = true;
|
|
break;
|
|
|
|
case ReturnMode.Redis:
|
|
// salvo in Redis!
|
|
string rKey = taskConfig.RedisOut;
|
|
RedisMan redMan = new RedisMan(taskConfig.RedisServer, taskConfig.RedisPort, taskConfig.RedisDB);
|
|
// salvo!
|
|
if (taskConfig.RedisTTL > 0)
|
|
{
|
|
redMan.setRSV(rKey, fileReturnData, taskConfig.RedisTTL);
|
|
}
|
|
else
|
|
{
|
|
redMan.setRSV(rKey, fileReturnData);
|
|
}
|
|
break;
|
|
|
|
case ReturnMode.File:
|
|
// verifico path ci sia... sennò creo
|
|
string outPath = string.IsNullOrEmpty(taskConfig.FileOutPath) ? "FileOut.txt" : taskConfig.FileOutPath;
|
|
// verifico se vadano salvati in una folder differente...
|
|
if (!string.IsNullOrEmpty(taskConfig.ConvertDir))
|
|
{
|
|
if (!Directory.Exists(taskConfig.ConvertDir))
|
|
{
|
|
Directory.CreateDirectory(taskConfig.ConvertDir);
|
|
}
|
|
outPath = Path.Combine(taskConfig.ConvertDir, Path.GetFileName(outPath));
|
|
}
|
|
// salvo il file!
|
|
File.WriteAllText(outPath, fileReturnData);
|
|
answ = true;
|
|
break;
|
|
|
|
case ReturnMode.ND:
|
|
default:
|
|
break;
|
|
}
|
|
// se fatto eventualmente archivio
|
|
if (answ)
|
|
{
|
|
if (!string.IsNullOrEmpty(taskConfig.ArchiveDir))
|
|
{
|
|
// folder archivio con dataora...
|
|
string folderArch = Path.Combine(taskConfig.ArchiveDir, $"{DateTime.Now:yyyyMMdd_HHmmss}");
|
|
// verifico cartella archivio
|
|
if (!Directory.Exists(folderArch))
|
|
{
|
|
Directory.CreateDirectory(folderArch);
|
|
}
|
|
// sposto file
|
|
string fName = Path.GetFileName(taskConfig.FileInPath);
|
|
File.Move(taskConfig.FileInPath, Path.Combine(folderArch, fName), true);
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Properties
|
|
|
|
/// <summary>
|
|
/// Nome del file config da processare
|
|
/// </summary>
|
|
protected string fileConfName { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Contenuto del file da restituire come return data (serializzato)
|
|
/// </summary>
|
|
protected string fileReturnData { get; set; } = "";
|
|
|
|
/// <summary>
|
|
/// Configurazione del task da eseguire
|
|
/// </summary>
|
|
protected ConfigFile? taskConfig { get; set; } = new ConfigFile();
|
|
|
|
#endregion Protected Properties
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Estrae da una riga l'i-esimo elemento
|
|
/// </summary>
|
|
/// <param name="riga"></param>
|
|
/// <param name="col"></param>
|
|
/// <returns></returns>
|
|
protected string getCellVal(System.Data.DataRow? riga, int col)
|
|
{
|
|
string answ = "";
|
|
if (riga != null)
|
|
{
|
|
try
|
|
{
|
|
answ = $"{riga.ItemArray[col]}".Trim();
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cleanup stringa x impiego tipo ident da char dubbi
|
|
/// </summary>
|
|
/// <param name="origData"></param>
|
|
/// <returns></returns>
|
|
protected string strFixId(string origData)
|
|
{
|
|
return origData.Replace(".", "").Replace(" ", "_");
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Importa un file excel e restituisce una
|
|
/// </summary>
|
|
/// <param name="fileItem"></param>
|
|
/// <returns></returns>
|
|
private string processExcelImport(string fileItem, OutDataType outReq = OutDataType.RegGiacenze)
|
|
{
|
|
string outVal = "";
|
|
switch (outReq)
|
|
{
|
|
case OutDataType.ParamTaglioUstd:
|
|
outVal = getParTaglioUstdJson(fileItem, true);
|
|
break;
|
|
case OutDataType.RegGiacenze:
|
|
default:
|
|
outVal = getRegGiacJson(fileItem);
|
|
break;
|
|
}
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa e restituisce un oggetto lista giacenze serializzato
|
|
/// </summary>
|
|
/// <param name="fileItem">Nome file excel</param>
|
|
/// <param name="doIndent">Output indentato</param>
|
|
/// <returns></returns>
|
|
private string getRegGiacJson(string fileItem, bool doIndent = false)
|
|
{
|
|
int numErr = 0;
|
|
string outVal = "";
|
|
// test procedura di import files excel (default Giacovelli...)
|
|
var currExcel = new ExcelMan(fileItem);
|
|
// creo lista dati in formato RegGiacenze...
|
|
Dictionary<string, BatchRec> listaGiac = new Dictionary<string, BatchRec>();
|
|
var dtSet = currExcel.getDataSet();
|
|
if (dtSet != null && dtSet.Tables != null && dtSet.Tables.Count > 0)
|
|
{
|
|
string nomeFile = Path.GetFileName(fileItem);
|
|
nomeFile = nomeFile.Substring(0, nomeFile.LastIndexOf("."));
|
|
var elSheet = dtSet.Tables;
|
|
int idxTab = 0;
|
|
// cerco lo sheet corretto se > 1
|
|
if (dtSet.Tables.Count > 1)
|
|
{
|
|
bool found = false;
|
|
for (int i = 0; i < dtSet.Tables.Count; i++)
|
|
{
|
|
if (nomeFile.Contains(dtSet.Tables[i].TableName))
|
|
{
|
|
idxTab = i;
|
|
found = true;
|
|
break;
|
|
}
|
|
// controllo parametro opzionale...
|
|
if (!found && taskConfig != null && !string.IsNullOrEmpty(taskConfig.TargetName))
|
|
{
|
|
if (dtSet.Tables[i].TableName == taskConfig.TargetName)
|
|
{
|
|
idxTab = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var tabella = dtSet.Tables[idxTab];
|
|
int numRighe = tabella.Rows.Count;
|
|
int idxODL = taskConfig != null ? taskConfig.IdxODL : 0;
|
|
for (int i = 0; i < numRighe; i++)
|
|
{
|
|
if (taskConfig != null && taskConfig.ProcessParamInt != null && taskConfig.ProcessParamInt.Count > 5)
|
|
{
|
|
if (numErr < numRighe / 5)
|
|
{
|
|
try
|
|
{
|
|
// variabili di appoggio...
|
|
DateTime dtRif = DateTime.Today;
|
|
double qtyTot = 0;
|
|
int numPack = 0;
|
|
var riga = tabella.Rows[i];
|
|
if (riga != null)
|
|
{
|
|
string ddt = getCellVal(riga, taskConfig.ProcessParamInt["ExtDoc"]);
|
|
string sDate = getCellVal(riga, taskConfig.ProcessParamInt["DateRif"]);
|
|
string prod = getCellVal(riga, taskConfig.ProcessParamInt["Product"]);
|
|
// verifiche x import: header, data e DDT (vuoti o "-") --> SKIP!
|
|
bool checkHeaderKo = (ddt == "DDT" || prod == "PRODOTTO");
|
|
bool checkEmptyDdt = (string.IsNullOrEmpty(ddt) || ddt == "-");
|
|
bool checkEmptyDate = (string.IsNullOrEmpty(sDate) || sDate == "-");
|
|
if (checkHeaderKo)
|
|
{
|
|
//lgTrace($"SKIP header");
|
|
}
|
|
else if (checkEmptyDdt || checkEmptyDate)
|
|
{
|
|
//lgTrace($"SKIP linea vuota | i: {i} | codice: {codice} | date: {serie} | prod: {prod}");
|
|
}
|
|
else
|
|
{
|
|
string variety = getCellVal(riga, taskConfig.ProcessParamInt["Variety"]);
|
|
string suppl = getCellVal(riga, taskConfig.ProcessParamInt["Supplier"]);
|
|
string sQty = getCellVal(riga, taskConfig.ProcessParamInt["QtyTot"]);
|
|
string sNum = getCellVal(riga, taskConfig.ProcessParamInt["NumPack"]);
|
|
string numPed = getCellVal(riga, taskConfig.ProcessParamInt["NumPed"]);
|
|
string packPed = getCellVal(riga, taskConfig.ProcessParamInt["PackPed"]);
|
|
string pesoPack = getCellVal(riga, taskConfig.ProcessParamInt["PesoPack"]);
|
|
DateTime.TryParse(sDate, out dtRif);
|
|
int.TryParse(sNum, out numPack);
|
|
double.TryParse(sQty, out qtyTot);
|
|
string identRG = ddt.Length > 2 ? $"{strFixId(ddt)}.{strFixId(prod)}.{strFixId(variety)}.{strFixId(suppl)}" : $"{dtRif:yyyyMMdd}.{strFixId(prod)}.{strFixId(variety)}.{strFixId(suppl)}";
|
|
string notes = $"{numPed}x{packPed}x{pesoPack}";
|
|
// verifico di avere dati per proseguire...
|
|
bool checkIdent = !string.IsNullOrEmpty($"{prod}{variety}{suppl}");
|
|
if (checkIdent)
|
|
{
|
|
BatchRec newRow = new BatchRec()
|
|
{
|
|
IdxODL = idxODL,
|
|
IdentRG = identRG,
|
|
DateRif = dtRif,
|
|
ExtDoc = ddt,
|
|
Product = prod,
|
|
Variety = variety,
|
|
Supplier = suppl,
|
|
NumPack = numPack,
|
|
QtyTot = qtyTot,
|
|
Notes = notes
|
|
};
|
|
// verifico: se manca aggiungo
|
|
if (!listaGiac.ContainsKey(identRG))
|
|
{
|
|
listaGiac.Add(identRG, newRow);
|
|
}
|
|
else
|
|
{
|
|
// altrimenti aggiorno giacenza con valori numerici
|
|
listaGiac[identRG].NumPack += newRow.NumPack;
|
|
listaGiac[identRG].QtyTot += newRow.QtyTot;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//lgError($"Errore verifica identità riga | prod: {prod} | variety: {variety} | suppl: {suppl}");
|
|
numErr++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
numErr++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (listaGiac.Count > 0)
|
|
{
|
|
// converto in una nuova lista...
|
|
int rCounter = 1;
|
|
Dictionary<int, BatchRec> list2Send = new Dictionary<int, BatchRec>();
|
|
foreach (var item in listaGiac)
|
|
{
|
|
list2Send.Add(rCounter, item.Value);
|
|
rCounter++;
|
|
}
|
|
// serializzo e restituisco file JSON...
|
|
Formatting fMode = doIndent ? Formatting.Indented : Formatting.None;
|
|
var serVal = JsonConvert.SerializeObject(list2Send, fMode);
|
|
if (serVal != null && !string.IsNullOrEmpty(serVal))
|
|
{
|
|
outVal = serVal;
|
|
}
|
|
}
|
|
return outVal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa e restituisce un oggetto parametri taglio serializzato
|
|
/// </summary>
|
|
/// <param name="fileItem">Nome file excel</param>
|
|
/// <param name="doIndent">Output indentato</param>
|
|
/// <returns>Restituisce un serializzato formato Dictionary<string, CutterParam></returns>
|
|
private string getParTaglioUstdJson(string fileItem, bool doIndent = false)
|
|
{
|
|
int numErr = 0;
|
|
string outVal = "";
|
|
// test procedura di import files excel (default Giacovelli...)
|
|
var currExcel = new ExcelMan(fileItem);
|
|
// creo lista dati in formato ParametriTaglioUSTD...
|
|
Dictionary<string, CutterParam> listaParams = new Dictionary<string, CutterParam>();
|
|
var dtSet = currExcel.getDataSet();
|
|
if (dtSet != null && dtSet.Tables != null && dtSet.Tables.Count > 0)
|
|
{
|
|
string nomeFile = Path.GetFileName(fileItem);
|
|
nomeFile = nomeFile.Substring(0, nomeFile.LastIndexOf("."));
|
|
var elSheet = dtSet.Tables;
|
|
int idxTab = 0;
|
|
// cerco lo sheet corretto se > 1
|
|
if (dtSet.Tables.Count > 1)
|
|
{
|
|
bool found = false;
|
|
for (int i = 0; i < dtSet.Tables.Count; i++)
|
|
{
|
|
if (nomeFile.Contains(dtSet.Tables[i].TableName))
|
|
{
|
|
idxTab = i;
|
|
found = true;
|
|
break;
|
|
}
|
|
// controllo parametro opzionale...
|
|
if (!found && taskConfig != null && !string.IsNullOrEmpty(taskConfig.TargetName))
|
|
{
|
|
if (dtSet.Tables[i].TableName == taskConfig.TargetName)
|
|
{
|
|
idxTab = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var tabella = dtSet.Tables[idxTab];
|
|
int numRighe = tabella.Rows.Count;
|
|
int idxODL = taskConfig != null ? taskConfig.IdxODL : 0;
|
|
for (int i = 0; i < numRighe; i++)
|
|
{
|
|
// voglio che ci sia setup x params
|
|
if (taskConfig != null && taskConfig.ProcessParamInt != null && taskConfig.ProcessParamInt.Count > 5)
|
|
{
|
|
// procedo se errori < 20%...
|
|
if (numErr < numRighe / 5)
|
|
{
|
|
try
|
|
{
|
|
double lungPezzo = 0;
|
|
double quotaUscita = 0;
|
|
double lungBarra = 0;
|
|
double altezza = 0;
|
|
var riga = tabella.Rows[i];
|
|
if (riga != null)
|
|
{
|
|
string codice = getCellVal(riga, taskConfig.ProcessParamInt["Codice"]);
|
|
string serie = getCellVal(riga, taskConfig.ProcessParamInt["Serie"]);
|
|
string sLungPezzo = getCellVal(riga, taskConfig.ProcessParamInt["LungPezzo"]);
|
|
string sQuotaUscita = getCellVal(riga, taskConfig.ProcessParamInt["QuotaUscita"]);
|
|
string sLungBarra = getCellVal(riga, taskConfig.ProcessParamInt["LungBarra"]);
|
|
string sAltezza = getCellVal(riga, taskConfig.ProcessParamInt["Altezza"]);
|
|
|
|
// verifiche x import: header avrà codice e serie con nome "codice" e "serie" --> SKIP!
|
|
bool chkHeaderKo = (codice.ToLower() == "codice" || serie.ToLower() == "serie");
|
|
bool chkEmptyLP = (string.IsNullOrEmpty(sLungPezzo) || sLungPezzo.Length < 2);
|
|
bool chkEmptyQU = (string.IsNullOrEmpty(sQuotaUscita) || sQuotaUscita.Length < 2);
|
|
bool chkEmptyLB = (string.IsNullOrEmpty(sLungBarra) || sLungBarra.Length < 2);
|
|
bool chkEmptyA = (string.IsNullOrEmpty(sAltezza) || sAltezza.Length < 2);
|
|
if (chkHeaderKo)
|
|
{
|
|
//lgTrace($"SKIP header");
|
|
}
|
|
else if (chkEmptyLP || chkEmptyQU || chkEmptyLB || chkEmptyA)
|
|
{
|
|
//lgTrace($"SKIP linea vuota | i: {i} | codice: {codice} | date: {serie} | prod: {prod}");
|
|
}
|
|
else
|
|
{
|
|
// conversione valori double
|
|
bool bLP = double.TryParse(sLungPezzo, out lungPezzo);
|
|
bool bQU = double.TryParse(sQuotaUscita, out quotaUscita);
|
|
bool bLB = double.TryParse(sLungBarra, out lungBarra);
|
|
bool bA = double.TryParse(sAltezza, out altezza);
|
|
|
|
// verifico di avere dati per proseguire...
|
|
bool chkConvert = bLP && bQU && bLB && bA;
|
|
if (chkConvert)
|
|
{
|
|
CutterParam newRow = new CutterParam()
|
|
{
|
|
Codice = codice,
|
|
Serie = serie,
|
|
LungPezzo = lungPezzo,
|
|
QuotaUscita = quotaUscita,
|
|
LungBarra = lungBarra,
|
|
Altezza = altezza
|
|
};
|
|
// verifico: se manca aggiungo
|
|
if (!listaParams.ContainsKey(codice))
|
|
{
|
|
listaParams.Add(codice, newRow);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//lgError($"Errore verifica identità riga | prod: {prod} | variety: {variety} | suppl: {suppl}");
|
|
numErr++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
numErr++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// serializzo direttamente la listaParams x velocizzare poi ricerca da dictionary
|
|
if (listaParams.Count > 0)
|
|
{
|
|
#if false
|
|
// converto in una nuova lista...
|
|
int rCounter = 1;
|
|
Dictionary<int, CutterParam> list2Send = new Dictionary<int, CutterParam>();
|
|
foreach (var item in listaParams)
|
|
{
|
|
list2Send.Add(rCounter, item.Value);
|
|
rCounter++;
|
|
}
|
|
// serializzo e restituisco file JSON...
|
|
Formatting fMode = doIndent ? Formatting.Indented : Formatting.None;
|
|
var serVal = JsonConvert.SerializeObject(list2Send, fMode);
|
|
if (serVal != null && !string.IsNullOrEmpty(serVal))
|
|
{
|
|
outVal = serVal;
|
|
}
|
|
#endif
|
|
// serializzo e restituisco file JSON...
|
|
Formatting fMode = doIndent ? Formatting.Indented : Formatting.None;
|
|
var serVal = JsonConvert.SerializeObject(listaParams, fMode);
|
|
if (serVal != null && !string.IsNullOrEmpty(serVal))
|
|
{
|
|
outVal = serVal;
|
|
}
|
|
}
|
|
return outVal;
|
|
}
|
|
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |