diff --git a/ax/SRC/A2012_UploadDocument.js b/ax/SRC/A2012_UploadDocument.js
new file mode 100644
index 0000000..c0266b4
--- /dev/null
+++ b/ax/SRC/A2012_UploadDocument.js
@@ -0,0 +1,98 @@
+// --------------------------------------------------------------------------------------
+// A2012_UploadDocument.js
+// Copyright 2020 SG|facilitor. 053-4800 700, helpdesk@mareon.nl
+// Written by MB (2020)
+//
+
+
+function A2012_UploadDocument (v_base64_str)
+{
+ var v_API = "api/v0.2/UploadDocumentFileBase64";
+
+ var l_json_data =
+ {
+ base64: v_base64_str
+ }
+
+ var v_req = JSON.stringify(l_json_data, null, 2);
+ var v_type = 0;
+ var v_soapAction = "";
+ var v_discard_active_abort = 1; //In geval van 500-error, geen active abort...
+ var v_resp = api_AX2(v_API, v_req, v_type, v_soapAction, v_discard_active_abort);
+
+ //Response v_resp is iets als dit:
+ //{
+ // "checksum": "ouWe2rfVjQXRItrYVAh8zBLgXkK33c3fTvsW7eUaXJc1"
+ //}
+ return v_resp;
+}
+
+
+function A2012_GetCheckSum_UploadDocument(p_json_text){
+ v_checksum = "";
+ if (p_json_text){
+ p_json = eval("(" + p_json_text + ")");
+ v_checksum = p_json.checksum;
+ }
+ __Log("A2012_GetCheckSum_UploadDocument v_checksum: " + v_checksum, 3);
+ return v_checksum;
+}
+
+// v_company_id, unieke id van (interne) bedrijf
+// v_entityname, b.v. ServiceTask of PurchaseOrder, in dit geval altijd op nivo van PurchaseOrder
+// v_entityid, b.v. MLD15009954-01 (Servicetask) of ION123456 (PurchaseOrder)
+// v_checksum, een reeks (string) die AX via A_UploadDocument teruggeeft, en hier moet worden gebruikt.
+// v_filename, naam van het te uploaden bestand, b.v test.png
+// v_description, omschrijving van het bestand
+// v_notes, een bijbehorende notitie.
+function A2012_CreateDocuRefByEntityName (v_company_id, v_entityname, v_entityid, v_checksum, v_filename, v_notes)
+{
+
+ var v_API = "api/v0.1/" + v_company_id + "/DocumentReferences";
+
+ var l_file_without_ext = MARX_substr(v_filename,".",1);
+
+ var l_json_data =
+ {entityName: v_entityname,
+ entityId: v_entityid,
+ documentReference:
+ {name: l_file_without_ext,
+ notes: v_notes,
+ docuTypeId: "Mareon",
+ fileName: v_filename,
+ checksum: v_checksum
+ }
+ }
+
+
+//Voorbeeld:
+// {"entityName": "ServiceTask",
+// "entityId": "MLD15009954-01",
+// "documentReference":
+// {"name": "omschrijving van het testbestand",
+// "notes": "notitie",
+// "docuTypeId": "Mareon",
+// "fileName": "Testbestand.png",
+// "checksum": "fGd0DavlPXvhM6wVgHM-zpSGM7R0h8q9xJkIzf3leIk1"
+// }
+// }
+
+
+ var v_req = JSON.stringify(l_json_data, null, 2);
+ var v_type = 0;
+ var v_soapAction = "";
+ var v_discard_active_abort = 1; //In geval van 500-error, geen active abort...
+ var v_resp = api_AX2(v_API, v_req, v_type, v_soapAction, v_discard_active_abort);
+
+//Hieronder is een voorbeeld van de bericht body te zien
+// {"entityName": "ServiceTask",
+// "entityId": "MLD15009954-01",
+// "documentReference": {"name": "Voorbeeld.txt",
+// "notes": "Voorbeeld via webservice",
+// "docuTypeId": "Bestand",
+// "filename": "Voorbeeld.txt",
+// "checksum": "89N3v4fkPjSQ5IgkZSEmou6GOjOdiUPRBfFC5tseejI1" } }
+
+
+return v_resp;
+}
diff --git a/ax/SRC/A365_GetToken.js b/ax/SRC/A365_GetToken.js
index 4a7925d..f8cdd0e 100644
--- a/ax/SRC/A365_GetToken.js
+++ b/ax/SRC/A365_GetToken.js
@@ -4,18 +4,31 @@
// Written by MB (2019)
//
+function A365_GetToken (){
+ return MARX_GetToken();
+}
-function A365_GetToken ()
+function A2012_GetToken (){
+ return MARX_GetToken();
+}
+
+function MARX_GetToken ()
{
- l_request_body = "client_id=" + G_MS_client_id
- + "&client_secret=" + G_MS_client_secret
- + "&grant_type=" + G_MS_grant_type
- + "&resource=" + G_MS_resource
+ l_request_body = "client_id=" + G_ID_client_id
+ + "&client_secret=" + G_ID_client_secret
+ + "&grant_type=" + G_ID_grant_type;
+ // G_ID_resource is optioneel, in geval van AX365 is derze wel gevuld (en in AX2012 niet)
+ if (G_ID_resource != "")
+ l_request_body = l_request_body + "&resource=" + G_ID_resource;
+ // G_ID_scope is optioneel, in geval van AX365 is deze LEEG en in AX2012 is deze gevuld
+ if (G_ID_scope != "")
+ l_request_body = l_request_body + "&scope=" + G_ID_scope;
+
var v_type = 1;
var v_contenttype = "application/x-www-form-urlencoded";
- __Log("A365_GetToken: Nieuwe token opgehaald" ,2);
- var v_resp = apiMS(G_MS_url, l_request_body, v_type, v_contenttype, 0);
+ __Log("MARX_GetToken: Nieuwe token opgehaald" ,2);
+ var v_resp = apiIDentity(G_ID_url, l_request_body, v_type, v_contenttype, 0);
var json_resp = JSON.parse(v_resp);
var v_token = json_resp.access_token;
diff --git a/ax/SRC/AxFacilitor.js b/ax/SRC/AxFacilitor.js
index 3307d9c..97676da 100644
--- a/ax/SRC/AxFacilitor.js
+++ b/ax/SRC/AxFacilitor.js
@@ -79,6 +79,9 @@ function AX2012_2_FCLT_Opdrachten(){
A2012_GetOpdrachten();
}
+function FCLT_2_AX2012_Bijlagen(){
+ F_GetOpdrachten_Bijlagen();
+}
function FCLT_2_AX2012_OpmerkingOpdrachten(){
F_GetOpdrachten_Opmerking();
}
@@ -289,6 +292,27 @@ function Ax2012_2_FACILITOR()
__Log("*** Communicatie logboek UIT", 2);
}
+ if (G_mar_sync_bijlages_naar_opdrgvr != '0'){
+ __Log("*** START FCLT --> AX2012 : Bijlagen bij opdrachten uit Mareon naar AX ***", 2);
+
+
+ //Bijlages naar AX2012 kan alleen via Token icm Saxton AX-webservice(s). Op soortgelijke (bijna identieke wijze) als AX365.
+ //---------------
+ __Log("*** START AX2012 --> FCLT : Get Token ***", 2);
+ G_Token = ReadTokenFromFile();
+ __Log("G_Token ReadTokenFromFile:" + G_Token, 4);
+ if (G_Token == ""){
+ __Log("G_Token ReadTokenFromFile is leeg:", 4);
+ G_Token = A2012_GetToken();
+ }
+ __Log("*** END Get Token", 2);
+ //---------------
+
+
+ FCLT_2_AX2012_Bijlagen();
+ __Log("*** END", 2);
+ }
+
__Log("*** START FCLT --> AX2012 : Afgemelde opdrachten uit Facilitor naar AX ***", 2);
FCLT_2_AX2012_AfgemeldeOpdrachten();
__Log("*** END", 2);
@@ -494,11 +518,12 @@ var G_ax_succeededfolder = Read_Ini_Setting("xtractor", "succeededfolder");
var G_ax_rejectedfolder = Read_Ini_Setting("xtractor", "rejectedfolder");
// Microsoft Token instellingen
-var G_MS_url = Read_Ini_Setting("microsoft","token/url");
-var G_MS_client_id = Read_Ini_Setting("microsoft","token/client_id");
-var G_MS_client_secret = Read_Ini_Setting("microsoft","token/client_secret");
-var G_MS_grant_type = Read_Ini_Setting("microsoft","token/grant_type");
-var G_MS_resource = Read_Ini_Setting("microsoft","token/resource");
+var G_ID_url = Read_Ini_Setting("identityserver","token/url");
+var G_ID_client_id = Read_Ini_Setting("identityserver","token/client_id");
+var G_ID_client_secret = Read_Ini_Setting("identityserver","token/client_secret");
+var G_ID_grant_type = Read_Ini_Setting("identityserver","token/grant_type");
+var G_ID_resource = Read_Ini_Setting("identityserver","token/resource");
+var G_ID_scope = Read_Ini_Setting("identityserver","token/scope");
// Mareon instellingen, de term (XML node) "facilitor" is ivm historie cq. alle locale installaties bij woco's niet 1-2-3 aan te passen in de veel logischere term mareon.
var G_marx_url = Read_Ini_Setting("facilitor","url");
@@ -524,7 +549,7 @@ var G_mar_timeout = 0; //initieel 1e keer.
__Log("***XML- rems/opdrachtenfolder: " + G_rems_opdracht_xmlfolder, 1);
__Log("***XML- rems/opdrachtstatusfolder: " + G_rems_opdrachtstatus_xmlfolder, 1);
__Log("***XML- rems/facturenfolder: " + G_rems_facturen_xmlfolder, 1);
- __Log("***XML- microsoft/token/url: " + G_MS_url, 1);
+ __Log("***XML- microsoft/token/url: " + G_ID_url, 1);
__Log("***XML- mareon/url: " + G_marx_url, 1);
__Log("***XML- xtractor/xmlfolder: " + G_ax_xtractorfolder, 1);
__Log("***XML- xtractor/pdffolder: " + G_pdf_xtractorfolder, 1);
diff --git a/ax/SRC/AxFacilitor.xml b/ax/SRC/AxFacilitor.xml
index 5b2629e..e6e4790 100644
--- a/ax/SRC/AxFacilitor.xml
+++ b/ax/SRC/AxFacilitor.xml
@@ -28,7 +28,7 @@
http://emmpc0003.sg.nl:8087/MicrosoftDynamicsAXAif60/MSMSupplierPortalHttp/xppservice.svc
- http://serviceax2012-dev.aareon.nl
+ https://saxton-test.aareoncloud.nl
sg\robb
@@ -44,15 +44,16 @@
1
-
+
+
-
+
https://xxxx.facilitor.nl/
diff --git a/ax/SRC/Common.js b/ax/SRC/Common.js
index 47840b7..5a3745f 100644
--- a/ax/SRC/Common.js
+++ b/ax/SRC/Common.js
@@ -269,7 +269,7 @@ function apiAX_GENERAL (v_API, v_req, v_type, v_soapAction, v_discard_active_abo
{
switch (v_soort_api){
case 1: var v_url = G_ax2012_url; break;
- case 2: var v_url = G_ax2012_url_serviceax; break;
+ case 2: var v_url = G_ax2012_url_serviceax + "/" + v_API; break;
}
l_result = api2_AX2012_inner(v_url, v_API, v_req, v_type, v_soapAction, v_discard_active_abort, v_soort_api);
}
@@ -370,6 +370,11 @@ function api2_AX2012_RequestXML(p_url, p_api, p_req_xml){
return v_msg;
}
+function api2_AX2012_RequestJSON(p_url, p_api, p_req_json){
+ var v_msg = p_req_json;
+ return v_msg;
+}
+
function api2_AX365_RequestXML(p_url, p_api, p_req_xml){
var v_msg = ' '+
'' +
@@ -502,11 +507,21 @@ function api2_AX2012_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_discard
xmlhttp.setProxy(SXH_PROXY_SET_PROXY, proxy);
xmlhttp.open("POST", v_Url, false);
- xmlhttp.setRequestHeader("Content-Type", "text/xml"),
- xmlhttp.setRequestHeader("Authorization", "Basic " + G_ax2012_bcProxy),
- xmlhttp.setRequestHeader("SOAPAction", '"http://tempuri.org/'+v_soapAction+'"');
-
- var v_msg = api2_AX2012_RequestXML(v_Url, v_API, v_req);
+
+ if (v_soort_api == 1){
+ xmlhttp.setRequestHeader("Content-Type", "text/xml");
+ xmlhttp.setRequestHeader("Authorization", "Basic " + G_ax2012_bcProxy);
+ xmlhttp.setRequestHeader("SOAPAction", '"http://tempuri.org/'+v_soapAction+'"');
+ var v_msg = api2_AX2012_RequestXML(v_Url, v_API, v_req);
+ }
+ if (v_soort_api == 2){
+ xmlhttp.setRequestHeader("Content-Type", "application/json"),
+ __Log("api2_AX2012_inner G_Token: " + G_Token, 4);
+ xmlhttp.setRequestHeader("Authorization", "Bearer " + G_Token);
+ //xmlhttp.setRequestHeader("SOAPAction", '"http://tempuri.org/'+v_soapAction+'"');
+ var v_msg = api2_AX2012_RequestJSON(v_Url, v_API, v_req);
+ }
+
__Log("api2_AX2012_inner v_msg: " + v_msg, 4);
if (G_mar_timeout != 0){
@@ -555,18 +570,43 @@ function api2_AX2012_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_discard
}
}
else
- { __Log("api2_AX2012_inner XML Response = FALSE :",1);
+ { __Log("api2_AX2012_inner XML Response = FALSE :",1);
__Log("api2_AX2012_inner - HTTP <> 2xx",1);
__Log("api2_AX2012_inner URL: " + v_Url,1);
__Log("api2_AX2012_inner Message: " + v_msg,1);
__Log("api2_AX2012_inner Status: "+ xmlhttp.status + " " + xmlhttp.statusText,1);
- __Log("api2_AX2012_inner ResponseText:" + xmlhttp.responseText,1);
- if (G_abort_http_error == 1)
- {
- MARXQUIT(v_discard_active_abort);
+ l_resp = xmlhttp.responseText;
+ __Log("api2_AX2012_inner ResponseText:" + l_resp,1);
+
+
+ if (xmlhttp.status == 401){
+ // Token expired? Kan heel goed mogelijk zijn, token heeft geldigheid van uur
+ // In dit geval wordt een HTTP 401 (Unautorized) geretourneerd, (itt AX365, die doet HTTP-500)
+
+ // Forbidden gevonden, we doen een retry, door een nieuwe token op te halen / op te vragen, max. 3 x in een sync (G_AX365_Allowed_Get_Token > 0)
+ if (G_AX365_Allowed_Get_Token > 0){
+ G_AX365_Allowed_Get_Token = G_AX365_Allowed_Get_Token - 1;
+ G_Token = A365_GetToken();
+ // We mogen nu de functie zelf nog eens aanroepen (iteratief).
+ l_result = api2_AX2012_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_discard_active_abort, v_soort_api);
+ return l_result;
+ }
+ else{
+ __Log("api2_AX2012_inner: Token problem, maximum van 3 pogingen zijn allemaal mislukt" ,1);
+ if (G_abort_http_error == 1)
+ {
+ MARXQUIT(v_discard_active_abort);
+ }
+ return {api_status_code: 0, api_status_message: xmlhttp.statusText, api_response_message: txt};
+ }
}
- return {api_status_code: 0, api_status_message: xmlhttp.statusText, api_response_message: txt};
- //return ""
+ else{
+ if (G_abort_http_error == 1)
+ {
+ MARXQUIT(v_discard_active_abort);
+ }
+ return {api_status_code: 0, api_status_message: xmlhttp.statusText, api_response_message: txt};
+ }
}
}
@@ -667,7 +707,7 @@ function api2_AX365_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_discard_
G_AX365_Allowed_Get_Token = G_AX365_Allowed_Get_Token - 1;
G_Token = A365_GetToken();
// We mogen nu de functie zelf nog eens aanroepen (iteratief).
- l_result = api2_AX365_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_soort_api);
+ l_result = api2_AX365_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_discard_active_abort, v_soort_api);
return l_result;
}
else{
@@ -690,24 +730,25 @@ function api2_AX365_inner (v_Url, v_API, v_req, v_type, v_soapAction, v_discard_
//return ""
}
}
- if (G_abort_http_error == 1)
- {
- MARXQUIT(v_discard_active_abort);
- }
- return {api_status_code: 0, api_status_message: xmlhttp.statusText, api_response_message: txt};
- //return ""
+ else {
+ if (G_abort_http_error == 1)
+ {
+ MARXQUIT(v_discard_active_abort);
+ }
+ return {api_status_code: 0, api_status_message: xmlhttp.statusText, api_response_message: txt};
+ }
}
}
-function apiMS (v_url, v_req, v_type, v_contenttype, v_discard_active_abort)
+function apiIDentity (v_url, v_req, v_type, v_contenttype, v_discard_active_abort)
{
- __Log("apiMS v_url: " + v_url, 3);
- __Log("apiMS v_req: " + v_req, 3);
- __Log("apiMS v_type: " + v_type, 3);
- __Log("apiMS v_discard_active_abort: " + v_discard_active_abort, 3);
+ __Log("apiIDentity v_url: " + v_url, 3);
+ __Log("apiIDentity v_req: " + v_req, 3);
+ __Log("apiIDentity v_type: " + v_type, 3);
+ __Log("apiIDentity v_discard_active_abort: " + v_discard_active_abort, 3);
var lResolve = 0;
var lConnect = 60 * 1000;
@@ -733,7 +774,7 @@ function apiMS (v_url, v_req, v_type, v_contenttype, v_discard_active_abort)
catch (e)
{
//MARX#57502: AX Adapter robuuster maken: Waarschijnlijk timeout-error
- __Log("apiMS failed/timeout: " + e.description,1);
+ __Log("apiIDentity failed/timeout: " + e.description,1);
if (G_abort_http_error == 1)
{
MARXQUIT(v_discard_active_abort);
@@ -746,20 +787,20 @@ function apiMS (v_url, v_req, v_type, v_contenttype, v_discard_active_abort)
try
{ var txt = xmlhttp.responseText;
- __Log("apiMS Response :" + txt, 3);
+ __Log("apiIDentity Response :" + txt, 3);
return txt;
}
catch (e)
{
// Waarschijnlijk http-error terug gekregen
- __Log("apiMS failed: " + e.description,1);
+ __Log("apiIDentity failed: " + e.description,1);
__Log(txt,1);
return "";
}
}
else
- { __Log("apiMS - HTTP <> 2xx",1);
+ { __Log("apiIDentity - HTTP <> 2xx",1);
__Log("URL: " + v_url,1);
__Log("Request: " + v_req,1);
__Log("Status: "+ xmlhttp.status + " " + xmlhttp.statusText,1);
diff --git a/ax/SRC/FCLT_GetOpdrachtBijlages.js b/ax/SRC/FCLT_GetOpdrachtBijlages.js
index 17b2e77..5cc3f0a 100644
--- a/ax/SRC/FCLT_GetOpdrachtBijlages.js
+++ b/ax/SRC/FCLT_GetOpdrachtBijlages.js
@@ -33,7 +33,14 @@ function MARX_2_AX_PutOpdrachtBijlages(v_ax_company_id, v_mld_opdr_key_marx, v_m
var v_aantal_bestanden = FCLT_or_MARX_PutOpdrachtBijlages(G_marx_url, G_marx_apikey, v_mld_opdr_key_marx, "", v_ax_company_id, v_mld_opdr_externnr, "28", "", "MARX_2_AX", v_fac_bijlagen_filename);
return v_aantal_bestanden;
}
-
+// Parameters:
+// v_mld_opdr_key_marx: key van mld_opdr in Mareon
+// v_mld_opdr_key_ax: IONR (key) van inkooporder in AX (2012) omgeving
+function MARX_2_AX2012_PutOpdrachtBijlages(v_ax_company_id, v_mld_opdr_key_marx, v_mld_opdr_externnr, v_fac_bijlagen_filename)
+{
+ var v_aantal_bestanden = FCLT_or_MARX_PutOpdrachtBijlages(G_marx_url, G_marx_apikey, v_mld_opdr_key_marx, "", v_ax_company_id, v_mld_opdr_externnr, "28", "", "MARX_2_AX2012", v_fac_bijlagen_filename);
+ return v_aantal_bestanden;
+}
function FCLT_or_MARX_PutOpdrachtBijlages(v_url_bron, v_apikey_bron, v_mld_opdr_key_bron, v_url_dest, v_apikey_dest, v_mld_opdr_key_dest, v_mld_kenmerk_key_bron, v_mld_kenmerk_key_dest, v_src_2_dest, v_fac_bijlagen_filename)
{
@@ -91,6 +98,17 @@ function FCLT_or_MARX_PutOpdrachtBijlages(v_url_bron, v_apikey_bron, v_mld_opdr_
__Log("FCLT_or_MARX_PutOpdrachtBijlages warning: checksum not returned by Tobias AX 2009",1);
}
}
+ if (v_src_2_dest == "MARX_2_AX2012") {
+ var v_resp_json_str = A2012_UploadDocument (v_base64_str);
+ var v_checksum = A2012_GetCheckSum_UploadDocument(v_resp_json_str);
+ if (v_checksum != ""){
+ // v_company_id, v_entityname, v_entityid , v_checksum, v_filename, v_notes);
+ A2012_CreateDocuRefByEntityName (v_apikey_dest, "PurchaseOrder", v_mld_opdr_key_dest, v_checksum, l_filename, "");
+ }
+ else{
+ __Log("FCLT_or_MARX_PutOpdrachtBijlages warning: checksum not returned by Tobias AX 2012",1);
+ }
+ }
if ((v_src_2_dest == "FCLT_2_MARX") || (v_src_2_dest == "MARX_2_FCLT")) {
// Van Facilitor naar Mareon OF van Mareon naar Facilitor
var l_kenmerk_arr = v_mld_kenmerk_key_dest.split(",");
diff --git a/ax/SRC/F_GetOpdrachtenBijlagen.js b/ax/SRC/F_GetOpdrachtenBijlagen.js
index 0292e86..9539ff6 100644
--- a/ax/SRC/F_GetOpdrachtenBijlagen.js
+++ b/ax/SRC/F_GetOpdrachtenBijlagen.js
@@ -47,6 +47,9 @@ function F_GetOpdrachten_Bijlagen()
if (AX_or_Tobias() == "A") {
MARX_2_AX_PutOpdrachtBijlages(v_ax_company_id, v_mld_opdr_key_marx, v_mld_opdr_externnr, v_fac_bijlagen_filename);
}
+ if (AX_or_Tobias() == "A12") {
+ MARX_2_AX2012_PutOpdrachtBijlages(v_ax_company_id, v_mld_opdr_key_marx, v_mld_opdr_externnr, v_fac_bijlagen_filename);
+ }
if (AX_or_Tobias() == "F") {
MARX_2_FCLT_PutOpdrachtBijlages(v_mld_opdr_key_marx, v_mld_opdr_key_fclt, v_fac_bijlagen_filename);
}