Files
Facilitor/APPL/EXP/exp_shared.js
Jos Groot Lipman e5d42faffd Merge 2024.1 Gold A patches
svn path=/Website/trunk/; revision=64055
2024-03-26 08:30:30 +00:00

467 lines
19 KiB
JavaScript

/*
$Revision$
$Id$
File: exp_shared.js
Description: Helper functie
Parameters:
export_app_key Exportfunctie key
Context:
Note: ========= LET OP LET OP =========
Dit bestand wordt ook gebruikt door ../../utils/gen_export/gen_export.wsf
Daar hebben we door CScript maar heel weinig functies!
DUS: Geen L() functie voor locale!!!!
EN: Geen Server.CreateObject maar new ActiveXObject
EN: Slechts enkele functies van safe.
========= LET OP LET OP =========
gen_export_app_flags: 00001 (1) zip het resultaat
00010 (2) manual allowed (future use)
*/
// fileStream moet onze data bevatten
// export_app_key de export-functie
// params export_key mag/zal leeg zijn voor het eerste bestand
// customerId: "ABCD"
// fac_home: net boven de APPL dus bijv. "d:/apps/facilitor/"
function expCreateStream(export_key, params)
{
preExport(params);
var exportFile = getFileName(params.fileprefix, params.postfix, params.applrun, params.timestamp);
var streamData = exportToStream(params, exportFile); // exportFile voor als compress
if (!params.preview)
postExport(params);
if (params.compress)
exportFile += '.zip';
return { exportFile: exportFile
, streamData: streamData
};
}
function getSettings(app_key)
{
// Read settings from database
//
var settings = {};
var sql = "SELECT *"
+ " FROM fac_export_app"
+ " WHERE fac_export_app_key = " + app_key;
var oRs = Oracle.Execute(sql);
if (oRs.Eof)
{
__Log("Unable to find " + app_key + " in fac_export_app");
}
else
{
var sql = "UPDATE fac_export_app"
+ " SET fac_export_app_datum = SYSDATE" // voor het laatst gebruikt
+ " WHERE fac_export_app_key = " + app_key;
Oracle.Execute(sql);
settings = { code: oRs("fac_export_app_code").Value
, oms: oRs("fac_export_app_oms").Value
, xsl: oRs("fac_export_app_xsl").Value || ""
, charset: oRs("fac_export_app_charset").Value || "Windows-1252"
, folder: oRs("fac_export_app_folder").Value || ""
, prefix: oRs("fac_export_app_prefix").Value // straks fallback naar params.custid die we hier nog niet hebben
, postfix: oRs("fac_export_app_postfix").Value || ""
, timestamp: oRs("fac_export_app_timestamp").Value || ""
, flags: oRs("fac_export_app_flags").Value || 0
, functie_key: oRs("fac_functie_key").Value || -1
, logpostfix: oRs("fac_export_app_log_postfix").Value || ""
, fileprefix: oRs("fac_export_app_file_prefix").Value || ""
}
}
oRs.Close();
if (settings.flags & 1)
settings.compress = true;
if (settings.flags & 2)
settings.manual = true;
return settings;
}
function preExport(params)
{
// Clean up the mess of the previous run
//
var sql = "DELETE FROM imp_log"
+ " WHERE imp_log_applicatie = " + safe.quoted_sql(params.code);
__Log("SQL: " + sql);
Oracle.Execute(sql);
//
// Call the database procedure for selecting the export results.
var selectProc = (params.prefix||params.custid) + "_SELECT_" + params.code;
var sql = "SELECT DISTINCT name"
+ " FROM user_source"
+ " WHERE type = 'PROCEDURE'"
+ " AND name = " + safe.quoted_sql(selectProc.toUpperCase());
//__Log("SQL: " + sql);
var oRs = Oracle.Execute(sql);
if(!oRs.Eof)
{
sql = "BEGIN " + selectProc + "(" + safe.quoted_sql(params.code) + ", " + safe.quoted_sql(toDateTimeString(params.applrun)) + "); END;";
__Log("SQL: " + sql);
Oracle.Execute(sql);
}
else
{
//__Log("Optional select/pre-export procedure not found: " + selectProc);
}
oRs.Close();
}
function postExport(params)
{
// Call the database procedure for creation of exportfile.
var toMulti = params.fileprefix.charAt(0) == "*";
// if toMulti, fileprefix translates to the filename_column
var fileprefix = toMulti ? params.fileprefix.substr(1) : params.fileprefix;
var filename = getFileName(fileprefix, params.postfix, params.applrun, params.timestamp);
var exportProc = (params.prefix||params.custid) + "_EXPORT_" + params.code;
var sql = "SELECT DISTINCT name"
+ " FROM user_source"
+ " WHERE type='PROCEDURE'"
+ " AND name = " + safe.quoted_sql(exportProc.toUpperCase());
//__Log("SQL: " + sql);
var oRs = Oracle.Execute(sql);
if (!oRs.Eof)
{
var sql = "BEGIN "
+ exportProc + "(" + safe.quoted_sql(params.code)
+ "," + safe.quoted_sql(toDateTimeString(params.applrun))
+ ",'-1'" //+ safe.quoted_sql(iniOraclePath) // ??
+ "," + safe.quoted_sql(filename)
+ ");"
+ " END;"
__Log("SQL: " + sql);
Oracle.Execute(sql);
}
else
{
//__Log("Optional (post-)export procedure not found: " + exportProc);
}
oRs.Close();
}
// Lever null op als er geen select-view is gedefinieerd.
function exportToStream(params, exportFile)
{
var exportView = (params.prefix||params.custid) + "_V_EXPORT_" + params.code;
var sql = "SELECT DISTINCT view_name"
+ " FROM USER_VIEWS"
+ " WHERE view_name = " + safe.quoted_sql(exportView.toUpperCase());
//__Log("SQL: " + sql);
var oRs = Oracle.Execute(sql);
if (oRs.Eof)
{
//__Log("Optional export view not found: " + exportView);
oRs.Close()
return null;
}
else
{
var fstr;
var toMulti = params.fileprefix.charAt(0) == "*";
if (toMulti)
{
var last_filename;
var this_filename;
var fstr_arr = [];
var filename_col = params.fileprefix.substr(1);
var sql_v = "SELECT " + filename_col + ", result"
+ " FROM " + exportView
+ " ORDER BY " + filename_col + ", result_order";
__Log("SQL: " + sql_v);
var oRs_v = Oracle.Execute(sql_v);
while (!oRs_v.Eof)
{
last_filename = oRs_v(filename_col).Value;
this_filename = last_filename;
fstr = openStreamWriteText({charset: params.charset});
while (!oRs_v.Eof && last_filename == this_filename)
{
fstr.WriteText(oRs_v("result").Value, 1); // 0=adWriteChar, 1=adWriteLine (LineSeparator required)
oRs_v.MoveNext();
if (!oRs_v.Eof)
this_filename = oRs_v(filename_col).Value;
}
if (params.xsl)
fstr = transformStream(fstr, params.xsl, params);
fstr.Position = 0;
fstr_arr.push({ "filename": last_filename, "fstr": fstr });
}
}
else
{
fstr = openStreamWriteText({charset: params.charset});
var sql_v = "SELECT result"
+ " FROM " + exportView
+ " ORDER BY result_order";
__Log("SQL: " + sql_v);
var oRs_v = Oracle.Execute(sql_v);
while (!oRs_v.Eof)
{
fstr.WriteText(oRs_v("result").Value, 1); // 0=adWriteChar, 1=adWriteLine (LineSeparator required)
oRs_v.MoveNext();
}
if (params.xsl)
fstr = transformStream(fstr, params.xsl, params);
fstr.Position = 0;
}
oRs_v.Close();
}
oRs.Close();
if (!params.compress || toMulti) // Zip not supported for toMulti
return (toMulti ? fstr_arr : fstr);
var oZIP = new ActiveXObject("SLNKDWF.Zip");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var temp = params.tempFolder + fso.GetTempName();
oZIP.New(temp) //;; Helaas niet *naar* stream
oZIP.ZipFromStream(exportFile, fstr);
oZIP.Close();
var oStream = new ActiveXObject("ADODB.Stream");
oStream.Open;
oStream.Type = 1; // adTypeBinary
oStream.LoadFromFile(temp);
oStream.Position = 0;
fso.DeleteFile(temp);
return oStream;
}
function transformStream(stream, xsl, params)
{
//return stream;
var xslfile = params.fac_home + "CUST/" + params.customerId + "/" + xsl;
__Log("Transforming export using " + xslfile);
var source = new ActiveXObject("MSXML2.DOMDocument.6.0");
source.async = false;
source.resolveExternals = false; // XML-data vertrouwen we niet altijd
source.validateOnParse = false; // maar dan kun je geen DTD's meer controleren
source.setProperty("ProhibitDTD", false); // niet moeilijk doen over DTD's
stream.Position = 0;
// if (0) // testing
// source.loadXML("<facilitor><FCLTattachment encoding='hex' templatenodename='test'>367079</FCLTattachment></facilitor>");
// else
if( ! source.load(stream) ) // Het bestand laden
{
var err = "XML error: " + source.parseError.reason + " @ " + source.parseError.line + "." + source.parseError.linepos;
__DoLog(err);
throw({ description: err });
}
// Load the XSLT
var style = new ActiveXObject("MSXML2.DOMDocument.6.0");
style.async = false;
style.resolveExternals = true; // XSL kan includes hebben
style.validateOnParse = true; // en moet correct zijn
style.setProperty("ProhibitDTD", false); // niet moeilijk doen over DTD's
if( ! style.load(xslfile) ) // De stylesheet laden
{
var err = xslfile + "\nXSL error: " + style.parseError.reason + " @ " + style.parseError.line + "." + style.parseError.linepos;
__DoLog(err);
throw({ description: err });
}
var XMLresult = new ActiveXObject("Msxml2.DOMDocument.6.0");
source.transformNodeToObject(style, XMLresult);
// kijk of er <FCLTattachment>bijlagenkey<FCLTattachment> in
// de XMLresult zit en vervang die eventueel
mergeXMLAttachments3(XMLresult, style);
var oStream = openStreamWriteText({charset: params.charset});
XMLresult.save(oStream);
return oStream;
}
function mergeXMLAttachments3(iXml, style)
{
var xmltag = "//FCLTattachment";
// Doorzoek iXml op <FCLTattachment>345</FCLTattachment>
// waarbij 345 een fac_bijlagen_key is
// en vervang die door
// <Attachment>
// <BinaryData>...b64data...</BinaryData>
// <Name>naam</Name>
// <Size>1235</Size>
// </Attachment>
var NodeList = iXml.documentElement.selectNodes(xmltag);
__Log("Gezocht op FCLTattachment");
if (NodeList.length > 0)
{
__Log("*> mergeXMLAttachments");
for (var index=0; index < NodeList.length; index++)
{
var node = NodeList[index];
var bijlage_key = node.text;
var nodename = node.attributes.getNamedItem("nodename")?node.attributes.getNamedItem("nodename").text:"Attachment";
var node_encoding = node.attributes.getNamedItem("encoding"); // als die NIET is gevuld doen we default "base64"
var encoding = "base64";
if (node_encoding)
{
encoding = node_encoding.text;
}
var node_templatenodename = node.attributes.getNamedItem("templatenodename"); // als die is gevuld doen we een post-parse met de stylesheet
var templatenodename = '';
if (node_templatenodename)
{
templatenodename = node_templatenodename.text;
}
__Log("Including fac_bijlagen {0}".format(bijlage_key));
var att_list = [];
var sql = "SELECT r.fac_bijlagen_disk_directory"
+ " , r.fac_bijlagen_filename"
+ " , r.fac_bijlagen_file_size"
+ " FROM fac_v_bijlagen r"
+ " WHERE r.fac_bijlagen_verwijder IS NULL"
+ " AND r.fac_bijlagen_key = " + bijlage_key;
var oRs = Oracle.Execute(sql);
if (!oRs.eof)
{
att_list.push( { f_disk: oRs("fac_bijlagen_disk_directory").Value
, f_name: oRs("fac_bijlagen_filename").Value
, f_size: oRs("fac_bijlagen_file_size").Value
, f_path: S("flexfilespath") + "/" + oRs("fac_bijlagen_disk_directory").Value + "/" + oRs("fac_bijlagen_filename").Value
}
);
oRs.MoveNext();
}
else
__Log("fac_bijlagen record not found?");
oRs.Close();
for (var a=0; a < att_list.length; a++)
{
__Log("Embedding attachment: " + att_list[a].f_path + " (" + att_list[a].f_size + " bytes)");
// en hier de rest voor het invoegen van de bijlagen.
var elemAttachments = iXml.createElement(nodename);
var elemAtt = iXml.createElement("BinaryData");
switch (encoding)
{
case "hex": elemAtt.text = Hexify(att_list[a].f_path);
break;
case "base64": elemAtt.text = Base64fy(att_list[a].f_path);
break;
}
__Log("{0} encoded it becomes {1} bytes".format(encoding, elemAtt.text.length));
elemAttachments.appendChild(elemAtt);
elemAtt = iXml.createElement("Encoding");
elemAtt.text = encoding;
elemAttachments.appendChild(elemAtt);
elemAtt = iXml.createElement("Name");
elemAtt.text = att_list[a].f_name;
elemAttachments.appendChild(elemAtt);
elemAtt = iXml.createElement("Size");
elemAtt.text = att_list[a].f_size;
elemAttachments.appendChild(elemAtt);
if (templatenodename != '') // post processing met de stylesheet
{ // puo_xmltools gebruikt hier function XML2HTML() maar dat introduceert mij te veel afhankelijkheden
var elemWrapper = iXml.createElement(templatenodename);
elemWrapper.appendChild(elemAttachments);
var tmp_xmlDoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
tmp_xmlDoc.async = false;
tmp_xmlDoc.loadXML(elemWrapper.xml);
//LogString2File(3, "PostProces", tmp_xmlDoc.xml, "xml");
var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0");
style.resolveExternals = true; // anders op de volgende regel al:
// A reference to variable or parameter 'srtnotificatiecode' cannot be resolved
xslt.stylesheet = style;
var xslProc = xslt.createProcessor();
xslProc.input = tmp_xmlDoc;
xslProc.addParameter("srtnotificatiecode", "");
xslProc.addParameter("mode", "processattachments");
xslProc.transform();
tmp_xmlResult = xslProc.output;
tmp_xmlDoc.loadXML(tmp_xmlResult);
//LogString2File(3, "PostProcesAttach", tmp_xmlResult, "xml");
var NodeList2 = tmp_xmlDoc.documentElement.childNodes;
for (var i=0; i < NodeList2.length; i++)
{
var tmp_node = NodeList2[i];
//Let op: niet appendChild gebruikt, want die voegt achteraan toe aan de parentnode, waardoor de volgorde wordt aangepast.
//Door gebruikt van insertBefore blijft de volgorde intact, die wezenlijk voor Validatie tegen XSD (van externe partijen) kan zijn!
node.parentNode.insertBefore(tmp_node, node);
}
}
else
{
node.parentNode.appendChild(elemAttachments);
}
}
node.parentNode.removeChild(node); // dummy fcltattachments weg
}
__Log("*< mergeXMLAttachments");
}
return iXml;
}
function openStreamWriteText(params)
{
// params:
// lineseparator: -1=adCRLF, 10=adLF, 13=adCR
// streamwrite: 1=adSaveCreateNotExist, 2=adSaveCreateOverWrite
// charset:
// var streamwrite = (params.streamwrite ? params.streamwrite : 1);
var fileStream = new ActiveXObject("ADODB.Stream");
fileStream.CharSet = (params.charset ? params.charset : "Windows-1252");
fileStream.LineSeparator = (params.lineseparator ? params.lineseparator : -1);
fileStream.Type = 2; // 1=adTypeBinary, 2=adTypeText
fileStream.Open();
return fileStream;
}
function getFileName(fileprefix, postfix, daterun, dateformat)
{
var index = fileprefix.indexOf(".");
var naam = (index==-1?fileprefix:fileprefix.substr(0, index)) + formatDate(daterun, dateformat) + postfix;
return naam;
}
function formatDate(datum, format)
{
var onejan = new Date(datum.getFullYear(),0,1);
var o = { "m+" : datum.getMonth()+1 //month
, "d+" : datum.getDate() //day
, "H+" : datum.getHours() //hour
, "M+" : datum.getMinutes() //minute
, "S+" : datum.getSeconds() //second
, "q+" : Math.floor((datum.getMonth()+3)/3) //quarter
, "s" : datum.getMilliseconds() //millisecond
, "w+" : Math.ceil((((datum - onejan) / 86400000) + onejan.getDay()+1)/7) // weeknumber
};
format = format.replace('hhmm', 'HHMM');
if (/(y+)/.test(format))
format = format.replace(RegExp.$1, (datum.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
{
if(new RegExp("("+ k +")").test(format))
{
format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length));
}
}
return format;
}