460 lines
18 KiB
PHP
460 lines
18 KiB
PHP
<% /*
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: model_report_columns.inc
|
|
|
|
Description: rapport model voor de kolommen van rapporten.
|
|
|
|
Parameters:
|
|
Context:
|
|
|
|
Notes:
|
|
*/
|
|
|
|
// model_reportcolumns is uitsluitend beschikbaar onder model_reports(x) die de autorisatie dan ook doet
|
|
// TODO: neen, security lek FSN#33869
|
|
function model_reportcolumns(usrrap_key, params)
|
|
{
|
|
var rap_key = getQParamInt("fac_usrrap_key", -1); // JGL: Lelijk
|
|
|
|
params = params || {};
|
|
this.table = "fac_usrrap_cols";
|
|
this.primary = "fac_usrrap_cols_key";
|
|
this.records_name = "columns";
|
|
this.record_name = "column";
|
|
this.records_title = L("lcl_rap_columns");
|
|
this.record_title = L("lcl_rap_column");
|
|
this.autfunction = "WEB_UDRMAN",
|
|
this.edit = { modal: true };
|
|
|
|
this.fields = {
|
|
"id": {
|
|
dbs: "fac_usrrap_cols_key",
|
|
typ: "key",
|
|
label: "Key",
|
|
filter: "exact",
|
|
seq: "fac_s_fac_usrrap_cols_key"
|
|
},
|
|
"name": {
|
|
dbs: "fac_usrrap_cols_column_name",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_column"),
|
|
required: true,
|
|
insertonly: true
|
|
},
|
|
"datatype": {
|
|
dbs: "fac_usrrap_cols_datatype",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_datatype"),
|
|
required: true,
|
|
LOV: L("lcl_rap_datatypeLOV") // "varchar;Tekst;date;Datum;datetime;Datumtijd;float;Float;currency;Bedrag;number;Getal"
|
|
},
|
|
"sequence": {
|
|
dbs: "fac_usrrap_cols_volgnr",
|
|
typ: "number",
|
|
label: L("lcl_rap_sequence"),
|
|
required: true
|
|
},
|
|
"caption": {
|
|
dbs: "fac_usrrap_cols_caption",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_caption"),
|
|
required: true,
|
|
translate: true
|
|
},
|
|
"filter": {
|
|
dbs: "fac_usrrap_cols_filter",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_filter"),
|
|
LOV: L("lcl_rap_filterLOV") // "A;Automatisch"
|
|
},
|
|
"filterdefault": {
|
|
dbs: "fac_usrrap_cols_filterdefault",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_filterdefault")
|
|
},
|
|
"visible": {
|
|
dbs: "fac_usrrap_cols_visible",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_visible"),
|
|
required: true,
|
|
LOV: L("lcl_rap_visibleLOV"), // "V;Visible;I;Invisible;H;hidden"
|
|
emptyoption: null
|
|
},
|
|
"group": {
|
|
dbs: "fac_usrrap_cols_group",
|
|
typ: "varchar",
|
|
label: L("lcl_rap_groupby"),
|
|
required: true,
|
|
LOV: L("lcl_rap_groupbyLOV"),
|
|
emptyoption: null
|
|
},
|
|
"fac_usrrap_key": {
|
|
dbs: "fac_usrrap_key",
|
|
typ: "key",
|
|
hidden_fld: true
|
|
},
|
|
"expression": {
|
|
dbs: "fac_usrrap_cols_expression",
|
|
typ: "memo",
|
|
label: "sql-expressie",
|
|
required: true,
|
|
readonly: true
|
|
}
|
|
};
|
|
|
|
this.fnrowClass = function _fnrowClass(oRs)
|
|
{
|
|
return "report_" + oRs.Fields("visible").Value.id;
|
|
}
|
|
|
|
this.list = {
|
|
columns: [
|
|
"sequence",
|
|
"name",
|
|
"caption",
|
|
"datatype",
|
|
"visible",
|
|
"filter",
|
|
"group"
|
|
],
|
|
rowClass: this.fnrowClass
|
|
};
|
|
|
|
this.hook_pre_edit = function (obj, fld)
|
|
{
|
|
this.fields.filter.LOV = api2.filterLOV(L("lcl_rap_filterLOV"), "A,E,R"); // De meesten mogen L(ike) niet
|
|
if ((obj.datatype && !obj.expression) || !user.has("WEB_FACTAB"))
|
|
{
|
|
switch (obj.datatype.id)
|
|
{
|
|
case "date":
|
|
case "datetime":
|
|
this.fields.group.LOV = api2.filterLOV(L("lcl_rap_groupbyLOV"), "G,D,W,M,Q,Y,H");
|
|
this.fields.datatype.LOV = api2.filterLOV(L("lcl_rap_datatypeLOV"), "date,datetime,time");
|
|
break;
|
|
case "time":
|
|
this.fields.group.LOV = api2.filterLOV(L("lcl_rap_groupbyLOV"), "G,H");
|
|
this.fields.datatype.LOV = api2.filterLOV(L("lcl_rap_datatypeLOV"), "date,datetime,time");
|
|
break;
|
|
case "varchar":
|
|
this.fields.group.LOV = api2.filterLOV(L("lcl_rap_groupbyLOV"), "G");
|
|
this.fields.datatype.readonly = true;
|
|
this.fields.filter.LOV = L("lcl_rap_filterLOV"); // die mag alle filters
|
|
break;
|
|
case "html":
|
|
this.fields.group.LOV = api2.filterLOV(L("lcl_rap_groupbyLOV"), "G");
|
|
this.fields.datatype.readonly = true;
|
|
this.fields.filter.LOV = L("lcl_rap_filterLOV");
|
|
break;
|
|
case "float":
|
|
case "number":
|
|
case "currency":
|
|
this.fields.group.LOV = api2.filterLOV(L("lcl_rap_groupbyLOV"), "G,S,C,A");
|
|
this.fields.datatype.LOV = api2.filterLOV(L("lcl_rap_datatypeLOV"), "float,currency,number");
|
|
break;
|
|
default:
|
|
this.fields.group.LOV = api2.filterLOV(L("lcl_rap_groupbyLOV"), "G");
|
|
}
|
|
}
|
|
|
|
if (user.has("WEB_FACTAB") && (obj.expression || !obj.id))
|
|
{
|
|
this.fields.expression.readonly = false;
|
|
this.fields.name.insertonly = false;
|
|
// Een zelf toegevoegd veld mag ook verwijderd worden.
|
|
if (obj.expression)
|
|
{
|
|
this.REST_DELETE = generic_REST_DELETE(this); //this._REST_DELETE;
|
|
}
|
|
}
|
|
};
|
|
|
|
this.hook_pre_post = function (params, obj)
|
|
{
|
|
if (obj.id == -1)
|
|
this.fields.expression.readonly = false;
|
|
};
|
|
|
|
this.hook_pre_delete = function (params, columns_key)
|
|
{
|
|
this.REST_DELETE = generic_REST_DELETE(this);
|
|
};
|
|
|
|
// Maakt de default fac_usrrap_cols records aan aan de hand van de view of werk ze bij
|
|
this._view2columns = function (usrrap_key, lastrefresh, oldcols)
|
|
{
|
|
var sql = "SELECT fac_usrrap_view_name"
|
|
+ " , fac_usrrap_functie"
|
|
+ " FROM fac_usrrap"
|
|
+ " WHERE fac_usrrap_key = " + usrrap_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var view_name = oRs("fac_usrrap_view_name").Value;
|
|
var is_view_name = (oRs("fac_usrrap_functie").Value & 2) == 0; // niet de procedures
|
|
oRs.Close();
|
|
|
|
if (!is_view_name) return;
|
|
|
|
// Rapport kan ook zijn XXXX.RAP_YYYYY?
|
|
// PF: jawel, maar dan is het een procedure waarvan je de structuur niet zo op kunt vragen?!
|
|
// Vandaar de regel hiervoor, die zorgt dat we hier al weg zijn. Ik denk dat de shortname dan verder
|
|
// niet meer voorkomt eigenlijk.
|
|
var view_name_short = view_name.toUpperCase();
|
|
var i = view_name_short.indexOf('.');
|
|
if (i != -1)
|
|
view_name_short = view_name_short.substring(i+1);
|
|
|
|
var hasFACFAC = user.checkAutorisation("WEB_FACFAC", true); // Die mag ook tabellen doen
|
|
var sql = "SELECT object_name, object_type, last_ddl_time, status"
|
|
+ " FROM user_objects"
|
|
+ " WHERE "
|
|
+ (hasFACFAC ? "object_type IN ('VIEW', 'TABLE')" : " object_type = 'VIEW'")
|
|
+ " AND object_name = UPPER(" + safe.quoted_sql(view_name_short) + ")";
|
|
var oRs = Oracle.Execute(sql);
|
|
if (oRs.Eof)
|
|
abort_with_warning("Unable to determine columns for report view '{0}'!".format(view_name_short));
|
|
|
|
if (oRs("status").Value != 'VALID') // Gebeurt nog wel eens na een dump-refresh
|
|
{
|
|
if (oRs("object_type").Value == 'VIEW')
|
|
{
|
|
__DoLog("Auto compile invalid {0}".format(view_name_short));
|
|
Oracle.Execute("ALTER VIEW {0} COMPILE".format(view_name_short));
|
|
oRs.Close();
|
|
var oRs = Oracle.Execute(sql); // Tweede poging
|
|
}
|
|
}
|
|
if (oRs("status").Value != 'VALID')
|
|
abort_with_warning("Report view '{0}' is INVALID!".format(view_name_short));
|
|
|
|
var view_ddl_time = new Date(oRs("last_ddl_time").Value);
|
|
oRs.Close();
|
|
var mustRefresh = (oldcols.length == 0 || !lastrefresh || view_ddl_time > lastrefresh);
|
|
|
|
if (!mustRefresh)
|
|
return;
|
|
|
|
var sequence = 10;
|
|
var sql = "SELECT INITCAP(column_name) column_name"
|
|
+ " , data_type"
|
|
+ " , data_length"
|
|
+ " , data_precision"
|
|
+ " , data_scale"
|
|
+ " FROM user_tab_columns"
|
|
+ " WHERE table_name = UPPER(" + safe.quoted_sql(view_name_short) + ")"
|
|
+ " ORDER BY column_id";
|
|
var oRs = Oracle.Execute(sql);
|
|
var newcols = [];
|
|
while (!oRs.eof)
|
|
{
|
|
var colname = oRs.Fields("column_name").Value.toLowerCase();
|
|
var colpar = { caption: oRs.Fields("column_name").Value, // Met de initcap
|
|
name: colname,
|
|
datatype: "varchar",
|
|
group: 'G',
|
|
sequence: sequence,
|
|
visible: 'V',
|
|
filter: null
|
|
};
|
|
sequence += 10;
|
|
var ucolname = colname.toUpperCase();
|
|
|
|
var special_cols = ucolname.match(/^(HIDE_F_|FCLT_X_|FCLT_3D_|FCLT_KEY|FCLT_F_|HTML_|FCLT_D_|FCLT_C_)/);
|
|
if (special_cols)
|
|
colpar.caption = colpar.caption.substring(special_cols[0].length);
|
|
colpar.caption = colpar.caption.replace(/\_/g, " "); // underscores er uit
|
|
|
|
if (ucolname.match(/^(HIDE_F_|FCLT_3D_|FCLT_KEY)/))
|
|
colpar.visible = 'H'; // Hidden
|
|
|
|
if (ucolname.match(/^(FCLT_X_)/))
|
|
colpar.visible = 'I'; // Invisible, je mag hem wel aanzetten
|
|
|
|
if (view_name_short.match(/_V_UDR/))
|
|
colpar.visible = 'H'; // Hidden, die hebben te veel kolommen
|
|
|
|
if (ucolname.match(/^(FCLT_F_|FCLT_X_)/))
|
|
colpar.filter = 'A';
|
|
if (ucolname.match(/^(FCLT_D_)/))
|
|
colpar.filter = 'R'; // Altijd range
|
|
|
|
var ora_type = oRs("data_type").Value;
|
|
var ora_length = oRs("data_length").Value;
|
|
var ora_precision = oRs("data_precision").Value;
|
|
var ora_scale = oRs("data_scale").Value;
|
|
|
|
if (ucolname.match("^FCLT_C_")) // Currency
|
|
{
|
|
colpar.datatype = 'currency';
|
|
}
|
|
else if (ucolname.match("^HTML_"))
|
|
{
|
|
colpar.datatype = 'html';
|
|
}
|
|
else if (ora_type == 'NUMBER')
|
|
{
|
|
colpar.datatype = 'number';
|
|
if (ora_scale > 0)
|
|
{
|
|
colpar.datatype = 'float';
|
|
}
|
|
}
|
|
else if (ora_type == "DATE") //
|
|
{
|
|
colpar.datatype = 'date';
|
|
}
|
|
|
|
newcols.push(colpar);
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.Close();
|
|
|
|
// Vervallen kolommen
|
|
for (var o = 0; o < oldcols.length; o++)
|
|
{
|
|
var found = false;
|
|
for (var n = 0; !found && n < newcols.length; n++)
|
|
{
|
|
if (newcols[n].name == oldcols[o].name)
|
|
found = true;
|
|
}
|
|
if (!found)
|
|
{
|
|
__Log("Dropping column {0}".format(oldcols[o].name));
|
|
// We kennen geen REST_DELETE
|
|
var sql = "DELETE fac_usrrap_cols"
|
|
+ " WHERE fac_usrrap_cols_expression IS NULL"
|
|
+ " AND fac_usrrap_cols_key = " + oldcols[o].id;
|
|
Oracle.Execute(sql);
|
|
}
|
|
}
|
|
|
|
// Nieuwe en gewijzigde kolommen
|
|
for (var n = 0; n < newcols.length; n++)
|
|
{
|
|
var found = false;
|
|
for (var o = 0; !found && o < oldcols.length; o++)
|
|
{
|
|
if (newcols[n].name == oldcols[o].name)
|
|
{
|
|
found = true;
|
|
if (newcols[n].datatype == oldcols[o].datatype.id)
|
|
continue;
|
|
// wisseling binnen float,currency,number is niet erg
|
|
if (inArray(newcols[n].datatype, "float,currency,number".split(",")) &&
|
|
inArray(oldcols[o].datatype.id, "float,currency,number".split(",")))
|
|
continue;
|
|
// wisseling binnen date,datetime,time is ook niet erg
|
|
if (inArray(newcols[n].datatype, "date,datetime,time".split(",")) &&
|
|
inArray(oldcols[o].datatype.id, "date,datetime,time".split(",")))
|
|
continue;
|
|
|
|
// datatype aanpassen
|
|
__Log("Updating datatype column {0} to {1}".format(oldcols[o].name, newcols[n].datatype));
|
|
this._REST_PUT({}, { datatype: newcols[n].datatype }, oldcols[o].id)
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
__Log("Adding column {0}".format(newcols[n].name));
|
|
var params = { internal: true };
|
|
this._REST_POST(params, newcols[n], usrrap_key); // internal _REST_POST is er altijd
|
|
}
|
|
}
|
|
|
|
// update lastrefresh. reports.REST_PUT is mij te kritisch op rechten
|
|
var sql = "UPDATE fac_usrrap"
|
|
+ " SET fac_usrrap_col_refresh = SYSDATE"
|
|
+ " WHERE fac_usrrap_key = " + usrrap_key;
|
|
Oracle.Execute(sql);
|
|
}
|
|
|
|
this.REST_GET = function _GET(params)
|
|
{
|
|
// De modal detail popup gebruikt dit echter nog wel.
|
|
var query = api2.sqlfields(params, this );
|
|
var wheres = api2.sqlfilter(params, this);
|
|
query.wheres = query.wheres.concat(wheres);
|
|
|
|
var sql = "SELECT " + query.selects.join(", ")
|
|
+ " FROM " + query.tables.join(", ")
|
|
+ " WHERE " + query.wheres.join(" AND " )
|
|
+ " ORDER BY fac_usrrap_cols_volgnr";
|
|
|
|
var json = api2.sql2json (params, sql, this );
|
|
if (!json.length)
|
|
{
|
|
INTERNAL_ERROR_MISSING_COLUMNS;
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
this.REST_PUT = function (params, jsondata, the_key) /* update columns */
|
|
{
|
|
var valid_char = /^[_0-9a-zA-Z]+$/; // Alleen deze tekens zijn geldig!
|
|
if (!valid_char.test(jsondata.name))
|
|
abort_with_warning(L("lcl_rap_column_invalid"));
|
|
|
|
if (user.has("WEB_FACTAB") && (jsondata.expression || !jsondata.id))
|
|
{
|
|
this.fields.expression.readonly = false;
|
|
this.fields.name.insertonly = false;
|
|
}
|
|
|
|
var dbfields = api2.update_fields(params, this, jsondata); // Build updater
|
|
|
|
var sql = buildUpdate("fac_usrrap_cols", dbfields, { noValidateToken: true }) + " fac_usrrap_cols_key = " + the_key;
|
|
var err = Oracle.Execute(sql, true);
|
|
if (err.friendlyMsg)
|
|
abort_with_warning(err.friendlyMsg);
|
|
|
|
return { key: the_key };
|
|
}
|
|
|
|
this._REST_PUT = this.REST_PUT; // Interne is er altijd
|
|
|
|
// Only internally used by report_clone and _view2columns
|
|
this._REST_POST = function (params, jsondata, parent_key) /* insert columns */
|
|
{
|
|
var valid_char = /^[_0-9a-zA-Z]+$/;
|
|
if (!valid_char.test(jsondata.name))
|
|
abort_with_warning(L("lcl_rap_column_invalid"));
|
|
|
|
var dbfields = api2.update_fields(params, this, jsondata); // Build updater
|
|
|
|
dbfields["id"] = this.fields["id"];
|
|
if (parent_key && !jsondata.fac_usrrap_key)
|
|
dbfields["xxx"] = { dbs: "fac_usrrap_key", typ: "key", val: parent_key };
|
|
|
|
var rapIns = buildInsert("fac_usrrap_cols", dbfields, { noValidateToken: true });
|
|
var col_key = rapIns.sequences["fac_usrrap_col_key"];
|
|
|
|
var err = Oracle.Execute(rapIns.sql, true);
|
|
if (err.friendlyMsg)
|
|
abort_with_warning(err.friendlyMsg);
|
|
|
|
return { key: col_key, warning: "" };
|
|
}
|
|
|
|
if (rap_key > 0)
|
|
{
|
|
// var rap_data = model_reportsx(rap_key); te veel recursie
|
|
var sql = "SELECT fac_usrrap_functie"
|
|
+ " FROM fac_usrrap"
|
|
+ " WHERE fac_usrrap_key = " + rap_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var functie = oRs("fac_usrrap_functie").Value || 0;
|
|
oRs.Close();
|
|
if (functie & 32) // template
|
|
this.REST_PUT = false;
|
|
}
|
|
|
|
if (params.internal || user.has("WEB_FACTAB"))
|
|
{
|
|
this.REST_POST = this._REST_POST; // Voor de clone-report
|
|
}
|
|
}
|
|
|
|
%> |