870 lines
38 KiB
JavaScript
870 lines
38 KiB
JavaScript
/*
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: imp_shared.js
|
|
Description: Helper functie
|
|
Parameters:
|
|
import_app_key Importfunctie key
|
|
Context:
|
|
Note: ========= LET OP LET OP =========
|
|
Dit bestand wordt ook gebruikt door ../../utils/gen_import/gen_import.wsf
|
|
Daar hebben we door CScript maar heel weinig functies!
|
|
DUS: Geen L() functie voor locale!!!!
|
|
EN: Geen Server.CreateObject maar new ActiveXObject
|
|
Dit bestand wordt ook gebruikt door ../api/api_gen_import.asp
|
|
========= LET OP LET OP =========
|
|
*/
|
|
|
|
// fileStream moet onze data bevatten
|
|
// import_app_key de import-functie
|
|
// params import_key mag/zal leeg zijn voor het eerste bestand
|
|
// customerId: "UWVA"
|
|
// ref_key: optioneel een key die in FAC_IMPORT_REFKEY gaat.
|
|
// fac_home: net boven de APPL dus bijv. "d:/apps/facilitor/"
|
|
// filepathname: optioneel: stoppen we in fac_import_filenaam
|
|
// keep_old: oude imports van dezelfde soort van maximaal keep_old
|
|
// seconden worden nog even aangehouden. Default 0
|
|
// Nodig als je meerdere parallelle imports wilt ondersteunen
|
|
// (vanuit api_gen_import bijvoorbeeld)
|
|
// keep_backup: als fac_import_app_folder gezet is wordt een backup
|
|
// van de import file gemaakt onder fac_import_app_folder/BACKUP2015/....
|
|
// Merk op: vanuit gen_import.wsf wordt keep_backup *niet* gezet
|
|
// omdat gen_import.wsf (nog) zelf de backup maakt
|
|
// stylesheet: optionele overrule van de import-XSL-stylesheet
|
|
|
|
|
|
function parseCSVLine(csvLine, delimiter)
|
|
{
|
|
var fields = csvLine.split(delimiter);
|
|
var correctedFields = [];
|
|
var mergedField = '';
|
|
|
|
for (var regel in fields)
|
|
{
|
|
var field = fields[regel];
|
|
if (!mergedField && field.charAt(0) !== '"')
|
|
{
|
|
correctedFields.push(field);
|
|
}
|
|
else
|
|
{
|
|
mergedField += mergedField ? (delimiter + field) : field;
|
|
if (mergedField.charAt(mergedField.length - 1) === '"')
|
|
{
|
|
correctedFields.push(mergedField.substring(1, mergedField.length - 1));
|
|
mergedField = '';
|
|
}
|
|
}
|
|
};
|
|
|
|
return correctedFields;
|
|
}
|
|
|
|
function impReadStream(fileStream, import_app_key, params)
|
|
{
|
|
params = params || {};
|
|
if (!("keep_old" in params))
|
|
params.keep_old = 0;
|
|
params.is_stream = ("is_stream" in params ? params.is_stream : false); // default false
|
|
var import_key = params.import_key || -1;
|
|
if (import_key < 0)
|
|
{
|
|
var this_import_where = " fac_import_app_key = " + import_app_key;
|
|
if (params.keep_old > 0)
|
|
this_import_where += " AND fac_import_datum_gelezen <= SYSDATE - " + parseInt(params.keep_old) + " /60/60/24";
|
|
|
|
// Hadden we nog iets openstaan voor deze import_app_key? Dan wissen we die eerst
|
|
// We ondersteunen namelijk geen *twee* openstaande imports van dezelfde functie
|
|
if (params.keep_old == 0) // alleen bij ad-hoc imports, niet die via API aanroepen
|
|
{
|
|
var sql = "DELETE FROM fac_import"
|
|
+ " WHERE " + this_import_where
|
|
+ " AND fac_import_datum_verwerkt IS NULL";
|
|
Oracle.Execute(sql); // cascadeert vanzelf FAC_IMP_LOG en FAC_IMP_FILE
|
|
|
|
// Merk op: verwerkte FAC_IMPORT records blijven eeuwig bestaan
|
|
// TODO: Ooit saved files opruimen op basis van fac_import_backupdir
|
|
|
|
// Ook: *alle* oude FAC_IMP_FILE voor deze import gaan nu weg
|
|
var sql = "DELETE FROM fac_imp_file"
|
|
+ " WHERE fac_import_key IN"
|
|
+ " (SELECT fac_import_key"
|
|
+ " FROM fac_import"
|
|
+ " WHERE " + this_import_where + ")";
|
|
Oracle.Execute(sql);
|
|
|
|
// Ook: *alle* oude FAC_IMP_CSV voor deze import gaan nu weg
|
|
var sql = "DELETE FROM fac_imp_csv"
|
|
+ " WHERE fac_import_key IN"
|
|
+ " (SELECT fac_import_key"
|
|
+ " FROM fac_import"
|
|
+ " WHERE " + this_import_where + ")";
|
|
Oracle.Execute(sql);
|
|
}
|
|
// Opruimen van oude logging doen we in fac.fac_cleanup die elke dag uitgevoerd wordt dmv fac.fac_daily
|
|
|
|
var sql = "SELECT fac_s_fac_import_key.nextval FROM DUAL";
|
|
var oRs = Oracle.Execute(sql);
|
|
import_key = oRs(0).Value;
|
|
oRs.Close();
|
|
|
|
sql = "INSERT INTO fac_import"
|
|
+ " (fac_import_key,"
|
|
+ " fac_import_app_key,"
|
|
+ " fac_import_refkey,"
|
|
+ " fac_import_filenaam,"
|
|
+ " fac_import_datum_gelezen,"
|
|
+ " prs_perslid_key)"
|
|
+ " VALUES( " + import_key + ", "
|
|
+ import_app_key + ", "
|
|
+ (params.ref_key||"NULL") + ","
|
|
+ safe.quoted_sql(params.filepathname, 256) + ", "
|
|
+ "SYSDATE, "
|
|
+ (params.user_key > 0 ? params.user_key : "NULL")
|
|
+ ")";
|
|
Oracle.Execute(sql);
|
|
}
|
|
else
|
|
{ // Mocht een import-functie *echt* iets met de filenaam willen doen dan kan hij hem zelf opzoeken
|
|
// in fac_import. Voor multi-import slaan we daartoe de laatste filenaam op.
|
|
sql = "UPDATE fac_import"
|
|
+ " SET fac_import_filenaam = " + safe.quoted_sql(params.filepathname,256)
|
|
+ " WHERE fac_import_key = " + import_key;
|
|
Oracle.Execute(sql);
|
|
}
|
|
var sql = "SELECT i.fac_import_app_code "
|
|
+ ", i.fac_import_app_prefix "
|
|
+ ", i.fac_import_app_xsl "
|
|
+ ", i.fac_import_app_charset "
|
|
+ ", i.fac_import_app_csv"
|
|
+ ", i.fac_import_app_delimiter"
|
|
+ ", i.fac_import_app_folder" // voor eventuele backup
|
|
+ " FROM fac_import_app i"
|
|
+ " WHERE i.fac_import_app_key = " + import_app_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
|
|
var import_app = oRs("fac_import_app_code").value;
|
|
var import_csv = oRs("fac_import_app_csv").Value == 1;
|
|
var import_delimiter = oRs("fac_import_app_delimiter").Value || ";";
|
|
var procprefix = oRs("fac_import_app_prefix").value||"FAC";
|
|
var charset = oRs("fac_import_app_charset").value;
|
|
if (params.stylesheet) // vanuit de API bv, die is sterker
|
|
var xslfile = params.fac_home + "CUST/" + params.customerId + "/" + params.stylesheet;
|
|
else
|
|
var xslfile = oRs("fac_import_app_xsl").value?params.fac_home + "CUST/" + params.customerId + "/" + oRs("fac_import_app_xsl").value:"";
|
|
var folder = oRs("fac_import_app_folder").Value;
|
|
oRs.Close();
|
|
|
|
var backDir = params.is_stream ? null : backupfolder(import_app, folder, import_key);
|
|
// Registeren (ook al doen we er verder nog niets mee)
|
|
sql = "UPDATE fac_import"
|
|
+ " SET fac_import_backupdir = " + safe.quoted_sql(backDir)
|
|
+ " WHERE fac_import_key = " + import_key;
|
|
Oracle.Execute(sql);
|
|
|
|
if (backDir && params.keep_backup)
|
|
{
|
|
var oZIP = new ActiveXObject("SLNKDWF.Zip");
|
|
oZIP.New(backDir + safe.filename(params.filepathname) + ".zip");
|
|
fileStream.Position = 0;
|
|
oZIP.ZipFromStream(params.filepathname, fileStream);
|
|
oZIP.Close();
|
|
}
|
|
|
|
if( !fileStream.Size ) // Leeg bestand?
|
|
{
|
|
return { success: false,
|
|
backDir: backDir, // Ongeldig bestand wel weg-moven
|
|
warning: "Import error: file is empty" };
|
|
}
|
|
|
|
// Altijd naar win1252 converteren, dat heeft onze database ook
|
|
fileStream.Position = 0;
|
|
fileStream.Type = 2; // adTypeText nu
|
|
fileStream.Charset = charset || 'Windows-1252'; // de bron
|
|
|
|
var win1252Stream = new ActiveXObject("ADODB.Stream");
|
|
win1252Stream.Open();
|
|
win1252Stream.CharSet = "Windows-1252"; // het doel
|
|
fileStream.copyTo(win1252Stream);
|
|
//win1252Stream.SaveToFile(Server.MapPath("./win1252Stream.txt"), 2);
|
|
|
|
if (xslfile)
|
|
{
|
|
// Zet xml om in string
|
|
__Log("XML2STR: with XSL: " + xslfile);
|
|
|
|
// Load the XML
|
|
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
|
|
|
|
var fileData; // Hier gaan we de data als string in stoppen
|
|
win1252Stream.Position = 0
|
|
var ReadBytes = 131072; // optimaal volgens https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/readtext-method?view=sql-server-ver15
|
|
var sOut = "";
|
|
while (!win1252Stream.EOS)
|
|
{
|
|
sOut = sOut + win1252Stream.ReadText(ReadBytes);
|
|
}
|
|
if( ! source.loadXML(sOut) ) // Het bestand laden
|
|
{
|
|
return { success: false,
|
|
backDir: backDir, // Ongeldig bestand wel weg-moven
|
|
warning: "XML error: " + source.parseError.reason + " @ " + source.parseError.line + "." + source.parseError.linepos };
|
|
}
|
|
|
|
// 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
|
|
{
|
|
return { success: false,
|
|
// backDir: backDir, // het import bestand is gewoon geldig dus laten staan tot iemand de xsl-error oplost
|
|
warning: xslfile + "\nXSL error: " + style.parseError.reason + " @ " + style.parseError.line + "." + style.parseError.linepos };
|
|
}
|
|
fileData = source.transformNode(style); // terugstoppen in de fileData string
|
|
// of?: xslproc.output = win1252Stream;
|
|
// xslproc.transform();
|
|
|
|
}
|
|
else // Geen XSL, hij is 'perfect' aangeleverd.
|
|
{
|
|
win1252Stream.Position = 0;
|
|
var ReadBytes = 131072; // optimaal volgens https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/readtext-method?view=sql-server-ver15
|
|
var fileData = "";
|
|
while (!win1252Stream.EOS)
|
|
{
|
|
fileData = fileData + win1252Stream.ReadText(ReadBytes);
|
|
}
|
|
}
|
|
|
|
//
|
|
// fileData bevat nu de geimporteerde file. Wat gaan we er mee doen
|
|
// A) Naar Oracle (via table fac_imp_file) en daar laten verwerken
|
|
// B) Doorsturen naar SOAP service (want daar hebben we al afhandeling gebouwd)
|
|
//
|
|
|
|
var read_lines = -1;
|
|
// data naar de database naar FAC_IMP_FILE
|
|
teller = 1;
|
|
var sqls = [];
|
|
//var fileDataArr = fileData.split(/[\r\n]/); // gaat mis bij CSV's met newline binnen quotes
|
|
var fileDataArr = fileData.split(/\x0D\x0A/); // CR LF is verplicht. Unix heeft alleen LF en dat ondersteunen we niet
|
|
// (alleen LF kan wel binnen quotes voor een newline in een veld) FSN#18597
|
|
if (fileDataArr.length == 1)
|
|
var fileDataArr = fileData.split(/\x0A/); // Misschien alleen UNIX LF's?
|
|
|
|
if (fileDataArr.length == 1)
|
|
var fileDataArr = fileData.split(/\x0D/); // Misschien alleen MAC CR's?
|
|
|
|
if (import_csv)
|
|
{ // Importregel in fac_imp_csv opslaan per kolom.
|
|
for (var regel in fileDataArr)
|
|
{
|
|
var line = fileDataArr[regel];
|
|
if (line != "")
|
|
{
|
|
var cols = parseCSVLine(line, import_delimiter);
|
|
var colsName = ["fac_import_key", "fac_imp_csv_index"];
|
|
var safe_colsValue = [import_key, (teller)];
|
|
for (var c=1; c<=cols.length;c++)
|
|
{
|
|
if (c <= 99) // Maximaal aantal kolommen
|
|
{
|
|
colsName.push("fac_imp_csv_col" + ("00" + c).slice(-2));
|
|
safe_colsValue.push(safe.quoted_sql(cols[c-1]));
|
|
if (cols[c-1].length > 4000)
|
|
{
|
|
//__Log(cols[c-1].length);
|
|
//__Log(cols[c-1]);
|
|
sql = "BEGIN fac.imp_writelog (" + import_key + ","
|
|
+ "'E',"
|
|
+ safe.quoted_sql(L("lcl_imp_oversized_column").format(teller, c)) + ", NULL);"
|
|
+ "END;"
|
|
Oracle.Execute(sql);
|
|
return { success: false,
|
|
backDir: backDir, // Ongeldig bestand wel weg-moven
|
|
warning: "Import error: " + L("lcl_imp_oversized_column").format(teller, c) };
|
|
}
|
|
}
|
|
}
|
|
var insertSql = "INSERT INTO fac_imp_csv"
|
|
+ "( " + colsName.join(",") + ")"
|
|
+ "VALUES"
|
|
+ "(" + safe_colsValue.join(",") + ")";
|
|
Oracle.Execute(insertSql);
|
|
teller++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ // Importregel in fac_imp_file opslaan.
|
|
var sqllen = 0;
|
|
for (var regel in fileDataArr)
|
|
{
|
|
var line = fileDataArr[regel];
|
|
if (line != "")
|
|
{
|
|
if (line.length > 4000) {
|
|
sql = "BEGIN fac.imp_writelog (" + import_key + ","
|
|
+ "'E',"
|
|
+ safe.quoted_sql(L("lcl_imp_oversized_line").format(teller)) + ", NULL);"
|
|
+ "END;"
|
|
Oracle.Execute(sql);
|
|
return { success: false,
|
|
backDir: backDir, // Ongeldig bestand wel weg-moven
|
|
warning: "Import error: " + L("lcl_imp_oversized_line").format(teller) };
|
|
}
|
|
sql = teller + ", " + safe.quoted_sql(line) + "," + import_key;
|
|
sqllen += sql.length + 28; // grove schatting
|
|
sqls.push(sql);
|
|
teller = teller + 1;
|
|
}
|
|
if (sqllen > 10000) // empirisch bepaald: fatsoenlijke performance
|
|
{
|
|
var insertSql = "INSERT INTO fac_imp_file"
|
|
+ " (fac_imp_file_index, fac_imp_file_line, fac_import_key) SELECT "
|
|
+ sqls.join(" FROM DUAL UNION ALL SELECT ") + " FROM DUAL";
|
|
Oracle.Execute(insertSql);
|
|
sqls = [];
|
|
sqllen = 0;
|
|
}
|
|
}
|
|
if (sqls.length) // de laatste
|
|
{
|
|
Oracle.Execute("INSERT INTO fac_imp_file"
|
|
+ " (fac_imp_file_index, fac_imp_file_line, fac_import_key) SELECT "
|
|
+ sqls.join(" FROM DUAL UNION ALL SELECT ") + " FROM DUAL");
|
|
}
|
|
}
|
|
__Log("Ingelezen regels: " + fileDataArr.length);
|
|
|
|
var importProc = procprefix + "_IMPORT_" + import_app;
|
|
var sql = "SELECT DISTINCT object_name"
|
|
+ " FROM USER_OBJECTS"
|
|
+ " WHERE object_type = 'PROCEDURE'"
|
|
+ " AND object_name = " + safe.quoted_sql(importProc.toUpperCase());
|
|
var oRs = Oracle.Execute(sql);
|
|
if (oRs.eof)
|
|
{ //__Log("Optional import procedure not found: " + importProc);
|
|
oRs.Close();
|
|
var read_lines = teller-1;
|
|
}
|
|
else
|
|
{
|
|
// De _IMPORT_ proc zal doorgaans de data van FAC_IMP_FILE of FAC_IMP_CSV naar bijv. FAC_IMP_CATALOGUS overzetten
|
|
// De latere _UPDATE_ proc zal zo'n FAC_IMP_CATALOGUS dan echt verwerken
|
|
// (sommige _UPDATE_ procs werken rechtstreekd op FAC_IMP_CSV maar moeten dan nog steeds een dummy _IMPORT_ hebben)
|
|
var extra_params = (params.proc_params ? params.proc_params : "");
|
|
sql = "BEGIN " + importProc + "(" + import_key + extra_params + "); END;"
|
|
Oracle.Execute(sql);
|
|
|
|
var read_lines = teller-1;
|
|
var summarytxt = "";
|
|
if (read_lines != 2) // uitsluitend header + 1 dataregel komt bij klanten die PRSIMP per persoon doen duizenden keren per dag voor
|
|
{
|
|
var summarytxt = "Ingelezen regels: " + read_lines;
|
|
}
|
|
|
|
var read_lines = teller-1;
|
|
|
|
if (summarytxt)
|
|
{
|
|
sql = "BEGIN fac.imp_writelog (" + import_key + ","
|
|
+ "'S',"
|
|
+ safe.quoted_sql(summarytxt) + ", NULL);"
|
|
+ "END;"
|
|
Oracle.Execute(sql)
|
|
}
|
|
|
|
}
|
|
return { success: true, import_key: import_key, backDir: backDir, read_lines: read_lines };
|
|
}
|
|
|
|
// import_key bevat een te verwerken key
|
|
// params: customerId: "UWVA"
|
|
function impProcessStream(import_key, params)
|
|
{
|
|
var result = {message: "", success: false};
|
|
var now_sql = "SELECT TO_CHAR (SYSDATE, 'DD-MM-YYYY HH24:MI:SS') now FROM DUAL";
|
|
var sql = "SELECT COALESCE (MAX (imp_log_key), -1) imp_log_key"
|
|
+ " FROM imp_log"
|
|
+ " WHERE fac_import_key = " + import_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var last_imp_log_key = oRs("imp_log_key").Value;
|
|
oRs.Close();
|
|
|
|
var sql = "SELECT ia.fac_import_app_key"
|
|
+ ", fac_import_app_code"
|
|
+ ", fac_import_app_prefix"
|
|
+ ", fac_import_app_folder"
|
|
+ ", fac_import_filenaam"
|
|
+ " FROM fac_import_app ia"
|
|
+ ", fac_import i"
|
|
+ " WHERE ia.fac_import_app_key = i.fac_import_app_key"
|
|
+ " AND i.fac_import_key = " + import_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var import_app_key = oRs("fac_import_app_key").Value;
|
|
var impcode = oRs("fac_import_app_code").Value;
|
|
var prefix = oRs("fac_import_app_prefix").Value||"FAC";
|
|
var filenaam = oRs("fac_import_filenaam").Value;
|
|
var folder = oRs("fac_import_app_folder").Value;
|
|
oRs.Close();
|
|
|
|
// Start de UPDATE procedure om de database aan te passen
|
|
var extra_params = (params.proc_params ? params.proc_params : "");
|
|
sql = "BEGIN "
|
|
+ prefix + "_UPDATE_" + impcode
|
|
+ "(" + import_key + extra_params + ");"
|
|
+ " END;"
|
|
|
|
Oracle.Execute(sql);
|
|
|
|
// Optioneel kan er nog klantspecifiek wat achteraan komen in geval van Catalogus-import
|
|
// Bijv. NFIB#21853
|
|
if (impcode == 'CATALOGUS')
|
|
{
|
|
var sql = "SELECT object_type"
|
|
+ " FROM user_objects"
|
|
+ " WHERE object_name = " + safe.quoted_sql(customerId + "_UPDATE_CATALOGUS");
|
|
var oRs = Oracle.Execute(sql);
|
|
|
|
if (!oRs.eof && oRs(0).Value == "PROCEDURE")
|
|
{ // Geldige aanwezig, roep aan
|
|
sql = "BEGIN "
|
|
+ customerId + "_UPDATE_CATALOGUS"
|
|
+ "(" + import_key + ");"
|
|
+ " END;"
|
|
Oracle.Execute(sql);
|
|
}
|
|
oRs.Close();
|
|
}
|
|
|
|
// Nu kijken of we nog iets met flexbijlagen moeten doen
|
|
//
|
|
// LET OP(?): Vanuit gen_import.wsf hebben we geen S() noch allerlei
|
|
// andere functies die we hier gebruiken!!
|
|
// Dit werkt dus (vooralsnog) alleen vanuit de GUI en via SOAP!!
|
|
//
|
|
|
|
var flexcode = null;
|
|
var sql = "SELECT fac_result_waarde"
|
|
+ " FROM fac_result"
|
|
+ " WHERE fac_result_naam = 'flexcode'"
|
|
+ " AND fac_result_sessionid = 'IMPORT:{0}'".format(import_key);
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.Eof)
|
|
{ // melding S undefined? We ondersteunen dit nog niet vanuit gen_import.wsf
|
|
flexcode = oRs("fac_result_waarde").Value;
|
|
}
|
|
oRs.Close();
|
|
//flexcode = "MLD:995837:544:M";
|
|
if (flexcode) // FIN:12345:18:F (12345=factuurkey, 18=kenmerkkey, F=factuur (versus R=regels)
|
|
{
|
|
if (!folder)
|
|
abort_with_warning("IMPORT CONFIGURATION ERROR:\nflexcode result but FAC_IMPORT_APP_FOLDER is not set");
|
|
|
|
if (!this.flexProps)
|
|
INTERNAL_ERROR_FLEXCODE; // Niet ondersteund vanuit gen_import.wsf
|
|
|
|
var backDir = backupfolder(impcode, folder, import_key);
|
|
var res = extractAttachments(backDir + safe.filename(filenaam) + ".zip", safe.filename(filenaam), flexcode);
|
|
if (!res.success)
|
|
return res;
|
|
}
|
|
|
|
sql = "UPDATE fac_import"
|
|
+ " SET fac_import_datum_verwerkt = SYSDATE"
|
|
+ (params.user_key > 0 ? ", prs_perslid_key = " + params.user_key : "")
|
|
+ " WHERE fac_import_key = " + import_key
|
|
+ " AND fac_import_datum_verwerkt IS NULL";
|
|
Oracle.Execute(sql);
|
|
|
|
// Verder opruimen van oude data doen we in fac.fac_cleanup die elke dag uitgevoerd wordt dmv fac.fac_daily
|
|
|
|
result.message = (typeof L != "undefined"?L("lcl_imp_inf_processed"):"Ingelezen gegevens zijn verwerkt"); // Geen L vanuit gen_import.wsf!
|
|
result.success = true;
|
|
|
|
var sql = "SELECT COUNT(*)"
|
|
+ " FROM imp_log"
|
|
+ " WHERE imp_log_status = 'W'"
|
|
+ " AND imp_log_key > " + last_imp_log_key
|
|
+ " AND fac_import_key = " + import_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var cntW = oRs(0).Value;
|
|
oRs.Close();
|
|
if (cntW > 0) {
|
|
result.message += "\n" + (typeof L != "undefined" ? L("lcl_imp_rap_w") : "Waarschuwingen") + ": " + cntW;
|
|
}
|
|
var sql = "SELECT COUNT(*)"
|
|
+ " FROM imp_log"
|
|
+ " WHERE imp_log_status = 'E'"
|
|
+ " AND imp_log_key > " + last_imp_log_key
|
|
+ " AND fac_import_key = " + import_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var cntE = oRs(0).Value;
|
|
oRs.Close();
|
|
if (cntE > 0) {
|
|
result.message += "\n" + (typeof L != "undefined" ? L("lcl_imp_rap_e") : "Fouten") + ": " + cntE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function backupfolder(import_app, folder, import_key)
|
|
{
|
|
if (!folder)
|
|
return null;
|
|
|
|
// <folder>\BACKUP<jaar>-<maand>\<import_app>\<fulldate>_<import_key>
|
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|
if (!fso.FolderExists(folder))
|
|
abort_with_warning("Import error: backup folder {0} not found on server".format(folder));
|
|
|
|
var jsDate = new Date();
|
|
|
|
folder = folder.replace("/", "\\");
|
|
if (folder.substr(folder.length-1) != "\\")
|
|
folder += "\\";
|
|
var backDir = folder + "BACKUP" + jsDate.getFullYear() + "-" + padout(jsDate.getMonth() + 1) + "\\";
|
|
if (!fso.FolderExists(backDir))
|
|
fso.CreateFolder(backDir);
|
|
|
|
backDir += import_app + "\\";
|
|
if (!fso.FolderExists(backDir))
|
|
fso.CreateFolder(backDir);
|
|
|
|
var dtstring = padout(jsDate.getFullYear()) + "-" + padout(jsDate.getMonth() + 1) + "-" + padout(jsDate.getDate());
|
|
|
|
backDir += dtstring + "_" + import_key + "\\";
|
|
if (!fso.FolderExists(backDir))
|
|
fso.CreateFolder(backDir);
|
|
|
|
return backDir;
|
|
}
|
|
|
|
function XMLval(xml, tag)
|
|
{
|
|
if (!xml)
|
|
return null;
|
|
var xx = xml.getElementsByTagName(tag);
|
|
if (!xx || !xx.length)
|
|
return null;
|
|
xx = xx[0].childNodes
|
|
if (!xx || !xx.length)
|
|
return null;
|
|
return xx[0].nodeValue;
|
|
}
|
|
|
|
function add2bijlagen(pModule, pKenmerkKey, pKey, pSafefilename, params)
|
|
{
|
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|
var oCrypto = new ActiveXObject("SLNKDWF.Crypto");
|
|
var sql = "BEGIN "
|
|
+ " flx.setflexbijlage"
|
|
+ "(" + safe.quoted_sql(pModule) // MLD | RES | ....
|
|
+ ", " + pKenmerkKey
|
|
+ ", " + pKey
|
|
+ ", " + safe.quoted_sql(params.AttachSubPath)
|
|
+ ", " + "NULL" // diskfilename
|
|
+ ", " + safe.quoted_sql(pSafefilename)
|
|
+ ", " + fso.GetFile(params.AttachPath + pSafefilename).Size
|
|
+ ", " + "SYSDATE"
|
|
+ ", " + safe.quoted_sql(oCrypto.hex_sha1_file(params.AttachPath + pSafefilename))
|
|
+ ");"
|
|
+ " END;";
|
|
Oracle.Execute(sql);
|
|
}
|
|
|
|
function extractAttachments(safeSourceXML, filename, flexcode)
|
|
{
|
|
__Log("Attachments uit {0} extraheren en opslaan volgens {1}".format(safeSourceXML, flexcode));
|
|
var arr = flexcode.split(":"); // FIN:12345:18:F
|
|
var pModule = arr[0];
|
|
if (arr.length > 1)
|
|
var pKey = parseInt(arr[1], 10);
|
|
if (arr.length > 2)
|
|
var pKenmerkKey = parseInt(arr[2], 10);
|
|
if (arr.length > 3)
|
|
var pNiveau = arr[3];
|
|
var params = flexProps(pModule, pKey, pKenmerkKey, pNiveau);
|
|
|
|
//fileStream.CharSet = charset; // Vroeg, anders krijgen we een BOM?
|
|
var oStream = new ActiveXObject("ADODB.Stream");
|
|
oStream.Type = 1; //adTypeBinary
|
|
oStream.Open;
|
|
var oZIP = new ActiveXObject("SLNKDWF.Zip");
|
|
oZIP.Open(safeSourceXML);
|
|
oZIP.UnzipToStream(oStream, filename);
|
|
|
|
var xmldoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
|
|
xmldoc.async = false;
|
|
xmldoc.resolveExternals = false; // XML-data vertrouwen we niet altijd
|
|
xmldoc.validateOnParse = false; // maar dan kun je geen DTD's meer controleren
|
|
xmldoc.setProperty("ProhibitDTD", false); // niet moeilijk doen over DTD's
|
|
|
|
oStream.Position = 0;
|
|
if( ! xmldoc.load(oStream) ) // De XML terug laden
|
|
{
|
|
return { success: false, warning: filename + "\nXML error: " + xmldoc.parseError.reason + " @ " + xmldoc.parseError.line + "." + xmldoc.parseError.linepos };
|
|
}
|
|
oZIP.Close();
|
|
oStream.Close();
|
|
//
|
|
// Dit is het enige formaat wat we (hardcoded) ondersteunen. DocumentType en FileType negeren we
|
|
// <Attachment>
|
|
// <AttachedData>JVBERi0xLjQKJcfsjCi9<....></AttachedData>
|
|
// <DocumentType>FAC</DocumentType>
|
|
// <FileType>PDF</FileType>
|
|
// <FileName>0123456789123_201403159.pdf</FileName>
|
|
// </Attachment>
|
|
|
|
|
|
var Attachments = xmldoc.getElementsByTagName("Attachment");
|
|
var nr_att_1 = Attachments.length;
|
|
__Log("Variabele nr_att_1: " + nr_att_1);
|
|
for (var i=0; i < Attachments.length; i++)
|
|
{
|
|
var safefilename = safe.filename(XMLval(Attachments[i], "FileName"));
|
|
if (!params.isAllowedName(safefilename))
|
|
{
|
|
// TODO: Misschien ook terugkoppelen in IMP_LOG?
|
|
__Log("Onbekende extensie upload bijlage: {0}. Bestand is niet opgeslagen.".format(safefilename));
|
|
}
|
|
else
|
|
{
|
|
__Log('Bijlage {0} mag naar {1}'.format(safefilename, params.AttachPath));
|
|
var AttachmentData = XMLval(Attachments[i], "AttachedData");
|
|
if (AttachmentData)
|
|
{
|
|
CreateFullPath(params.AttachPath);
|
|
encodedString2File(params.AttachPath + safefilename, AttachmentData, "bin.base64");
|
|
add2bijlagen(pModule, pKenmerkKey, pKey, safefilename, params)
|
|
__Log("Done saving: " + params.AttachPath + safefilename);
|
|
}
|
|
else
|
|
__Log("Empty file skipped: " + safefilename);
|
|
}
|
|
}
|
|
if (nr_att_1 == 0){
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:sales005='http://www.ketenstandaard.nl/onderhoudsopdracht/SALES/005'");
|
|
var Attachments = xmldoc.selectNodes("//sales005:Attachment");
|
|
var nr_att_1 = Attachments.length;
|
|
__Log("Variabele nr_att_1: " + nr_att_1);
|
|
for (var i=0; i < Attachments.length; i++)
|
|
{
|
|
var l_filenaam_node = Attachments[i].selectSingleNode("sales005:FileName");
|
|
var l_base64_node = Attachments[i].selectSingleNode("sales005:AttachedData");
|
|
if (l_filenaam_node && l_base64_node)
|
|
{
|
|
__Log("XML filename: " + l_filenaam_node.text);
|
|
__Log("XML base64: " + l_base64_node.text);
|
|
|
|
var safefilename = safe.filename(l_filenaam_node.text);
|
|
__Log("safefilename: " + safefilename);
|
|
if (!params.isAllowedName(safefilename))
|
|
{
|
|
// TODO: Misschien ook terugkoppelen in IMP_LOG?
|
|
__Log("Onbekende extensie upload bijlage: {0}. Bestand is niet opgeslagen.".format(safefilename));
|
|
}
|
|
else
|
|
{
|
|
__Log('Bijlage {0} mag naar {1}'.format(safefilename, params.AttachPath));
|
|
var AttachmentData = l_base64_node.text;
|
|
if (AttachmentData)
|
|
{
|
|
CreateFullPath(params.AttachPath);
|
|
encodedString2File(params.AttachPath + safefilename, AttachmentData, "bin.base64");
|
|
add2bijlagen(pModule, pKenmerkKey, pKey, safefilename, params)
|
|
__Log("Done saving: " + params.AttachPath + safefilename);
|
|
}
|
|
else
|
|
__Log("Empty file skipped: " + safefilename);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// En ook:
|
|
// <cac:AdditionalDocumentReference>
|
|
// <cbc:ID>V1700746.pdf</cbc:ID>
|
|
// <cbc:DocumentType>PrimaryImage</cbc:DocumentType>
|
|
// <cac:Attachment>
|
|
// <cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf">
|
|
// ... base64 ...
|
|
// </cbc:EmbeddedDocumentBinaryObject>
|
|
// </cac:Attachment>
|
|
// </cac:AdditionalDocumentReference>
|
|
//
|
|
// filename kan ook opgegeven zijn via:
|
|
// <cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf" filename="1205_17180793_03002557.pdf">
|
|
|
|
var Attachments = xmldoc.getElementsByTagName("cac:AdditionalDocumentReference");
|
|
var nr_att_2 = Attachments.length;
|
|
__Log("Variabele nr_att_2: " + nr_att_2);
|
|
for (var i=0; i < Attachments.length; i++)
|
|
{
|
|
// Eerst maar eens het attribute 'filename' zoeken
|
|
var filename = "";
|
|
var Attachment = Attachments[i].getElementsByTagName("cbc:EmbeddedDocumentBinaryObject");
|
|
if (Attachment.length)
|
|
filename = Attachment[0].getAttribute("filename");
|
|
if (!filename)
|
|
{ // Als geen filenaam-attribuut aanwezig, dan proberen we element ID
|
|
filename = XMLval(Attachments[i], "cbc:ID");
|
|
}
|
|
if (filename &&
|
|
!filename.match(/\.pdf$/i) &&
|
|
Attachment.length &&
|
|
Attachment[0].getAttribute("mimeCode") == "application/pdf")
|
|
{
|
|
filename += ".pdf";
|
|
}
|
|
var safefilename = safe.filename(filename);
|
|
if (!params.isAllowedName(safefilename))
|
|
{
|
|
// TODO: Misschien ook terugkoppelen in IMP_LOG?
|
|
__Log("Onbekende extensie upload bijlage: {0}. Bestand is niet opgeslagen.".format(safefilename));
|
|
}
|
|
else
|
|
{
|
|
__Log('Bijlage {0} mag naar {1}'.format(safefilename, params.AttachPath));
|
|
var AttachmentData = XMLval(Attachments[i], "cbc:EmbeddedDocumentBinaryObject");
|
|
if (AttachmentData)
|
|
{
|
|
CreateFullPath(params.AttachPath);
|
|
encodedString2File(params.AttachPath + safefilename, AttachmentData, "bin.base64");
|
|
add2bijlagen(pModule, pKenmerkKey, pKey, safefilename, params)
|
|
__Log("Done saving: " + params.AttachPath + safefilename);
|
|
}
|
|
else
|
|
__Log("Empty file skipped: " + safefilename);
|
|
}
|
|
}
|
|
|
|
// MARX#49027: PDF uit XMLfactuur (harde node) werkt niet bij INSBOU004,
|
|
// default namespace icm method getElementsByTagName werkt niet,
|
|
// vervangen door selectSingleNode en expliciet property 'SelectionNamespaces' zetten
|
|
if (nr_att_1 == 0 && nr_att_2 == 0)
|
|
{
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:insbou4='http://www.gs1.nl/factuur/insbou/004'");
|
|
var l_filenaam_node = xmldoc.selectSingleNode("//insbou4:Attachment/insbou4:FileName");
|
|
var l_base64_node = xmldoc.selectSingleNode("//insbou4:Attachment/insbou4:AttachedData");
|
|
// MARX#55904: PDF uit XMLfactuur (harde node) werkt niet bij SALES005
|
|
if (!l_filenaam_node || !l_base64_node){
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:sales005='http://www.ketenstandaard.nl/factuur/SALES/005'");
|
|
var l_filenaam_node = xmldoc.selectSingleNode("//sales005:Attachment/sales005:FileName");
|
|
var l_base64_node = xmldoc.selectSingleNode("//sales005:Attachment/sales005:AttachedData");
|
|
}
|
|
if (l_filenaam_node && l_base64_node){
|
|
var l_filenaam_text = l_filenaam_node.text;
|
|
__Log("Variabele l_filenaam_text: " + l_filenaam_text);
|
|
var l_base64_text = l_base64_node.text;
|
|
__Log("Variabele l_base64_text: " + l_base64_text);
|
|
|
|
var safefilename = safe.filename(l_filenaam_text);
|
|
if (!params.isAllowedName(safefilename))
|
|
{
|
|
// TODO: Misschien ook terugkoppelen in IMP_LOG?
|
|
__Log("Onbekende extensie upload bijlage: {0}. Bestand is niet opgeslagen.".format(safefilename));
|
|
}
|
|
else
|
|
{
|
|
__Log('Bijlage {0} mag naar {1}'.format(safefilename, params.AttachPath));
|
|
var AttachmentData = l_base64_text;
|
|
if (AttachmentData)
|
|
{
|
|
CreateFullPath(params.AttachPath);
|
|
encodedString2File(params.AttachPath + safefilename, AttachmentData, "bin.base64");
|
|
add2bijlagen(pModule, pKenmerkKey, pKey, safefilename, params)
|
|
__Log("Done saving: " + params.AttachPath + safefilename);
|
|
}
|
|
else
|
|
__Log("Empty file skipped: " + safefilename);
|
|
}
|
|
}
|
|
else{
|
|
//51764: PDF attachment in CDATA (ketenstandaard MessageSevice) ?
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:mes='http://etim.nl/xmlschemas/messageservice/2.40'");
|
|
var l_cdata_node = xmldoc.selectSingleNode("//mes:MsgContent");
|
|
if (! l_cdata_node){
|
|
__Log("Cdata MessageService/2.4 NOT found");
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:mes='https://www.ketenstandaard.nl/WS/MessageService/3.0'");
|
|
var l_cdata_node = xmldoc.selectSingleNode("//mes:MsgContent");
|
|
}
|
|
if (! l_cdata_node){
|
|
__Log("Cdata MessageService/2.4 AND 3.0 NOT found");
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:mes='https://www.ketenstandaard.nl/WS/MessageService/3.1'");
|
|
var l_cdata_node = xmldoc.selectSingleNode("//mes:MsgContent");
|
|
}
|
|
if (! l_cdata_node){
|
|
__Log("Cdata MessageService/2.4 AND 3.0 AND 3.1 NOT found");
|
|
var l_cdata_node = xmldoc.selectSingleNode("//MsgContent");
|
|
}
|
|
if (l_cdata_node){
|
|
__Log("Cdata found: " + l_cdata_node.text);
|
|
xmldoc.loadXML("" + l_cdata_node.text.replace(/^\n*/, '')); // Leading \n er af voor als er een xml-declaratie vooraan staat.
|
|
if (xmldoc.parseError.errorCode != 0)
|
|
{
|
|
__DoLog("\nXML error in CDATA: " + xmldoc.parseError.reason + " @ " + xmldoc.parseError.line + "." + xmldoc.parseError.linepos);
|
|
return { success: false, warning: filename + "\nXML error in CDATA: " + xmldoc.parseError.reason + " @ " + xmldoc.parseError.line + "." + xmldoc.parseError.linepos };
|
|
}
|
|
|
|
__Log("l_cdata_node loaded in xmldoc");
|
|
var l_filenaam_node = xmldoc.selectSingleNode("//Attachment/FileName");
|
|
var l_base64_node = xmldoc.selectSingleNode("//Attachment/AttachedData");
|
|
if (!l_filenaam_node || !l_base64_node){
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:insbou4='http://www.gs1.nl/factuur/insbou/004'");
|
|
var l_filenaam_node = xmldoc.selectSingleNode("//insbou4:Attachment/insbou4:FileName");
|
|
var l_base64_node = xmldoc.selectSingleNode("//insbou4:Attachment/insbou4:AttachedData");
|
|
}
|
|
// MARX#55904: PDF uit XMLfactuur (harde node) werkt niet bij SALES005
|
|
if (!l_filenaam_node || !l_base64_node){
|
|
xmldoc.setProperty ("SelectionNamespaces", "xmlns:sales005='http://www.ketenstandaard.nl/factuur/SALES/005'");
|
|
var l_filenaam_node = xmldoc.selectSingleNode("//sales005:Attachment/sales005:FileName");
|
|
var l_base64_node = xmldoc.selectSingleNode("//sales005:Attachment/sales005:AttachedData");
|
|
}
|
|
if (l_filenaam_node && l_base64_node){
|
|
var l_filenaam_text = l_filenaam_node.text;
|
|
__Log("Variabele l_filenaam_text: " + l_filenaam_text);
|
|
var l_base64_text = l_base64_node.text;
|
|
__Log("Variabele l_base64_text: " + l_base64_text);
|
|
var safefilename = safe.filename(l_filenaam_text);
|
|
if (!params.isAllowedName(safefilename))
|
|
{
|
|
// TODO: Misschien ook terugkoppelen in IMP_LOG?
|
|
__Log("Onbekende extensie upload bijlage: {0}. Bestand is niet opgeslagen.".format(safefilename));
|
|
}
|
|
else
|
|
{
|
|
__Log('Bijlage {0} mag naar {1}'.format(safefilename, params.AttachPath));
|
|
var AttachmentData = l_base64_text;
|
|
if (AttachmentData)
|
|
{
|
|
CreateFullPath(params.AttachPath);
|
|
encodedString2File(params.AttachPath + safefilename, AttachmentData, "bin.base64");
|
|
add2bijlagen(pModule, pKenmerkKey, pKey, safefilename, params)
|
|
__Log("Done saving: " + params.AttachPath + safefilename);
|
|
}
|
|
else
|
|
__Log("Empty file skipped: " + safefilename);
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
__Log("Cdata NOT found");
|
|
}
|
|
}
|
|
}
|
|
|
|
return { success: true };
|
|
}
|