Files
Facilitor/APPL/MARX/API_mareon_opdracht.asp
Jos Groot Lipman e774a40b51 MARX#82611 Is het mogelijk om bij verwerkingsfout een HTTP4xx code wordt teruggestuurd
svn path=/Website/trunk/; revision=64855
2024-05-28 14:52:57 +00:00

460 lines
18 KiB
Plaintext

<%@ language = "JavaScript" %>
<%
/*
$Revision$
$Id$
File: API_mareon_opdracht.asp
Description: API om (bekend formaat) opdracht (T365, SALES005, REMS, FCLT) te verwerken en realtime / direct te versturen
Parameters: Een xml
Status:
Context: Initiele opdracht (1) OF geupdate (meerwerk)opdracht (2) OF statusupdate ANN (3) van opdrachtgever naar opdrachtnemer.
Notes:
*/
DOCTYPE_Disable = 1;
THIS_FILE = "appl/marx/API_mareon_opdracht.asp";
%>
<!-- #include file="../../appl/Shared/common.inc" -->
<!-- #include file="../Shared/xml_converter.inc" -->
<!-- #include file="../api/api.inc" -->
<!-- #include file="../shared/putorders.inc" -->
<!-- #include file="../MARX/UploadBijlage.inc" -->
<!-- #include file="../../appl/api/api_gen_import.inc" -->
<script language="javascript" src="../imp/imp_shared.js" runat="server"></script>
<%
Session.Codepage = 65001;
Response.Charset = 'utf-8';
function xmlNodeVal(xml, strQuery)
{
var node = xml.selectSingleNode(strQuery);
if (node)
return node.text;
else
return null;
}
function xmlNodeVal_NS (p_xml, p_namespace, p_nodename)
{
var l_result;
if (p_namespace)
{
p_xml.setProperty ("SelectionNamespaces", p_namespace);
}
var l_result = xmlNodeVal(p_xml, p_nodename);
return (l_result);
}
function xmlNodeVal_NS_default (p_xml, p_namespace, p_nodename, p_default_value)
{
var l_result;
var l_result = xmlNodeVal_NS (p_xml, p_namespace, p_nodename);
if (l_result == null) l_result = p_default_value;
return (l_result);
}
function marx_get_mld_opdr_key (p_xml)
{ var l_mld_opdr_key;
var l_xml_query = "//mld_opdr_key";
var l_mld_opdr_key = xmlNodeVal(p_xml, l_xml_query);
return (l_mld_opdr_key);
}
function marx_get_teverzenden (p_mld_opdr_key)
{
var l_mld_opdr_teverzenden;
var l_mld_statusopdr_key;
if (p_mld_opdr_key){
var sql = "SELECT mld_opdr_teverzenden, mld_statusopdr_key FROM mld_opdr WHERE mld_opdr_key = " + p_mld_opdr_key;
var oRs = Oracle.Execute(sql);
if (!oRs.eof)
{
l_mld_opdr_teverzenden = oRs("mld_opdr_teverzenden").Value;
l_mld_statusopdr_key = oRs("mld_statusopdr_key").Value;
}
oRs.close();
}
if (l_mld_statusopdr_key == 1)
{ // als opdracht geannuleerd is, dan niet via Immediate putorders sturen, probleem is dat bugje zit bij annuleren, mld_opdr_teverzenden moet eerst NULL worden gemaakt, immediate zet de waarde daarna terug op 1 (en niet 2)!!
// dus uitsluiten vooralsnog, annuleren doen we via batch
return(0);}
else
{return(l_mld_opdr_teverzenden);}
}
function marx_put_null_teverzenden (p_mld_opdr_key)
{
if (p_mld_opdr_key)
{
// expliciet leeg maken zodat de force/immediate putorder wel werkt, die verwacht hem namelijk leeg. Ja? Ja!
// Ook beetje vreemd: een annuleren kan niet via immediate putorders, alleen via batch, hmmm?
var sql = "UPDATE mld_opdr SET mld_opdr_teverzenden = NULL WHERE mld_opdr_key = " + p_mld_opdr_key;
Oracle.Execute(sql);
}
}
function marx_get_puo_immediate ()
{
var l_puo_immediate = 0;
var sql = "SELECT LEAST(COALESCE(fac.safe_to_number(fac_usrdata_omschr),0),1) puo_immediate FROM fac_usrdata WHERE fac_usrtab_key = 1 AND fac_usrdata_upper = '$MARX_PUO_IMMEDIATE'";
var oRs = Oracle.Execute(sql);
if (!oRs.eof)
{
l_puo_immediate = oRs("puo_immediate").Value;
}
oRs.close();
return(l_puo_immediate);
}
function marx_force_putorders (p_mld_opdr_key)
{
// Veld teverzenden leeg maken, anders werkt immediate verzenden via sendMLDorders niet!
// En let op: als status geannuleerd is (afgewezen oftewel status = 1), dan werkt immediate putorders helemaal niet!!
// Dan kan die alleen maar via batch-putorders, inconsequent :-(
var l_result;
var l_teverzenden = marx_get_teverzenden (p_mld_opdr_key);
if (l_teverzenden)
{ // Mareon vindt dat de order kan worden verstuurd naar de (Premium)leverancier
marx_put_null_teverzenden (p_mld_opdr_key);
var l_result = putorders.sendMLDorders(p_mld_opdr_key);
if (!l_result)
{ // mld_opdr_teverzenden is op 1 gezet door sendMLDorders, putorders schedule probeert wel weer
__Log("lcl_puo_order_failfirst:");
}
}
}
function api_F_PutOpdr_Bijlage(p_mld_opdr_key, p_bestandsnaam, p_bijlage_base64, p_kenmerk_key)
{
__Log("Start api_F_PutOpdr_Bijlage: ");
var l_module = "MLD";
var l_niveau = "O";
marx_upload_bijlage(l_module, p_mld_opdr_key, p_kenmerk_key, l_niveau, p_bestandsnaam, p_bijlage_base64);
}
function marx_upload_rems_bijlages (p_mld_opdr_key, p_xml){
marx_upload_bijlages(p_mld_opdr_key, p_xml,"Document", "MediaId", "MediaType", "DocumentInhoud", 10, "ByTagName", null);
}
function marx_upload_fclt_bijlages (p_mld_opdr_key, p_xml){
marx_upload_bijlages(p_mld_opdr_key, p_xml,"TMP_Attachment", "name", "idontexist", "attachment", 10, "ByTagName", null);
}
function marx_upload_sales005_bijlages (p_mld_opdr_key, p_xml){
marx_upload_bijlages(p_mld_opdr_key, p_xml, "//sales005m:Attachment", "sales005m:FileName", "sales005m:FileType", "sales005m:AttachedData", 10, "BySelectNodes", "xmlns:sales005m='http://www.ketenstandaard.nl/onderhoudsopdracht/SALES/005'");
}
// p_xmlfetch_method = ByTagName or BySelectNodes
function marx_upload_bijlages (p_mld_opdr_key, p_xml, p_root_nodenaam, p_filenaam_nodenaam, p_filetype_nodenaam, p_base64_nodenaam, p_max_uploads, p_xmlfetch_method, p_namespace)
{
// Kenmerk-key in Mareon waarin de bijlagen terecht moet komen is key 20
var l_kenmerk_key = 20;
if (p_namespace)
{
p_xml.setProperty ("SelectionNamespaces", p_namespace);
}
if (p_mld_opdr_key)
{
if (p_xmlfetch_method == "ByTagName")
{
var nodes_doc = p_xml.getElementsByTagName(p_root_nodenaam);
__Log("# Document nodes : " + nodes_doc.length);
if (nodes_doc.length > 0)
{
for (i = 0; i < nodes_doc.length; i++) {
var l_bestandsnaam = null;
var l_bijlage_naam = null;
var l_bijlage_ext = null;
var l_bijlage_base64 = null;
var node_media_id = nodes_doc[i].getElementsByTagName(p_filenaam_nodenaam);
if (node_media_id.length !=0){
l_temp_node = node_media_id[0].childNodes[0];
if (l_temp_node){
l_bijlage_naam = node_media_id[0].childNodes[0].nodeValue;
__Log("l_bijlage_naam[" + i + "] : " + l_bijlage_naam);
l_bestandsnaam = l_bijlage_naam;
}
}
var node_media_type = nodes_doc[i].getElementsByTagName(p_filetype_nodenaam);
if (node_media_type.length !=0){
l_temp_node = node_media_type[0].childNodes[0];
if (l_temp_node){
l_bijlage_ext= node_media_type[0].childNodes[0].nodeValue;
__Log("p_filetype_nodenaam[" + i + "] : " + l_bijlage_ext);
l_bestandsnaam = l_bestandsnaam + "." + l_bijlage_ext;
}
}
var node_documentinhoud64 = nodes_doc[i].getElementsByTagName(p_base64_nodenaam);
if (node_documentinhoud64.length !=0){
l_temp_node = node_documentinhoud64[0].childNodes[0];
if (l_temp_node){
l_bijlage_base64 = node_documentinhoud64[0].childNodes[0].nodeValue;
if (l_bijlage_base64){
__Log("l_bijlage_base64[" + i + "] : " + l_bijlage_base64.substr(0,100));
}
}
}
// We staan een maximum aantal bijlages per opdracht toe.
if (i <= p_max_uploads && l_bijlage_base64 && l_bestandsnaam){
__Log("l_bestandsnaam[" + i + "] : " + l_bestandsnaam);
api_F_PutOpdr_Bijlage(l_mld_opdr_key, l_bestandsnaam, l_bijlage_base64, l_kenmerk_key);
}
}
}
}
else
{
if (p_xmlfetch_method == "BySelectNodes")
{
// Method = BySelectNodes
var l_added = 0;
var Attachments = p_xml.selectNodes(p_root_nodenaam);
for (var i=0; i < Attachments.length; i++)
{
var Attachments_filename = Attachments[i].selectNodes(p_filenaam_nodenaam);
var Attachments_base64 = Attachments[i].selectNodes(p_base64_nodenaam);
__Log ("Attachments_base64.length:" + Attachments_base64.length)
for (var j=0; j < Attachments_base64.length; j++)
{
var l_filenaam_node = Attachments_filename[j];
var l_base64_node = Attachments_base64[j];
//var l_filenaam_node = Attachments_filename[i];
//var l_base64_node = Attachments_base64[i];
if (l_added <= p_max_uploads && l_filenaam_node && l_base64_node)
{
l_bestandsnaam = l_filenaam_node.text;
l_bijlage_base64 = l_base64_node.text;
__Log("l_bestandsnaam[" + i + "] : " + l_bestandsnaam);
if (l_bijlage_base64){
__Log("l_bijlage_base64[" + i + "] : " + l_bijlage_base64.substr(0,100));
}
api_F_PutOpdr_Bijlage(l_mld_opdr_key, l_bestandsnaam, l_bijlage_base64, l_kenmerk_key);
l_added = l_added + 1;
}
}
}
}
}
}
}
// p_ms_namespace_url = endpoint oftewel de url van de specifieke namespace van de messageservice, b.v. "https://www.ketenstandaard.nl/WS/MessageService/3.1"
// p_ms_contentnode = naam van de XML node waar zich de plain-XML oftewel de daadwerkelijke inhoud zich bevindt, b.v. "MsgContent".
function marx_get_plainxml_of_messageservice(p_xml, p_ms_namespace_url, p_ms_contentnode)
{
var l_cdata_node;
var l_xml_result;
p_xml.setProperty ("SelectionNamespaces", "xmlns:mes='" + p_ms_namespace_url + "'");
if (xmlNodeVal(p_xml, "//mes:" + p_ms_contentnode)){
// MessageService bericht
var l_cdata_node = p_xml.selectSingleNode("//mes:" + p_ms_contentnode);
if (l_cdata_node)
{
__Log("Cdata found: " + l_cdata_node.text);
var l_xml_result = new ActiveXObject("Msxml2.DOMDocument.6.0");
l_xml_result.loadXML("" + l_cdata_node.text.replace(/^\n*/, '')); // Leading \n er af voor als er een xml-declaratie vooraan staat.
}
}
return l_xml_result;
}
// ***************************** START START START ****************************************
var API = new API_func();
var xmlReq = styledRequestXML(API); // originele XML die we binnenkrijgen
var xmlReq_org = new ActiveXObject("Msxml2.DOMDocument.6.0");
xmlReq_org.loadXML(xmlReq.xml);
var v_API_org = API.APIname;
var v_API;
switch (v_API_org)
{
case "FCLT_OPDRACHT": { v_API = "FCLT_OPDRACHT_IMPORT"; break;}
case "REMS_OPDRACHT": { v_API = "REMS_OPDRACHT_IMPORT"; break;}
case "TWINQ_OPDRACHT": { v_API = "TWINQ_OPDRACHT_IMPORT"; break;}
case "MLD_OPDRACHT_SALES005_1.0": { v_API = "MLD_OPDRACHT_SALES005_1.0_IMPORT"; break;}
case "MLD_OPDRACHT_SALES005_MS31_1.0": { v_API = "MLD_OPDRACHT_SALES005_1.0_IMPORT"; xmlReq = marx_get_plainxml_of_messageservice(xmlReq, "https://www.ketenstandaard.nl/WS/MessageService/3.1", "MsgContent"); break;}
case "AX_PUSH_OPDR": { v_API = "AX_PUSH_OPDR_IMPORT"; break;}
}
__Log("v_API:" + v_API);
if (!v_API)
{
if (xmlNodeVal(xmlReq, "//mld_opdr/mld_opdr_externnr")){
// FCLT OPDRACHTBERICHT
var v_API = "FCLT_OPDRACHT_IMPORT";
}
if (xmlNodeVal(xmlReq, "//ServiceOpdracht/_OpdrachtUitvoerder/Opdracht/Opdrachtnummer")){
// FCLT OPDRACHTBERICHT
var v_API = "REMS_OPDRACHT_IMPORT";
}
var l_plainxml;
if (!l_plainxml) var l_plainxml = marx_get_plainxml_of_messageservice(xmlReq, "https://www.ketenstandaard.nl/WS/MessageService/3.1", "MsgContent");
if (!l_plainxml) var l_plainxml = marx_get_plainxml_of_messageservice(xmlReq, "https://www.ketenstandaard.nl/WS/MessageService/3.0", "MsgContent");
if (!l_plainxml) var l_plainxml = marx_get_plainxml_of_messageservice(xmlReq, "https://www.ketenstandaard.nl/WS/MessageService/2.4", "MsgContent");
if (l_plainxml) xmlReq = l_plainxml;
xmlReq.setProperty ("SelectionNamespaces", "xmlns:sales005m='http://www.ketenstandaard.nl/onderhoudsopdracht/SALES/005'");
if (xmlNodeVal(xmlReq, "//sales005m:MaintenanceInstruction")){
// SALES005 1.0 OPDRACHTBERICHT
var v_API = "MLD_OPDRACHT_SALES005_1.0_IMPORT";
//switch (l_mes)
//{
// case "3.1": { v_API = "MLD_OPDRACHT_SALES005_MS31_1.0"; break;}
//}
}
xmlReq.setProperty ("SelectionNamespaces", "xmlns:sales005s='http://www.ketenstandaard.nl/onderhoudsstatus/SALES/005'");
if (xmlNodeVal(xmlReq, "//sales005s:MaintenanceStatus")){
// SALES005 1.0 STATUSBERICHT
var v_API = "MLD_OPDRACHT_SALES005_1.0_IMPORT";
//switch (l_mes)
//{
// case "3.1": { v_API = "MLD_OPDRACHT_SALES005_MS31_1.0"; break;}
//}
}
xmlReq.setProperty ("SelectionNamespaces", "xmlns:t365='http://schemas.datacontract.org/2004/07/SG.Services.Repositories'");
if (xmlNodeVal(xmlReq, "//t365:SupplierTaskSpec")){
// TOBIAS OPDRACHTBERICHT
var v_API = "AX_PUSH_OPDR_IMPORT";
}
}
// Mogelijke waarden van v_API :
// FCLT_OPDRACHT_IMPORT
// REMS_OPDRACHT_IMPORT
// TWINQ_OPDRACHT_IMPORT
// MLD_OPDRACHT_SALES005_1.0_IMPORT
// AX_PUSH_OPDR_IMPORT
if (v_API)
{
var API_imp = new API_func(v_API);
// utf-8 moet als parameter mee, b.v. een €-teken in een omschrijving van de XML zorgt ervoor dat de XML ongeldig wordt...
var resultdata = api_gen_import(API_imp, xmlReq.xml, "utf-8");
var result = resultdata.xmldom;
if (API.apidata.errorhandling == 1)
{
if (result.anyError) // een 'E' in imp_log
{
Response.Status = '400 Bad Request';
}
}
__Log("result:" + result.xml);
if (result)
{
// Fetch eerst indien alles gelukt is (dwz opdracht aangemaakt of gewijzigd), de mld_opdr_key, die hebben we eerst nodig....
var l_mld_opdr_key = marx_get_mld_opdr_key (result);
__Log("l_mld_opdr_key:" + l_mld_opdr_key);
var xmldoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
xmldoc.async = false;
xmldoc.loadXML(result.xml);
if (xmldoc.parseError.errorCode != 0)
{
var myErr = xmldoc.parseError;
__Log("XML2STR3 Error in xmlfile: " + myErr.reason);
Response.Write ("<html><body><b>Error in xmlfile:</b><br>" + safe.html(myErr.reason) + "</body></html>");
Response.End;
}
__Log("xmldoc.xml:" + xmldoc.xml);
Response.ContentType = "application/soap+xml";
if (API.apidata.stylesheet_out)
{
// Niet super efficient dat we eerst naar tekstuele xml gaan maar ach...
STR2Stream(xmldoc.xml, API.apidata.stylesheet_out, Response, {});
}
else
{
Response.Write(xmldoc.xml);
}
if (l_mld_opdr_key > 0)
{
// Nu eerst nog bijlages uploaden bij de opdracht...
switch (v_API)
{
case "FCLT_OPDRACHT_IMPORT": { marx_upload_fclt_bijlages(l_mld_opdr_key, xmlReq) ; break; }
case "REMS_OPDRACHT_IMPORT": { marx_upload_rems_bijlages(l_mld_opdr_key, xmlReq) ; break; }
case "TWINQ_OPDRACHT_IMPORT": { marx_upload_sales005_bijlages(l_mld_opdr_key, xmlReq) ; break; }
case "MLD_OPDRACHT_SALES005_1.0_IMPORT": { marx_upload_sales005_bijlages(l_mld_opdr_key, xmlReq) ; break; }
}
// Als deze variabele true (1) wordt, dan overruled deze ALLES en wordt immediate puo geskipped.
var l_puo_skip_immediate = 0;
if (v_API == "AX_PUSH_OPDR_IMPORT")
{ // DEEL A uit MARX#81805 Bijlagen in ORG opdracht / (near)realtime opdrachten vanuit Tobias (365)
// ALs er bijlagen bij de T365 opdracht zitten (of het veld is onbekend/nog niet meegestuurd ivm oude T365 versie), dan moeten we geen immediate putorders doen, dus skippen
l_puo_skip_immediate = xmlNodeVal_NS_default(xmlReq, "xmlns:b='http://schemas.datacontract.org/2004/07/SG.Services.Repositories'", "//b:numberOfAttachments", 1);
__Log("l_puo_skip_immediate: " + l_puo_skip_immediate);
}
// Oke, LAATSTE STAP nog: nu gaan we als teverzenden staat ingevuld, de opdracht direct PUSHen via putorders.
var l_puo_immediate = marx_get_puo_immediate ();
if (l_puo_immediate && l_puo_skip_immediate==0){
__Log("marx_force_putorders: START");
marx_force_putorders (l_mld_opdr_key);
}
// Toch deze immediate putorders commentaar omheen gezet, want:
// 1. Robuust (A): Er zijn gevallen bekend waarin de make-xml (als onderdeel) > 100 sec erover doet, en een "timeout" geeft, en is tot op heden niet opgelost
// 2. Robuust (B): We zijn nu afhankelijk van de response-tijd van leverancier, en als dat (heel) lang duurt of "timeout error", duurt ook de response naar de aanroeper (opdrachtgever) heel lang (of fout), dat willen we niet.
// 3. ANN willen we ook (of juist) immediate kunnen sturen. Het is via Niet mogelijk om ANN via immediate te doen.
// Mn de robuustheid-punten 1 + 2 willen we/streven we na. Vandaar doen we dit via functie "loop_puo" uit marx_putorders.js
}
}
else
{
API.error("Could not send " + v_API);
}
}
else
{
API.error("Unknown/empty API: " + v_API);
}
ASPPAGE_END();
%>