Files
Facilitor/APPL/API2/model_issues.inc
2015-01-06 12:02:06 +00:00

520 lines
27 KiB
PHP

<% /*
$Revision$
$Id$
File: model_issues.inc
Description: Melding model. Dit bestand heeft niets met interfacing te maken
maar werkt uitsluitend op JSON-data
Parameters:
Context:
Notes: TODO on demand: PUT/POST/DELETE
TODO test autorisatie-toepassing (MGE?)
*/
%>
<!-- #include file="../Shared/discx3d.inc" -->
<!-- #include file="../mld/mld.inc" -->
<!-- #include file="model_issueobjects.inc"-->
<!-- #include file="model_notes.inc"-->
<!-- #include file="model_orders.inc"-->
<%
model_issues =
{
module: "MLD",
table: "mld_melding",
// aliasprefix: "", // Deze prefix wordt voor fields.name gezet.
primary: "mld_melding_key",
records_name: "issues",
record_name: "issue",
fields: [{ name: "id", dbs: "mld_melding_key", typ: "key", filter: "exact" },
{ name: "name", dbs: "mld_melding_id", typ: "varchar", sql: "ins_srtdiscipline.ins_srtdiscipline_prefix||mld_melding.mld_melding_key", filter: "exact" },
{ name: "contact", dbs: "prs_perslid_key", typ: "key", foreign: "prs_perslid", track: L("lcl_mld_name"), filter: "exact" },
{ name: "requestor", dbs: "prs_perslid_key_voor", typ: "key", foreign: "prs_perslid", track: L("lcl_mld_call_for"), filter: "exact" },
{ name: "issuedate", dbs: "mld_melding_datum", typ: "datetime", track: L("lcl_mld_date_time")},
{ name: "enddate", dbs: "mld_melding_einddatum", typ: "datetime", track: L("lcl_mld_enddate")},
{ name: "issuetype", dbs: "mld_stdmelding_key", typ: "key", foreign: "mld_stdmelding", track: L("lcl_complain"), filter: "exact" },
{ name: "description", dbs: "mld_melding_omschrijving", typ: "varchar", track: L("lcl_descr"), filter: "like" },
{ name: "remark", dbs: "mld_melding_opmerking", typ: "varchar", track: L("lcl_remark")},
{ name: "status", dbs: "mld_melding_status", typ: "key", foreign: mld.getmldstatustext, track: L("lcl_status"), filter: "exact" },
{ name: "flag", dbs: "mld_melding_flag", typ: "key", /* geen echte key, wel key-gedrag */ track: L("lcl_mld_flags"), filter: "exact" },
{ name: "account", dbs: "prs_kostenplaats_key", typ: "key", foreign: "prs_kostenplaats", track: L("lcl_account"), filter: "exact" },
{ name: "handler", dbs: "mld_melding_behandelaar_key", typ: "key", foreign: "prs_perslid", track: L("lcl_mld_behandelaar"), filter: "exact" },
{ name: "location", dbs: "mld_alg_locatie_key", typ: "key", foreign: "alg_locatie", track: L("lcl_location"), filter: "exact" },
{ name: "building", dbs: "alg_v_allonroerendgoed.alg_gebouw_key", typ: "key", foreign: "alg_gebouw", track: L("lcl_building"), filter: "exact" },
{ name: "floor", dbs: "alg_v_allonroerendgoed.alg_verdieping_key", typ: "key", foreign: "alg_verdieping", track: L("lcl_floor"), filter: "exact" },
{ name: "room", dbs: "alg_v_allonroerendgoed.alg_ruimte_key", typ: "key", foreign: "alg_ruimte", track: L("lcl_room"), filter: "exact" },
{ name: "terrain", dbs: "alg_v_allonroerendgoed.alg_terreinsector_key", typ: "key", foreign: "alg_terreinsector", track: L("lcl_room"), filter: "exact" }
],
includes: {
"issueobjects": {
model: model_issueobjects,
joinfield: "mld_melding_key",
single_only: false
},
"notes": {
model: model_notes,
joinfield: "parent_key",
single_only: false,
joinfunction: function (params)
{
/* gaat uit dat die wordt geimplementeerd met een view fac_v_notes (module, key, columns....) */
return "(module='MLD' OR module IS NULL) AND fac_v_notes.parent_key(+) = mld_melding.mld_melding_key";
}
},
"orders": {
model: model_orders,
joinfield: "mld_melding_key",
single_only: false,
joinfunction: function (params)
{
return " mld_melding.mld_melding_key = mld_opdr.mld_melding_key(+) ";
}
}
},
REST_GET: function _GET(params)
{
var scope = getQParamSafe("scope", "fe");
var autfunction = { fe : "WEB_MLDUSE", fo : "WEB_MLDFOF", bo : "WEB_MLDBOF", mi : "WEB_MLDBAC" } [scope];
params.authparams = user.checkAutorisation(autfunction, null, null, true); /* pessimistic */
// Hier kom je niet meer terecht als bovenstaande autorisatiecheck niet tot succes leidt.
var alg3d = false;
var prs3d = false;
var query = api2.sqlfields(params, model_issues );
if (scope == "fe")
{
query.wheres.push("mld_melding.prs_perslid_key=" + user_key);
}
if (!params.filter.id)
{
/* You can't go any further back in time than the GUI could (ongeveer)*/
if (S("mld_max_history") > 0)
{
query.wheres.push("mld_melding_datum > SYSDATE - "+ S("mld_max_history"));
}
if (!params.filter.status)
{
/* Limitation: if no status filter, then default to the active statusses (all except 1,6,5) */
// Zou zo kunnen, params.filter.status = [0,2,3,4,7];, maar eigenlijk is dit logischer
query.wheres.push("mld_melding_status IN (0,2,3,4,7)");
}
}
/* we need the prefix for the name */
query.tables.push("mld_stdmelding");
query.wheres.push("mld_melding.mld_stdmelding_key = mld_stdmelding.mld_stdmelding_key");
query.tables.push("ins_tab_discipline");
query.wheres.push("mld_stdmelding.mld_ins_discipline_key = ins_tab_discipline.ins_discipline_key");
query.tables.push("ins_srtdiscipline");
query.wheres.push("ins_tab_discipline.ins_srtdiscipline_key = ins_srtdiscipline.ins_srtdiscipline_key");
query.tables.push("alg_v_allonroerendgoed");
query.wheres.push("mld_melding.mld_alg_onroerendgoed_keys = alg_v_allonroerendgoed.alg_onroerendgoed_keys(+)");
if (params.authparams.ALGreadlevel > -1)
{
/* required for 3D ALG scopeing */
alg3d = true;
__Log("ALGreadlevel="+params.authparams.ALGreadlevel);
query.tables.push("alg_locatie"); /* opletten: outerjoin denk ik? */
query.wheres.push("mld_melding.mld_alg_onroerendgoed_keys = alg_locatie.alg_locatie_key(+)");
query.tables.push("alg_district");
query.wheres.push("alg_locatie.alg_district_key = alg_district.alg_district_key(+)");
}
if (params.authparams.PRSreadlevel > -1)
{
/* required for 3D PRS scopeing */
prs3d = true;
__Log("PRSreadlevel="+params.authparams.PRSreadlevel);
query.tables.push("prs_v_afdeling");
query.wheres.push("mld_melding.prs_perslid_key = prs_v_afdeling.prs_afdeling_key");
}
var wheres = api2.sqlfilter(params, model_issues);
query.wheres = query.wheres.concat(wheres);
var sql = "SELECT " + query.selects.join(", ")
+ " FROM " + query.tables.join(", ")
+ " WHERE " + query.wheres.join(" AND " );
// Over het resultaat moet nog de 3D rasp, altijd
sql = discx3d (sql,
"ins_tab_discipline.ins_discipline_key",
(alg3d ? "alg_district.alg_regio_key" : null),
(alg3d ? "alg_district.alg_district_key" : null),
(alg3d ? "mld_melding.mld_alg_locatie_key" : null),
(alg3d ? "alg_v_allonroerendgoed.alg_gebouw_key" : null),
(alg3d ? "alg_v_allonroerendgoed.alg_verdieping_key" : null),
(alg3d ? "alg_v_allonroerendgoed.alg_ruimte_key" : null),
(prs3d ? "prs_bedrijf_key" : null),
(prs3d ? "prs_afdeling_key" : null),
autfunction,
"", /* no additional discipline restrictions */
(alg3d && prs3d ? 2 : prs3d ? 1 : 0)
);
sql += " ORDER BY mld_melding_key";
var json = api2.sql2json (params, sql, model_issues );
return json;
},
_pre_analyze_fields: function (params, jsondata) /* analyseer inkomende jsondata voor POST */
{
params.data = {};
var issuetype = api2.get_jdata_refkey(jsondata.issue.issuetype);
var account = api2.get_jdata_refkey(jsondata.issue.account);
var mld_key = jsondata.issue.id;
if (params.isNew)
{ // analyseer inkomende jsondata voor POST
var msgError = "";
var hasError = true;
//
// Voor een nieuwe melding moet er een geldige stdmelding zijn.
msgError = "Missing issuetype";
if (jsondata.issue.issuetype)
{
msgError = "Invalid issuetype";
var sql_stdm = "SELECT sm.mld_stdmelding_omschrijving"
+ " , sm.mld_ins_discipline_key"
+ " , md.ins_srtdiscipline_key"
+ " , COALESCE(sm.mld_stdmelding_directklaar, dp.mld_disc_params_directklaar, 0) mld_directklaar"
+ " FROM mld_stdmelding sm"
+ " , mld_discipline md"
+ " , mld_disc_params dp"
+ " WHERE sm.mld_ins_discipline_key = md.ins_discipline_key"
+ " AND sm.mld_ins_discipline_key = dp.mld_ins_discipline_key"
+ " AND sm.mld_stdmelding_key = " + issuetype;
var oRs_stdm = Oracle.Execute(sql_stdm);
if (!oRs_stdm.eof)
{
params.data.mld_ins_discipline_key = oRs_stdm("mld_ins_discipline_key").Value;
params.data.ins_srtdiscipline_key = oRs_stdm("ins_srtdiscipline_key").Value;
params.data.mld_directklaar = oRs_stdm("mld_directklaar").Value;
hasError = false;
}
oRs_stdm.Close();
}
if (hasError) api2.error(500, msgError);
//
// Bepaal de kostenplaats, indien verplicht.
var stdm_info = mld.mld_stdmeldinginfo(issuetype);
var kpkey = (account ? account : -1);
if (stdm_info.kpnverplicht && kpkey < 0)
{ // Kostenplaats is verplicht, maar is niet meegegeven. Bepaal default kostenplaats.
kpkey = (user.afdeling().prs_kostenplaats_key() || -1); // User kostenplaats key
}
if (stdm_info.kpnverplicht && kpkey < 0)
{ // Kon ook geen default kostenplaats vinden.
msgError = "Account could not be validated";
api2.error(500, msgError);
}
jsondata.issue.account = kpkey;
params.data.is_kto_antwoord = stdm_info.is_kto_antwoord;
//
//
if (!jsondata.issue.contact) jsondata.issue.contact = user_key; // Als er geen aanvrager opgegeven is, dan de huidige gebruiker invullen.
// Als de setting niet is gezet is "Melding voor" gelijk aan contactpersoon.
if (S("mld_allow_for_others") == 0)
{
jsondata.issue.requestor = jsondata.issue.contact;
}
}
else
{
// Bestaande melding: Haal de gegevens op.
var sql = "SELECT mld_stdmelding_key"
+ " FROM mld_melding"
+ " WHERE mld_melding_key = " + mld_key;
var oRs = Oracle.Execute(sql);
jsondata.issue.issuetype = oRs("mld_stdmelding_key").Value;
oRs.Close();
}
//
//
var stdm_info = mld.mld_stdmeldinginfo(issuetype);
// Startdatum: indien niet meegegeven, neem dan sysdate
var startdate = (jsondata.issue.issuedate ? jsondata.issue.issuedate : new Date);
var startwerkdag = parseFloat(S("fac_t_startofworkday"));
var startwerkdag_uur = Math.floor(startwerkdag);
var startwerkdag_min = (startwerkdag - Math.floor(startwerkdag)) * 60;
var startdatebegin = new Date(startdate.getFullYear(), startdate.getMonth(), startdate.getDate(), startwerkdag_uur, startwerkdag_min);
var sysdate = new Date();
//
if (stdm_info.startdatum)
{ // Situatie 1: Einddatum = TRUNC(startdatum) + 8:00 uur + SLA
// LET OP!!!: Als setting "mld_disc_params_startdatum" is gezet dan wordt eigenlijk verondersteld dat de SLA in dagen is en niet in uren.
// Echter als de startdatum de registratiedatum (bij nieuwe melding dus sysdate) is moet wel voor de begintijd de registratietijd (registratiedatum) genomen worden tijdens het opslaan.
// Anders geldt de acceptatietijd (in uren) onterecht al vanaf het begin van de dag.
if (params.isNew)
{ // Nieuwe melding.
// Startdatum is vandaag: starttijd is huidige tijd.
// Startdatum is niet vandaag: starttijd is begin werkdag.
var startdate_is_today = (startdate.midnight().getTime() == sysdate.midnight().getTime());
startdate = (startdate_is_today? sysdate : startdatebegin);
}
else
{ // Bestaande melding
sql = "SELECT mld_melding_datum"
+ " FROM mld_melding"
+ " WHERE mld_melding_key = " + mld_key;
oRs = Oracle.Execute(sql);
var oldstartdate = new Date(oRs("mld_melding_datum").Value);
// Alleen als datum veranderd is moet de starttijd worden aangepast.
if (startdate.midnight().getTime() != oldstartdate.midnight().getTime())
{ // Startdatum is aangepast.
// Als de startdatum is aangepast in registratiedatum, dan wel weer de registratietijd (registratiedatum) pakken.
// In alle andere gevallen begin van de werkdag pakken.
sql = "SELECT fac.gettrackingdate('MLDNEW', " + mld_key + ") registratiedatum FROM DUAL"
oRs_1 = Oracle.Execute(sql);
var registratiedatum = new Date(oRs_1("registratiedatum").Value);
oRs_1.Close();
var startdatum_is_registratiedatum = (startdate.midnight().getTime() == registratiedatum.midnight().getTime());
startdate = (startdatum_is_registratiedatum? registratiedatum : startdatebegin);
}
else
{ // else startdatum niet aanpassen.
startdate = oldstartdate;
}
oRs.Close();
}
}
else
{ // Situatie 2: Einddatum = COALESCE(huidige waarde, sysdate) + SLA
if (params.isNew)
{
startdate = new Date();
}
else
{
startdate = jsondata.issue.issuedate;
}
}
jsondata.issue.issuedate = startdate;
// De einddatum is de meegegeven einddatum, maar als die niet wordt meegegeven regelt de trigger dat wel, dus DAN MOET IK HEM NIET MEEGEVEN
//
// Onroerendgoed_keys wordt de verfijnste van de opgegeven plaats
var locatiekey = (jsondata.issue.location ? jsondata.issue.location : -1);
var gebouwkey = (jsondata.issue.building ? jsondata.issue.building : -1);
var verdiepingkey = (jsondata.issue.floor ? jsondata.issue.floor : -1);
var ruimtekey = (jsondata.issue.room ? jsondata.issue.room : -1);
var alg_onroerendgoed_keys = -1;
if (!S("mld_plaats_is_locatie_only"))
{ // die specifiekere plaats moet dan leegblijven
if (ruimtekey != -1)
alg_onroerendgoed_keys = ruimtekey;
else if (verdiepingkey != -1)
alg_onroerendgoed_keys = verdiepingkey;
else if (gebouwkey != -1)
alg_onroerendgoed_keys = gebouwkey;
}
params.data.alg_onroerendgoed_keys = alg_onroerendgoed_keys;
if (!params.isNew)
{ // Verwijder voor PUT wat niet gewijzigd mag worden.
delete jsondata.issue.name;
delete jsondata.issue.contact;
delete jsondata.issue.requestor;
delete jsondata.issue.issuetype;
delete jsondata.issue.location;
}
},
_analyze_fields: function (fields, params, jsondata) /* analyseer inkomende data, common voor PUT en POST */
{
},
_validate_fields: function (fields, params, jsondata) /* valideer fields, alle constraints die niet door de database worden afgevangen */
{
// als einddatum ingevuld is moet deze groter/gelijk zijn aan de begindatum
},
_validate_close: function (params, jsondata, the_key) /* uit: mld_close_save.asp */
{
var mld_key = the_key;
var this_mld = mld.func_enabled_melding(mld_key);
user.auth_required_or_abort(this_mld.canClose); // Als je mag accepteren mag je ook rejecten
params.data = {};
params.data.tobeclosed = false;
params.data.canCloseOpdrOfMld = [];
var canCloseOpdr = [];
var reqStatusEmpty = [];
var noOpdrCloseAtAll = false;
var futureOpdr = false;
// Zijn er nog kenmerken die nu wel verplicht zijn?
var kvsAfwezig = mld.hasRequiredStatusEmpty(mld_key, 5);
if (kvsAfwezig.length)
{
var mldnr = mld.mld_prefix(mld_key) + mld_key;
reqStatusEmpty.push(L("lcl_mld_req_status_empty").format(kvsAfwezig.join(", "), mldnr) );
}
// Zijn er nog lopende opdrachten?
var sql = "SELECT o.mld_opdr_key"
+ " FROM mld_opdr o"
+ " WHERE o.mld_melding_key = " + mld_key
+ " AND o.mld_statusopdr_key NOT IN (1, 6, 7, 9)";
var oRsOM = Oracle.Execute(sql);
while (!oRsOM.eof)
{ // Voor elke opdracht van een melding controleren of deze afgemeld mag worden
var mld_opdr_key = oRsOM("mld_opdr_key").Value;
sql = "SELECT mld_opdr_einddatum"
+ " FROM mld_opdr o"
+ " WHERE o.mld_opdr_key = " + mld_opdr_key;
var oRs = Oracle.Execute(sql);
// Als Setting S("mld_ord_afmeld_future") niet is gezet (0): Opdrachten waarvan de einddatum in de toekomst ligt mogen niet worden afgemeld.
var this_opdr = mld.func_enabled_opdracht(mld_opdr_key);
if (!this_opdr.canClose || (S("mld_ord_afmeld_future") != 1 && (oRs("mld_opdr_einddatum").value > new Date())))
{ // Geen autorisatie om alle opdrachten van een melding af te melden of opdrachten in de toekomst
// met setting S("mld_ord_afmeld_future") niet gezet-->dan geen enkele van die melding
noOpdrCloseAtAll = true;
if (S("mld_ord_afmeld_future") != 1 && (oRs("mld_opdr_einddatum").value > new Date()))
futureOpdr = true; // Indien opdrachten in de toekomst en setting S("mld_ord_afmeld_future") niet gezet (0) dan mag je de melding niet afmelden
}
oRs.Close();
params.data.canCloseOpdrOfMld.push(mld_opdr_key);
oRsOM.MoveNext();
}
oRsOM.Close();
if (!futureOpdr && !noOpdrCloseAtAll)
{ // Indien opdrachten in de toekomst en setting S("mld_ord_afmeld_future") niet gezet (0) dan mag je de melding niet afmelden
// EN geen opdrachten of alle opdrachten mogen gesloten worden, dan kan de melding afgemeld worden
params.data.tobeclosed = true;
}
else
{
msgError = "Issue can not be closed";
api2.error(500, msgError);
}
},
REST_PUT: function (params, jsondata, the_key) /* update call */
{
if (!jsondata.issue.id) jsondata.issue.id = the_key;
var scope = getQParamSafe("scope", "fe");
var autfunction = { fe : "WEB_MLDUSE", fo : "WEB_MLDFOF", bo : "WEB_MLDBOF", mi : "WEB_MLDBAC" } [scope];
params.authparams = user.checkAutorisation(autfunction, null, null, true); /* pessimistic */
// Hier kom je niet meer terecht als bovenstaande autorisatiecheck niet tot succes leidt.
var mld_key = the_key;
var this_mld = mld.func_enabled_melding(mld_key);
user.auth_required_or_abort(this_mld.canChange); // Geen wijzigingen toestaan bij onvoldoende rechten.
model_issues._pre_analyze_fields(params, jsondata);
var fields = api2.update_fields(params, model_issues, jsondata); // Build updater
model_issues._analyze_fields(fields, params, jsondata);
model_issues._validate_fields(fields, params, jsondata);
var wheres = [" mld_melding_key = " + mld_key];
var mldUpd = buildTrackingUpdate("mld_melding", wheres.join(" AND " ), fields, { noValidateToken: true });
// Alle gegevens bijwerken.
var sql = "BEGIN "
+ mldUpd.sql + ";"
+ " END;";
var err = Oracle.Execute(sql, true);
if (err.friendlyMsg)
abort_with_warning(err.friendlyMsg);
params.data.module = "MLD"; // model_notes moet weten bij wekle module de notes horen.
var mldtrack = api2.process_includes(params, model_issues, jsondata, mld_key);
// update nog tracken
if (mld_key > 0)
{
shared.trackaction("MLDUPD",
mld_key,
L("lcl_mld_is_mldupdtrack").format(mld_key) + (mldUpd.trackarray.length > 0? "\n" : "") + mldUpd.trackarray.join("\n"));
};
return { key: mld_key };
},
REST_POST: function (params, jsondata) /* new call */
{
var scope = getQParamSafe("scope", "fe");
var autfunction = { fe : "WEB_MLDUSE", fo : "WEB_MLDFOF", bo : "WEB_MLDBOF", mi : "WEB_MLDBAC" } [scope];
params.authparams = user.checkAutorisation(autfunction, null, null, true); /* pessimistic */
// Hier kom je niet meer terecht als bovenstaande autorisatiecheck niet tot succes leidt.
params.isNew = true;
model_issues._pre_analyze_fields(params, jsondata);
var this_mld = mld.func_enabled_mld(params.data.mld_ins_discipline_key, "D");
user.auth_required_or_abort(this_mld.canFEwrite || this_mld.canFOwrite);
//
var fields = api2.update_fields(params, model_issues, jsondata); // Build updater
model_issues._analyze_fields(fields, params, jsondata);
model_issues._validate_fields(fields, params, jsondata);
fields.push({ dbs: "mld_alg_onroerendgoed_keys", typ: "key", val: (params.data.alg_onroerendgoed_keys==-1 ? null : params.data.alg_onroerendgoed_keys) });
fields.push({ dbs: "mld_meldbron_key", typ: "key", val: S("mld_meldbron_key") });
fields.push({ dbs: "mld_melding_module", typ: "varchar", val: "MLD" });
fields.push({ dbs: "mld_melding_key", typ: "key", seq: "mld_s_mld_melding_key" });
var mldIns = buildInsert("mld_melding", fields, { noValidateToken: true });
var new_key = mldIns.sequences["mld_melding_key"];
var sql = "BEGIN "
+ mldIns.sql + ";"
+ "END;";
Oracle.Execute(mldIns.sql);
mld.setmeldingstatus(new_key, (params.data.mld_directklaar? 0 : 2)); // Zorgt ook voor tracking & daarmee notificatie
if (params.data.is_kto_antwoord) // die direct afmelden
mld.setmeldingstatus(new_key, 5);
params.data.module = "MLD"; // model_notes moet weten bij wekle module de notes horen.
return { key: new_key };
},
REST_DELETE: function (params, jsondata, the_key) /* delete call */
{
// Een melding wordt niet verwijderd maar wordt afgesloten.
var scope = getQParamSafe("scope", "fe");
var autfunction = { fe : "WEB_MLDUSE", fo : "WEB_MLDFOF", bo : "WEB_MLDBOF", mi : "WEB_MLDBAC" } [scope];
params.authparams = user.checkAutorisation(autfunction, null, null, true); /* pessimistic */
// Hier kom je niet meer terecht als bovenstaande autorisatiecheck niet tot succes leidt.
model_issues._validate_close(params, jsondata, the_key);
// De melding en eventuele opdrachten mogen afgemeld worden.
// Ik had nog graag een L("lcl_mld_final_remark") toe willen voegen aan de melding, maar er is geen jsondata bij DELETE.
// Eventuele opdrachten afmelden.
for (opdr_i in params.data.canCloseOpdrOfMld)
{
mld.setopdrachtstatus(canCloseOpdrOfMld[opdr_i], 6); // Technisch voltooid (TV) (Afgemeld)
}
// De melding zelf afmelden.
mld.setmeldingstatus(the_key, 5);
}
}
%>