Custom RunBaseBatch class to import electronic invoices.#SADA => A_ImportEInvoiceA_ImportEInvoice.PNG
// This is a framework class. Customizing this class may cause problems with future upgrades to the software.
class A_ImportEInvoice extends RunBaseBatch
{
// Packed variables
UserName user;
str password;
str access_token,user_id;
FromDate fromDate;
ToDate toDate;
// Dialog fields
DialogField dlgUser;
DialogField dlgPassword;
DialogField dlgFromDate;
DialogField dlgToDate;
#define.CurrentVersion(2)
#define.Version1(2)
#localmacro.CurrentList
user,
password,
fromDate,
toDate
#endmacro
}
/// <summary>
/// Indicates whether the class is shown in the list of <c>Journal</c> types.
/// </summary>
/// <returns>
/// true if the class is shown in the list of <c>Journal</c> types; otherwise, false.
/// </returns>
/// <remarks>
/// A class that can be used in a batch journal is a class where the same parameters can be used
/// repeatedly. The dialog box can be shown and the parameters can be changed, but parameters of some
/// classes might build on data that is only valid for a short time. Running a class two times with the
/// same parameters is not always possible. If the <c>RunBaseBatch.canGoBatch</c> method is false, this
/// method will not have any effect.
/// </remarks>
public boolean canGoBatchJournal()
{
return true;
}
private System.String connect()
{
System.Net.WebRequest requestlogin;
System.Net.WebResponse responseLogin;
System.String postDataLogin, stringResponseLogin;
System.Byte[] byteArrayLogin;
System.Text.Encoding utf8;
System.IO.Stream requestStreamLogin, responseStreamLogin;
System.IO.StreamReader streamReaderLogin;
str strRequestLogin;
strRequestLogin = A_RquestImportEinvoiceFileParameters::find().URLLogin;//"https://e-invoice7.conserva.cloud/api/v1/auth/";
requestlogin = System.Net.WebRequest::Create(strRequestLogin);
requestlogin.set_Method("POST");
postDataLogin = strFmt(A_RquestImportEinvoiceFileParameters::find().StrLogin,user,Password);
//postDataLogin = "{\"username\":\"alteanet\",\"password\":\"Acitorio1234\"}";
utf8 = System.Text.Encoding::get_UTF8();
byteArrayLogin = utf8.GetBytes(postDataLogin);
requestlogin.set_ContentType("application/json");
requestlogin.set_ContentLength(byteArrayLogin.get_Length());
requestStreamLogin = requestlogin.GetRequestStream();
requestStreamLogin.Write(byteArrayLogin,0,byteArrayLogin.get_Length());
responseLogin = requestlogin.GetResponse();
responseStreamLogin = responseLogin.GetResponseStream();
streamReaderLogin = new System.IO.StreamReader(responseStreamLogin);
stringResponseLogin = streamReaderLogin.ReadToEnd();
return stringResponseLogin;
}
/// <summary>
/// Returns a class that contains the methods that are described by the <c>RunBaseDialogable</c>
/// interface.
/// </summary>
/// <returns>
/// A class that contains the methods that are described by the <c>RunBaseDialogable</c> interface.
/// </returns>
/// <remarks>
/// A dialog box can be either built by using the <c>Dialog</c> class or by using a class that is
/// created in the Application Object Tree (AOT).
/// </remarks>
public Object dialog()
{
DialogRunbase dialog = super();
DialogGroup dlgGroup;
#resAppl
;
dlgGroup = dialog.addGroup("Credenziali di accesso");
dlgGroup.columns(3);
dialog.addImage(#ImageEmployee);
dlgUser = dialog.addField(extendedTypeStr(UserName));
dlgPassword = dialog.addField(extendedTypeStr(Password));
dlgGroup = dialog.addGroup("Data ricevimento files");
dlgGroup.columns(3);
dialog.addImage(#ImageProfileCalendar);
dlgFromDate = dialog.addField(extendedTypeStr(FromDate));
dlgToDate = dialog.addField(extendedTypeStr(ToDate));
return dialog;
}
public void dialogPostRun(DialogRunbase dialog)
{
;
super(dialog);
}
private void findAcces(System.String _stringResponseLogin)
{
container conResponseLogin, testCont;
str conLineValue;
int positionFind,conLength,conLengthLine,i;
str strRequestLogin, test;
conResponseLogin = str2con(_stringResponseLogin);
for (i = 1 ; i <= conLen(conResponseLogin) ; i++)
{
conLineValue = conPeek(conResponseLogin, i);
conLengthLine = strLen(conLineValue);
if(subStr(conLineValue,1,23) == '"data":{"access_token":')
{
access_token = substr(conLineValue,24,conLengthLine);
access_token = strRem(access_token,'"');
continue;
}
if(subStr(conLineValue,1,10) == '"user_id":')
{
user_id = substr(conLineValue,11,conLengthLine);
}
if(access_token && user_id)
{
break;
}
}
}
public boolean getFromDialog()
{
;
user = dlgUser.value();
password = dlgPassword.value();
fromDate = dlgFromDate.value();
toDate = dlgToDate.value();
return super();
}
private void importInvoice()
{
System.Net.WebRequest requestInvoiceList;
System.Net.WebResponse responseInvoiceList;
System.String postDataInvoiceList, stringResponseInvoiceList;
System.Byte[] byteArrayInvoiceList;
System.IO.Stream requestStreamInvoiceList, responseStreamInvoiceList;
System.IO.StreamReader streamReaderInvoiceList;
System.Net.WebHeaderCollection headerInvoiceList = new System.Net.WebHeaderCollection();
container conResponseInvoiceList,conResponseInvoices;
str strRequestInvoiceList;
CLRObject CLRObject;
System.Exception e;
Map getData, dataMap;
container data,operationSet, operation, dataCont,conNumRows, conData, conInvoice,conFileDownloaded,conFileNotDownloaded;
str result,invoiceID,fileName,originalFilename;
Filename filepath;
Filename fileExt;
int num, num2, pos = 1,numRow, numData, endData,FileDownloaded,FileNotDownloaded,i;
#file
str convertDate(InvoiceDate _date)
{
return date2str(_date,321,2,DateSeparator::Hyphen,2,DateSeparator::Hyphen,4) ;
}
;
headerInvoiceList.Add('einvauth', access_token);
strRequestInvoiceList = strfmt('https://e-invoice7.conserva.cloud/api/v1/users/%1/invoices/p?lastKeyVal=&pageSize=12&pagination=true&page=1&searchFilter={"metadata":[{"index":0,"name":"DataRicezione","label":"Data Ricezione","data_type":"d","input_type":"text","options_list":[],"value":["2019-10-01T00:00:00.000Z","2019-12-01T00:00:00.000Z"],"required":false,"id":1}],"workflow_id":"","workflow_state_code":[""]}',user_id);
strRequestInvoiceList = strfmt(A_RquestImportEinvoiceFileParameters::find().URLInvoiceList,user_id,convertdate(fromDate),convertdate(toDate));
//strRequestInvoiceList = strfmt('https://e-invoice7.conserva.cloud/api/v1/users/%1/invoices/p?lastKeyVal=&pageSize=12&pagination=true&page=1',user_id);
CLRObject = System.Net.WebRequest::Create(strRequestInvoiceList);
requestInvoiceList = CLRObject;
requestInvoiceList.set_Headers(headerInvoiceList);
requestInvoiceList.set_Method("GET");
requestInvoiceList.set_ContentType("application/json");
responseInvoiceList = requestInvoiceList.GetResponse();
requestStreamInvoiceList = responseInvoiceList.GetResponseStream();
streamReaderInvoiceList = new System.IO.StreamReader(requestStreamInvoiceList);
stringResponseInvoiceList = streamReaderInvoiceList.ReadToEnd();
getData = RetailCommonWebAPI::getMapFromJsonString(stringResponseInvoiceList);
if (getData.exists('data'))
{
operationSet = getData.lookup('data');
}
numRow = A_ImportEinvoice::recuperaValore(operationSet, "totalRows");
conData = A_ImportEinvoice::recuperaContainer(operationSet, "data");
endData = conLen(conData);
info(strFmt("@SAD504",numRow));
for(num = 1 ; num<=numRow ; num++)
{
conInvoice = conPeek(conData,endData);
invoiceID = A_ImportEinvoice::recuperaValore(conInvoice, "id");
fileName = A_ImportEinvoice::recuperaValore(conInvoice, "file_name");
originalFilename = fileName;
fileExt = strMin();
while (fileExt != #xml)
{
[filepath,fileName,fileExt] = fileNameSplit(fileName);
}
fileName = fileName + #xml;
try
{
this.importSingleInvoice(invoiceID,fileName);
conFileDownloaded = conIns(conFileDownloaded,1,originalFilename);
FileDownloaded++;
endData--;
}
catch
{
conFileNotDownloaded = conIns(conFileNotDownloaded,1,originalFilename);
FileNotDownloaded++;
endData--;
continue;
}
}
i = 1;
if(conLen(conFileDownloaded))
{
setPrefix(strFmt("%1 file scaricati"));
for (i = 1 ; i <= conLen(conFileDownloaded) ; i++)
{
info(conPeek(conFileDownloaded,i));
}
}
i = 1;
if(conLen(conFileNotDownloaded))
{
setPrefix(strFmt("%1 file non scaricati"));
for (i = 1 ; i <= conLen(conFileNotDownloaded) ; i++)
{
info(conPeek(conFileNotDownloaded,i));
}
}
}
private void importSingleInvoice(str _invoiceID, str _fileName)
{
System.Net.WebRequest requestInvoiceList;
System.Net.WebResponse responseInvoiceList;
System.String postDataInvoiceList, stringResponseInvoiceList;
System.Byte[] byteArrayInvoiceList;
System.IO.Stream requestStreamInvoiceList, responseStreamInvoiceList;
System.IO.StreamReader streamReaderInvoiceList;
System.Net.WebHeaderCollection headerInvoiceList = new System.Net.WebHeaderCollection();
container conResponseInvoiceList,conResponseInvoices;
str strRequestInvoiceList;
CLRObject CLRObject;
System.Exception e;
Map getData, dataMap;
container data,operationSet, operation, dataCont,conNumRows, conData, conInvoice;
str result;
int num, num2, pos = 1,numRow, numData, endData ;
str strBase64;
DocuValueFile docuValueFile;
DocuRef docuRef;
DocuValue docuValue;
BinData binData = new BinData();
System.Exception ex;
container content;
headerInvoiceList.Add('einvauth', access_token);
strRequestInvoiceList = strFmt(A_RquestImportEinvoiceFileParameters::find().URLSingleInvoiceList,user_id,_invoiceID);
CLRObject = System.Net.WebRequest::Create(strRequestInvoiceList);
requestInvoiceList = CLRObject;
requestInvoiceList.set_Headers(headerInvoiceList);
requestInvoiceList.set_Method("GET");
requestInvoiceList.set_ContentType("application/json");
responseInvoiceList = requestInvoiceList.GetResponse();
requestStreamInvoiceList = responseInvoiceList.GetResponseStream();
streamReaderInvoiceList = new System.IO.StreamReader(requestStreamInvoiceList);
stringResponseInvoiceList = streamReaderInvoiceList.ReadToEnd();
//this.strunz(stringResponseInvoiceList);
//content = RetailCommonWebAPI::
//content = str2con(stringResponseInvoiceList,":");
//this.strunz(conPeek(content,5));
try
{
getData = RetailCommonWebAPI::getMapFromJsonString(stringResponseInvoiceList);
}
//SN_IDALMASSO: Questa roba qui funziona, catcha l'eccezione SOLO rimuovendo il ttsbegin/ttscommit in metodo run.
//(In realtà secondo me quel ttsbegin/commit è un po' un eccesso di zelo, probabilmente si può cambiare di posizione e metterlo più all'interno nella classe)
//Però ci permette di capire dove sta l'errore nel caso
catch (Exception::CLRError)
{
ex = ClrInterop::getLastException();
if (ex != null)
{
ex = ex.get_InnerException();
if (ex != null)
{
error(ex.ToString());
}
}
}
if (getData.exists('data'))
{
operationSet = getData.lookup('data');
}
strBase64 = A_ImportEInvoice::recuperaValore(operationSet,"content");
AifUtil::saveBase64ToFile(A_PurchEinvoiceParameters::find().PathUploadInvoice + _fileName, strBase64);
}
public boolean init()
{
return true;
}
protected void new()
{
super();
}
public container pack()
{
return [#CurrentVersion,#CurrentList];
}
/// <summary>
/// Contains the code that does the actual job of the class.
/// </summary>
public void run()
{
System.String stringResponseLogin;
#OCCRetryCount
if (! this.validate())
throw error("");
try
{
ttsbegin;
stringResponseLogin = this.connect();
this.findAcces(stringResponseLogin);
this.importInvoice();
ttscommit;
}
catch (Exception::Deadlock)
{
retry;
}
catch (Exception::UpdateConflict)
{
if (appl.ttsLevel() == 0)
{
if (xSession::currentRetryCount() >= #RetryNum)
{
throw Exception::UpdateConflictNotRecovered;
}
else
{
retry;
}
}
else
{
throw Exception::UpdateConflict;
}
}
}
public boolean runsImpersonated()
{
return true;
}
public boolean unpack(container packedClass)
{
Version version = RunBase::getVersion(packedClass);
;
switch (version)
{
case #CurrentVersion:
[version,#CurrentList] = packedClass;
break;
default:
return false;
}
return true;
}
public boolean validate(Object _calledFrom = null)
{
if(!fromDate || !toDate)
{
return checkFailed("Entrambe le date sono obbligatorie");
}
if(fromDate > toDate)
{
return checkFailed("Date non valide");
}
return true;
}
server static A_ImportEInvoice construct()
{
return new A_ImportEInvoice();
}
// Here goes a description of the class
static ClassDescription description()
{
return "Importazione fatture fornitore da web";
}
static void main(Args args)
{
A_ImportEinvoice A_ImportEinvoice;
;
A_ImportEinvoice = A_ImportEinvoice::construct();
if (A_ImportEinvoice.prompt())
A_ImportEinvoice.run();
}
server static anytype recuperaContainer(container _con,str _label)
{
int posLocal;
container conLocal;
posLocal = conFind(_con, _label);
return conPeek(_con,posLocal+1);
}
server static anytype recuperaValore(container _con,str _label)
{
int posLocal;
container conLocal;
posLocal = conFind(_con, _label);
conLocal = conPeek(_con,posLocal+1);
return conPeek(conLocal,1);
}