2108 lines
110 KiB
C++
2108 lines
110 KiB
C++
<%
|
|
/*
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: res.inc
|
|
Description: res ondersteunende functies
|
|
Context:
|
|
Note:
|
|
*/
|
|
if (!this.JSON_Result && !Request.QueryString("api2").Count && !Request.QueryString("api").Count)
|
|
FCLTHeader.Requires({css: ["../res/res.css"] });
|
|
|
|
res = {
|
|
// sterke relatie met z:\Project\Sm44\VSSSRC\SQL\RES\RES_PAC.SRC
|
|
// merk op dat niet alle leveld gebruikt/ ondersteund worden
|
|
dirtlevel:
|
|
{
|
|
ruimte:
|
|
{
|
|
clean:0,
|
|
//licht
|
|
//middel
|
|
nocatering : 0x010, // 0b000100000000, // Niets zinvols (onder een CV)
|
|
//zwaar
|
|
noroom : 0x100, // 0b000100000000, // Geen alg_ruimte/opstel_key ingevuld
|
|
notavailable : 0x200 // 0b001000000000 // Niet beschikbaar op gekozen tijdstip
|
|
},
|
|
artikel:
|
|
{
|
|
clean:0,
|
|
//licht
|
|
//middel
|
|
timechanged : 0x000000010000, // Parent gewijzigd en wij mee gewijzigd
|
|
timenotchanged: 0x000000100000, // Parent gewijzigd maar wij niet mee gewijzigd
|
|
//zwaar
|
|
notallowed : 0x100 // Niet toegestaan in deze ruimte
|
|
},
|
|
deel:
|
|
{
|
|
clean:0,
|
|
//licht
|
|
//middel
|
|
timechanged : 0x000000010000, // Parent gewijzigd en wij mee gewijzigd
|
|
timenotchanged: 0x000000100000, // Parent gewijzigd maar wij niet mee gewijzigd
|
|
//zwaar
|
|
notallowed : 0x100, // Niet toegestaan in deze ruimte
|
|
notavailable : 0x200 // Niet beschikbaar op tijdstip
|
|
}
|
|
},
|
|
|
|
// Verwijder de afspraak die eventueel gekoppeld was aan rsv_ruimte_key
|
|
// (JGL: Eigenlijk moet dit gewoon cascading door een trigger gebeuren)
|
|
DeleteResAfspraak: function DeleteResAfspraak (rsv_ruimte_key)
|
|
{
|
|
var sql;
|
|
// delete parkeerplaatsen gebeurt wel met behulp van CASCADE (bez_bezoekers)
|
|
|
|
// delete bezoekers
|
|
var sql = "DELETE FROM bez_bezoekers"
|
|
+ " WHERE bez_afspraak_key in "
|
|
+ " (SELECT ba.bez_afspraak_key"
|
|
+ " FROM bez_afspraak ba"
|
|
+ " WHERE ba.res_rsv_ruimte_key = " + rsv_ruimte_key + ")";
|
|
Oracle.Execute(sql);
|
|
|
|
// delete afspraak
|
|
sql = "DELETE FROM bez_afspraak"
|
|
+ " WHERE res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
Oracle.Execute(sql);
|
|
},
|
|
|
|
trackreserveringupdate:
|
|
// Let op: dit moet wellicht niet altijd (aangeroepen na save)
|
|
function (rsv_ruimte_key, ptxt)
|
|
{
|
|
shared.trackaction("RESUPD", rsv_ruimte_key, ptxt);
|
|
},
|
|
|
|
trackobject:
|
|
function (deel_key, actie)
|
|
{
|
|
sql = "SELECT " + lcl.xsqla('rd.res_deel_omschrijving', 'rd.res_deel_key')
|
|
+ " FROM res_deel rd"
|
|
+ " WHERE rd.res_deel_key = " + deel_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var obj_oms = oRs("res_deel_omschrijving").Value;
|
|
oRs.Close();
|
|
var track = "";
|
|
switch (actie)
|
|
{
|
|
case "delete": track = L("lcl_res_insdelete") + ": " + obj_oms;
|
|
break;
|
|
case "insert": track = L("lcl_res_insinsert") + ": " + obj_oms;
|
|
break;
|
|
}
|
|
return track;
|
|
},
|
|
|
|
trackartikel:
|
|
function (artikel_key, actie, params)
|
|
{
|
|
sql = "SELECT ra.res_artikel_omschrijving"
|
|
+ " FROM res_artikel ra"
|
|
+ " WHERE ra.res_artikel_key = " + artikel_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var art_oms = oRs("res_artikel_omschrijving").Value;
|
|
oRs.Close();
|
|
var track = "";
|
|
switch (actie)
|
|
{
|
|
case "delete": track = L("lcl_res_artdelete") + ": " + art_oms;
|
|
break;
|
|
case "insert": track = L("lcl_res_artinsert") + ": " + art_oms;
|
|
break;
|
|
case "update": track = L("lcl_res_artupdate") + ": " + art_oms
|
|
+ (params.old_number != params.new_number
|
|
? "\n" + buildTrackText("number", params.old_number, params.new_number, { nodiff: true })
|
|
: "")
|
|
+ (params.old_price != params.new_price
|
|
? "\n" + buildTrackText("float", params.old_price, params.new_price, { nodiff: true })
|
|
: "")
|
|
+ (params.old_date.getTime() != params.new_date.getTime()
|
|
? "\n" + buildTrackText("datetime", params.old_date, params.new_date, { nodiff: true })
|
|
: "");
|
|
break;
|
|
}
|
|
return track;
|
|
},
|
|
|
|
res_set_dialect:
|
|
function (rsv_ruimte_key)
|
|
{
|
|
var sql = "SELECT ra.res_srtactiviteit_key"
|
|
+ " FROM res_rsv_ruimte rrr, "
|
|
+ " res_activiteit ra"
|
|
+ " WHERE res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " AND rrr.res_activiteit_key = ra.res_activiteit_key";
|
|
var oRs = Oracle.Execute(sql);
|
|
lcl.set_dialect(oRs("res_srtactiviteit_key").Value, "RES_SRTACTIVITEIT_KEY");
|
|
oRs.Close();
|
|
},
|
|
|
|
res_ruimte_info: function _res_ruimte(res_ruimte_key)
|
|
{
|
|
var result = { res_ruimte_key: res_ruimte_key,
|
|
RoomConfigs: [],
|
|
default_opstel_key : -1 };
|
|
|
|
var sql = "SELECT " + lcl.xsqla('rr.res_ruimte_nr', 'rr.res_ruimte_key')
|
|
+ " , " + lcl.xsqla('rr.res_ruimte_omschrijving', 'rr.res_ruimte_key')
|
|
+ " , res_ruimte_info_url"
|
|
+ " , res_ruimte_image"
|
|
+ " , ac.res_activiteit_aantalverplicht"
|
|
+ " , ac.res_activiteit_notfrontend"
|
|
+ " , res_disc_params_kosten"
|
|
+ " , ins_discipline_kpnverplicht"
|
|
+ " , COALESCE(res_ruimte_begintijd, " + S("res_t1") + ") begintijd"
|
|
+ " , COALESCE(res_ruimte_eindtijd, " + S("res_t2") + ") eindtijd"
|
|
+ " , res_ruimte_begintijdblok"
|
|
+ " , res_ruimte_eindtijdblok"
|
|
+ " , rr.res_discipline_key"
|
|
+ " , rr.res_status_fo_key"
|
|
+ " , res_ruimte_vervaldatum"
|
|
+ " , res_ruimte_extern_id"
|
|
+ " , res_ruimte_min_duur"
|
|
+ " FROM res_ruimte rr"
|
|
+ " , res_disc_params rdp"
|
|
+ " , res_discipline rd"
|
|
+ " , res_activiteitdiscipline ad"
|
|
+ " , res_activiteit ac"
|
|
+ " WHERE rr.res_ruimte_key = " + res_ruimte_key
|
|
+ " AND rr.res_discipline_key = rd.ins_discipline_key "
|
|
+ " AND rr.res_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND rd.ins_discipline_key = ad.res_discipline_key"
|
|
+ " AND ad.res_activiteit_key = ac.res_activiteit_key";
|
|
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.eof)
|
|
{
|
|
result.ruimte_nr = oRs("res_ruimte_nr").Value;
|
|
result.ruimte_omschrijving = oRs("res_ruimte_omschrijving").Value;
|
|
result.ruimte_info_url = oRs("res_ruimte_info_url").Value;
|
|
result.aantalreq = oRs("res_activiteit_aantalverplicht").Value;
|
|
result.notfrontend = oRs("res_activiteit_notfrontend").Value;
|
|
if (oRs("res_ruimte_image").Value)
|
|
result.imagePath = S("res_image_path") + oRs("res_ruimte_image").Value;
|
|
result.kosten = oRs("res_disc_params_kosten").Value;
|
|
result.kpnverplicht = oRs("ins_discipline_kpnverplicht").Value;
|
|
result.discipline_key = oRs("res_discipline_key").Value;
|
|
result.begintijd = oRs("begintijd").Value;
|
|
result.eindtijd = oRs("eindtijd").Value;
|
|
result.begintijdblok = oRs("res_ruimte_begintijdblok").Value;
|
|
result.eindtijdblok = oRs("res_ruimte_eindtijdblok").Value;
|
|
if (result.begintijd < S("res_t1")) result.begintijd = S("res_t1");
|
|
if (result.eindtijd > S("res_t2")) result.eindtijd = S("res_t2");
|
|
if (result.begintijd > result.eindtijd) result.begintijd = result.eindtijd;
|
|
result.status_fo_key = oRs("res_status_fo_key").Value || -1;
|
|
if (result.status_fo_key > 0)
|
|
result.status_fo_string = res.getfostatustext(result.status_fo_key);
|
|
result.vervaldatum = oRs("res_ruimte_vervaldatum").Value != null? new Date(oRs("res_ruimte_vervaldatum").Value) : null;
|
|
result.extern_id = oRs("res_ruimte_extern_id").Value;
|
|
result.min_duur = oRs("res_ruimte_min_duur").Value;
|
|
}
|
|
sql = "SELECT res_ruimte_opstel_key"
|
|
+ " , res_ruimte_opstel_bezoekers"
|
|
+ " , res_ruimte_opstel_default"
|
|
+ " , ro.res_opstelling_key"
|
|
+ " , res_ruimte_opstel_image"
|
|
+ " , " + lcl.xsqla('res_opstelling_omschrijving','ro.res_opstelling_key')
|
|
+ " , rro.res_ruimte_opstel_verwijder"
|
|
+ " FROM res_ruimte rr"
|
|
+ " , res_ruimte_opstelling rro"
|
|
+ " , res_opstelling ro"
|
|
+ " WHERE rr.res_ruimte_key = " + res_ruimte_key
|
|
+ " AND rr.res_ruimte_key = rro.res_ruimte_key"
|
|
+ " AND rro.res_opstelling_key = ro.res_opstelling_key"
|
|
+ " ORDER BY res_opstelling_volgnr";
|
|
oRs = Oracle.Execute(sql);
|
|
|
|
while (!oRs.eof)
|
|
{
|
|
var rc = { ruimte_opstel_key: oRs("res_ruimte_opstel_key").Value,
|
|
opstelling_omschrijving: oRs("res_opstelling_omschrijving").Value,
|
|
opstelling_key: oRs("res_opstelling_key").Value,
|
|
bezoekers: oRs("res_ruimte_opstel_bezoekers").Value,
|
|
verwijderd: oRs("res_ruimte_opstel_verwijder").Value != null }
|
|
if (oRs("res_ruimte_opstel_image").Value)
|
|
rc.imagePath = S("res_image_path") + oRs("res_ruimte_opstel_image").Value;
|
|
result.RoomConfigs.push(rc);
|
|
if (oRs("res_ruimte_opstel_default").Value)
|
|
result.default_opstel_key = oRs("res_ruimte_opstel_key").Value;
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.close();
|
|
|
|
return result;
|
|
},
|
|
|
|
res_rsv_ruimte_info: function res_rsv_ruimte_info(rsv_ruimte_key)
|
|
{
|
|
var result = {rsv_ruimte_key: rsv_ruimte_key };
|
|
|
|
var sql = "SELECT rrr.res_ruimte_opstel_key"
|
|
+ ", rrr.prs_kostenplaats_key"
|
|
+ ", rrr.res_rsv_ruimte_bezoekers"
|
|
+ ", rrr.res_status_fo_key"
|
|
+ ", rrr.res_activiteit_key"
|
|
+ ", rrr.res_reservering_key"
|
|
+ ", rrr.res_rsv_ruimte_volgnr"
|
|
+ ", rrr.res_rsv_ruimte_van"
|
|
+ ", rrr.res_rsv_ruimte_tot"
|
|
+ ", rrr.res_rsv_ruimte_omschrijving"
|
|
+ ", rrr.res_rsv_ruimte_opmerking"
|
|
+ ", rrr.res_rsv_ruimte_contact_key"
|
|
+ ", rrr.res_rsv_ruimte_host_key"
|
|
+ ", rrr.res_rsv_ruimte_telefoon"
|
|
+ ", " + lcl.xsqla("ra.res_activiteit_omschrijving", "ra.res_activiteit_key")
|
|
+ " FROM res_rsv_ruimte rrr,"
|
|
+ " res_activiteit ra"
|
|
+ " WHERE rrr.res_activiteit_key = ra.res_activiteit_key"
|
|
+ " AND rrr.res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
result.opstel_key = oRs("res_ruimte_opstel_key").Value;
|
|
result.account = oRs("prs_kostenplaats_key").Value;
|
|
result.bezoekers = oRs("res_rsv_ruimte_bezoekers").Value;
|
|
result.status_fo = oRs("res_status_fo_key").Value;
|
|
result.act_key = oRs("res_activiteit_key").Value;
|
|
result.reservering_key = oRs("res_reservering_key").Value;
|
|
result.ruimte_volgnr = oRs("res_rsv_ruimte_volgnr").Value;
|
|
result.ruimte_van = oRs("res_rsv_ruimte_van").Value;
|
|
result.ruimte_tot = oRs("res_rsv_ruimte_tot").Value;
|
|
result.omschrijving = oRs("res_rsv_ruimte_omschrijving").Value;
|
|
result.opmerking = oRs("res_rsv_ruimte_opmerking").Value;
|
|
result.contact_key = oRs("res_rsv_ruimte_contact_key").Value;
|
|
result.host_key = oRs("res_rsv_ruimte_host_key").Value;
|
|
result.telefoon = oRs("res_rsv_ruimte_telefoon").Value;
|
|
result.activiteit = oRs("res_activiteit_omschrijving").Value;
|
|
oRs.Close();
|
|
|
|
var sql = "SELECT COALESCE (opstelalg.res_ruimte_nr, ruimte_geg.alg_ruimte_aanduiding) res_ruimte_nr"
|
|
+ " , opstelalg.res_ruimte_key"
|
|
+ " , ruimte_geg.alg_locatie_key"
|
|
+ " , ruimte_geg.alg_ruimte_key"
|
|
+ " , rsa.res_srtactiviteit_metomschr"
|
|
+ " , rsa.res_srtactiviteit_metopmerk"
|
|
+ " , rsa.res_srtactiviteit_metaantal"
|
|
+ " FROM res_rsv_ruimte rrr"
|
|
+ " , alg_v_ruimte_gegevens_all ruimte_geg"
|
|
+ " , res_activiteit ra"
|
|
+ " , res_srtactiviteit rsa"
|
|
+ " , (SELECT res_ruimte_opstel_key"
|
|
+ " , rr.res_ruimte_nr res_ruimte_nr"
|
|
+ " , rr.res_ruimte_key"
|
|
+ " , MIN (alg_ruimte_key) alg_ruimte_key"
|
|
+ " FROM res_ruimte_opstelling rro"
|
|
+ " , res_alg_ruimte rar"
|
|
+ " , res_ruimte rr"
|
|
+ " WHERE rro.res_ruimte_key = rar.res_ruimte_key"
|
|
+ " AND rr.res_ruimte_key = rar.res_ruimte_key"
|
|
+ " AND rar.res_alg_ruimte_verwijder IS NULL"
|
|
+ " GROUP BY res_ruimte_opstel_key"
|
|
+ " , rr.res_ruimte_nr"
|
|
+ " , rr.res_ruimte_key) opstelalg"
|
|
+ " WHERE rrr.res_rsv_ruimte_verwijder IS NULL"
|
|
+ " AND rrr.res_ruimte_opstel_key = opstelalg.res_ruimte_opstel_key(+)"
|
|
+ " AND rrr.res_activiteit_key = ra.res_activiteit_key"
|
|
+ " AND ra.res_srtactiviteit_key = rsa.res_srtactiviteit_key"
|
|
+ " AND ruimte_geg.alg_ruimte_key = COALESCE (rrr.alg_ruimte_key, opstelalg.alg_ruimte_key)"
|
|
+ " AND rrr.res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
result.ruimtenr = oRs("res_ruimte_nr").Value;
|
|
result.ruimtekey = oRs("res_ruimte_key").Value;
|
|
result.loc_key = oRs("alg_locatie_key").Value;
|
|
result.room_key = oRs("alg_ruimte_key").Value;
|
|
result.toonOms = oRs("res_srtactiviteit_metomschr").Value || 0;
|
|
result.toonOpm = oRs("res_srtactiviteit_metopmerk").Value || 0;
|
|
result.toonBez = oRs("res_srtactiviteit_metaantal").Value || 0;
|
|
oRs.Close();
|
|
|
|
return result;
|
|
},
|
|
|
|
res_getnewdates: function _res_getnewdates(params)
|
|
{
|
|
var result = {};
|
|
|
|
var res_new_dates = [];
|
|
var limitDate = null;
|
|
var limit = ((params.urole == "fe" && S("res_fe_reservering_limiet") > 0)? S("res_fe_reservering_limiet") : S("res_reservering_limiet"))
|
|
|
|
var ruimte_vervaldatum = params.ruimte_vervaldatum > 0? new Date(params.ruimte_vervaldatum) : null;
|
|
var daysToExpire = null;
|
|
if (ruimte_vervaldatum != null)
|
|
daysToExpire = (ruimte_vervaldatum.midnight().getTime() - new Date().midnight().getTime())/(24*3600*1000);
|
|
|
|
if (daysToExpire != null && daysToExpire <= 0)
|
|
return {res_new_dates: [], message: L("lcl_res_date_limit_reached") + toDateString(new Date())}; // Geen geldige vervolgdatums mogelijk.
|
|
|
|
if (daysToExpire != null && daysToExpire >= 0 && daysToExpire < limit)
|
|
limit = daysToExpire;
|
|
|
|
if (limit > 0)
|
|
{
|
|
limitDate = new Date();
|
|
limitDate.setDate(limitDate.getDate() + limit);
|
|
}
|
|
|
|
var nextDate = new Date(params.nextDate);
|
|
var overflow = false;
|
|
var message = "";
|
|
for (var i = 0; i < params.np; i++)
|
|
{ // Maandelijks (Eerste dinsdag van de maand). Geen vast interval dus.
|
|
// fac.nextcyclusdate (begindatum, mode, eenheid, periode, bits, 1);
|
|
var ora_date1 = nextDate.beginToSQL();
|
|
var sql = "SELECT fac.nextcyclusdate (" + ora_date1 + ", 0, 3, 1, " + params.bits + ", 1) datum FROM DUAL"; // Eenheid Week(3)
|
|
var oRs = Oracle.Execute(sql);
|
|
nextDate = new Date(oRs("datum").Value); // Datum heeft al tijd van 0:00 uur
|
|
oRs.Close();
|
|
|
|
var date2 = new Date(nextDate); // zelfde tijdstip gebruiken als rrr.rsv_ruimte_van
|
|
date2 = date2.setFloatHours(new Date(params.rsv_ruimte_van).getFloatHours(), safe.jsfloat(S("res_h")));
|
|
|
|
var earliest_expire_change = new Date(params.earliest_expire_change);
|
|
if (params.chk_lastmin && params.urole == "fe" && earliest_expire_change && date2 < earliest_expire_change)
|
|
{
|
|
message = L("lcl_res_repeat_lastmin_n");
|
|
continue;
|
|
}
|
|
if (limitDate && nextDate > limitDate)
|
|
{
|
|
overflow = true;
|
|
break;
|
|
}
|
|
// Checkbox "Alleen werkdagen" is niet aanwezig voor "Maandelijks". Hiermee dus geen rekening houden.
|
|
res_new_dates.push(nextDate.getTime());
|
|
};
|
|
|
|
var result = {res_new_dates: res_new_dates, message: message};
|
|
if (overflow)
|
|
result.message += (message != ""? "<br>" : "") + L("lcl_res_date_limit_reached") + toDateString(limitDate);
|
|
|
|
return result;
|
|
},
|
|
|
|
res_getnrperiods: function _res_getnrperiods(params)
|
|
{
|
|
var nextDate = new Date(params.nextDate);
|
|
var lastDate = new Date(params.lastDate);
|
|
// De dag zelf telt ook nog mee als stap. Daarom bij gebruik van de functie fac.nextcyclusdatesteps() er nog 1 dag bij optellen.
|
|
lastDate.setDate(lastDate.getDate() + 1);
|
|
var message = "";
|
|
var res_steps = 0;
|
|
if (nextDate < lastDate)
|
|
{
|
|
var ora_date1 = nextDate.beginToSQL();
|
|
var ora_date2 = lastDate.beginToSQL();
|
|
var sql = "SELECT fac.nextcyclusdatesteps (" + ora_date1 + ", 0, 3, 1, " + params.bits + ", 0, " + ora_date2 + ") steps FROM DUAL";
|
|
var oRs = Oracle.Execute(sql);
|
|
res_steps = oRs("steps").Value;
|
|
oRs.Close();
|
|
}
|
|
var result = {res_steps: res_steps, message: message};
|
|
|
|
return result;
|
|
},
|
|
|
|
res_voorzieningen_info: function _res_voorzieningen_info(rsv_ruimte_key)
|
|
{
|
|
var result = {};
|
|
|
|
// TODO: In de toekomst algemene voorzieningen gegevens ophalen indien ze nodig zijn.
|
|
// Nu hebben we alleen de verplichtheid van de kostenplaats nog nodig.
|
|
if (!result.kpnverplicht)
|
|
{ // Is de kostenplaats verplicht via de voorzieningen en/of verbruiksartikelen.
|
|
var sql = "SELECT MAX(kpnverplicht) kpnverplicht"
|
|
+ " FROM (SELECT MAX(rd.ins_discipline_kpnverplicht) kpnverplicht"
|
|
+ " FROM res_rsv_artikel ra"
|
|
+ " , res_rsv_ruimte rr"
|
|
+ " , res_artikel a"
|
|
+ " , res_discipline rd"
|
|
+ " WHERE ra.res_rsv_ruimte_key = rr.res_rsv_ruimte_key"
|
|
+ " AND ra.res_artikel_key = a.res_artikel_key"
|
|
+ " AND a.res_discipline_key = rd.ins_discipline_key"
|
|
+ " AND ra.res_rsv_artikel_verwijder IS NULL"
|
|
+ " AND rr.res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " UNION"
|
|
+ " SELECT MAX (dis.ins_discipline_kpnverplicht) kpnverplicht"
|
|
+ " FROM res_rsv_deel rd"
|
|
+ " , res_rsv_ruimte rr"
|
|
+ " , res_deel d"
|
|
+ " , res_discipline dis"
|
|
+ " WHERE rd.res_rsv_ruimte_key = rr.res_rsv_ruimte_key"
|
|
+ " AND rd.res_deel_key = d.res_deel_key"
|
|
+ " AND d.res_discipline_key = dis.ins_discipline_key"
|
|
+ " AND rd.res_rsv_deel_verwijder IS NULL"
|
|
+ " AND rr.res_rsv_ruimte_key = " + rsv_ruimte_key + ")";
|
|
oRs = Oracle.Execute(sql);
|
|
if (!oRs.eof)
|
|
result.kpnverplicht = oRs("kpnverplicht").Value;
|
|
oRs.Close();
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
// Als een datum voor (discipline_expire(disc_key) ligt dan is hij 'te vroeg'
|
|
discipline_expire: function _discipline_expire(discipline_key, mode)
|
|
{
|
|
// Mode 0 = Use expire dagen (res_disc_params_expire_dagen)
|
|
// 1 = Use cancel dagen (res_disc_params_cancel_dagen)
|
|
// 2 = 24/7 organisatie
|
|
// res_disc_params_expire_tijd wordt duaal gebruikt. Rol A: kloktijd en rol B: na wanneer moet levertijd zijn
|
|
// als res_disc_params_expire_tijd (A) nog niet verstreken:
|
|
// dagen = 0 ==> levertijd voorziening moet na res_disc_params_expire_tijd (B) liggen
|
|
// dagen > 0 ==> levertijd voorziening moet morgenvroeg/overmorgenvroeg etc. (wel altijd na S("res_cat_t1")) liggen
|
|
// anders als res_disc_params_expire_tijd (A) wel verstreken:
|
|
// dagen = 0 ==> levertijd voorziening moet morgenvroeg na S("res_cat_t1") liggen
|
|
// dagen > 0 ==> levertijd voorziening moet overmorgen etc. na S("res_cat_t1") liggen
|
|
// (Als het model nog verder uitgewerkt zou worden zou je voor (B) een apart tijdstip hebben,
|
|
// bijvoorbeeld 12:00h voor lunchpakketten of: 2 uur, altijd minimaal twee uren van tevoren)
|
|
// Effectief is 00:15h en 0 dag gelijk aan 23:45 en 1 dag
|
|
|
|
// dagen expire_tijd hetisnu resultaat (veronderstel cat_t1 8:00)
|
|
// --------------------------------------------------------------------------------------
|
|
// -1 nvt nvt vandaag middernacht (0:00) Effectief: je mag zelfs *nu*
|
|
|
|
// 0 10.00 9:00 vandaag 10:00 \ Effectief: lunchpakketen Akzo
|
|
// 0 10.00 11:00 morgen 8:00 /
|
|
// 1 16.00 15:00 morgen 8:00 \ Effectief: voor 16:00h morgen nog
|
|
// 1 16.00 17:00 overmorgen 8:00 / anders overmorgen
|
|
|
|
// 0 00.25 9:00 morgen 8:00 \ Effectief: morgen mag altijd
|
|
// 0 00.25 11:00 morgen 8:00 /
|
|
// 1 00.25 9:00 overmorgen 8:00 \ Effectief: overmorgen mag altijd
|
|
// 1 00.25 11:00 overmorgen 8:00 /
|
|
|
|
// 23.75 is nooit nodig?
|
|
// 0 23.75 9:00 unsupported (vandaag 23.75)
|
|
// 0 23.75 11:00 unsupported (vandaag 23.75)
|
|
// 1 23.75 9:00 morgen 8:00 \ Effectief: morgen mag altijd
|
|
// 1 23.75 11:00 morgen 8:00 /
|
|
|
|
// 0 leeg 9:00 vandaag 9:00 (nu) \ Effectief: je mag altijd nog *in de toekomst*
|
|
// 0 leeg 11:00 vandaag 11:00 (nu) /
|
|
// 1 leeg 9:00 morgen 9:00 \ Effectief: over exact 24 uur
|
|
// 1 leeg 16:00 morgen 16:00 /
|
|
// Als de mode niet is meegegeven dan standaard 0 nemen (expired)
|
|
if (typeof mode == "undefined") mode = 0;
|
|
if (mode == 2)
|
|
var sql = "SELECT fac.DatumTijdPlusUitvoerTijd(SYSDATE, rdp.res_disc_params_expire_dagen, 'DAGEN', null, null, 2) datum";
|
|
else
|
|
var sql = "SELECT fac.DatumTijdPlusUitvoerTijd(SYSDATE, COALESCE(" + (mode == 1? "res_disc_params_cancel_dagen" : "res_disc_params_expire_dagen") + ", 1),"
|
|
+ " 'DAGEN', " + ((restype == "CV" && S("res_cat_t1") >= 0)? S("res_cat_t1") : S("res_t1")) + ", "
|
|
+ " COALESCE(CASE"
|
|
+ " WHEN res_disc_params_expire_tijd = -1 OR res_disc_params_expire_tijd IS NULL"
|
|
+ " THEN NULL"
|
|
+ " ELSE res_disc_params_expire_tijd"
|
|
+ " END, " + ((restype == "CV" && S("res_cat_t2") >= 0)? S("res_cat_t2") : S("res_t2")) + "), 1) datum"
|
|
|
|
sql += " , res_disc_params_expire_tijd"
|
|
+ " , COALESCE(" + (mode == 1? "res_disc_params_cancel_dagen" : "res_disc_params_expire_dagen") + ", 1) dagen"
|
|
+ " , ins_discipline_min_level"
|
|
+ " , ins_discipline_omschrijving"
|
|
+ " FROM res_disc_params rdp, res_discipline rd"
|
|
+ " WHERE rdp.res_ins_discipline_key = rd.ins_discipline_key"
|
|
+ " AND rd.ins_discipline_key = " + discipline_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
if (oRs("dagen").Value < 0)
|
|
{
|
|
oRs.Close();
|
|
return (new Date).midnight();
|
|
}
|
|
var restype = oRs("ins_discipline_min_level").Value == 3? "R" : "CV";
|
|
var omschrijving = oRs("ins_discipline_omschrijving").Value; // handig voor logging
|
|
|
|
var exp_time = oRs("res_disc_params_expire_tijd").Value;
|
|
var exp_datum = new Date(oRs("datum").Value);
|
|
if (exp_time > 0) // BLCC#34448: hij is nog wel eens -1
|
|
{
|
|
var now = (new Date).getFloatHours();
|
|
if (now <= exp_time) // (exp_time rol A)
|
|
{ // grens-tijdstip nog niet vertreken.
|
|
if (oRs("dagen").Value == 0) // we blijven vandaag
|
|
exp_datum = exp_datum.setFloatHours(exp_time); // (exp_time rol B)
|
|
else
|
|
exp_datum = exp_datum.setFloatHours((restype == "CV" && S("res_cat_t1") >= 0)? S("res_cat_t1") : S("res_t1"));
|
|
}
|
|
// else grens-tijdstip verstreken. Naar "8 uur 's ochtends". Tijd staat al goed.
|
|
}
|
|
if (exp_datum < new Date)
|
|
exp_datum = new Date;
|
|
oRs.Close();
|
|
__Log("discipline_expire " + omschrijving + " (key: " + discipline_key + "): " + toDateTimeString(exp_datum) + ", mode: " + mode + (mode == 1? " (cancel)" : " (expire)"));
|
|
return exp_datum;
|
|
},
|
|
|
|
keepFlexDocuments:
|
|
function(res_key, old_act_key, act_key)
|
|
{
|
|
/* Match de srtkenmerk_key-s van de oude en nieuwe mld_stdmelding */
|
|
if (old_act_key != act_key)
|
|
{
|
|
__Log("Old res_activiteit_key: " + old_act_key + " New: " + act_key);
|
|
var flexsql = "SELECT k_old.res_kenmerk_key k_old"
|
|
+ " , k_new.res_kenmerk_key k_new"
|
|
+ " FROM res_srtkenmerk t"
|
|
+ " , res_kenmerk k_old"
|
|
+ " , res_kenmerk k_new"
|
|
+ " , res_activiteit s_old"
|
|
+ " , res_activiteit s_new"
|
|
+ " WHERE s_old.res_activiteit_key = " + old_act_key
|
|
+ " AND s_new.res_activiteit_key = " + act_key
|
|
+ " AND k_old.res_activiteit_key = s_old.res_activiteit_key"
|
|
+ " AND k_new.res_activiteit_key = s_new.res_activiteit_key"
|
|
+ " AND k_old.res_kenmerk_verwijder IS NULL"
|
|
+ " AND k_new.res_kenmerk_verwijder IS NULL"
|
|
+ " AND k_old.res_srtkenmerk_key = t.res_srtkenmerk_key"
|
|
+ " AND k_new.res_srtkenmerk_key = t.res_srtkenmerk_key"
|
|
+ " AND t.res_srtkenmerk_verwijder IS NULL";
|
|
|
|
var subfolder = "RES/" + subfolderKey("R", res_key)
|
|
RenameFlexFolders(subfolder, flexsql);
|
|
}
|
|
},
|
|
|
|
getfostatustext:
|
|
function (p) {
|
|
var statustekst = "??";
|
|
var s = parseInt(p, 10);
|
|
// pseudo status_key -1 kan worden gebruikt om dirty te signaleren
|
|
switch (s) {
|
|
case 1: { statustekst = L("lcl_optie"); break; }
|
|
case 2: { statustekst = L("lcl_def"); break; }
|
|
case 3: { statustekst = L("lcl_blokkade"); break; }
|
|
case 4: { statustekst = L("lcl_vervallen"); break; }
|
|
case -1: { statustekst = L("lcl_res_status_dirty"); break; }
|
|
}
|
|
return statustekst;
|
|
},
|
|
|
|
getbostatustext:
|
|
function (p) {
|
|
var statustekst = "??";
|
|
var s = parseInt(p, 10);
|
|
switch (s) {
|
|
case 2: { statustekst = L("lcl_res_resnew"); break; }
|
|
case 5: { statustekst = L("lcl_res_resafm"); break; }
|
|
case 6: { statustekst = L("lcl_res_resver"); break; }
|
|
}
|
|
return statustekst;
|
|
},
|
|
|
|
|
|
// Controleert/bepaalt de rechten op het 'Algemeen' blok bij een (deel)reservering
|
|
// Altijd worden de disciplines van de catering/voorziening bekeken
|
|
// Voor restype=="R" wordt ook de discipline van de RES_RUIMTE bekeken
|
|
// We kijken pessimistisch: je moet rechten hebben voor alle disciplines
|
|
// Optioneel pdisc_key: controleer alleen voor deze discipline
|
|
func_enabled: function res_func_enabled(rsv_ruimte_key, pdisc_key, params)
|
|
{
|
|
var params = params || {};
|
|
// Wat informatie om rechten te kunnen bepalen
|
|
var sql = "SELECT r.res_ruimte_opstel_key"
|
|
+ " , r.alg_ruimte_key"
|
|
+ " , r.res_rsv_ruimte_van"
|
|
+ " , r.res_rsv_ruimte_tot"
|
|
+ " , r.res_rsv_ruimte_contact_key"
|
|
+ " , r.res_rsv_ruimte_host_key"
|
|
+ " , r.res_status_fo_key"
|
|
+ " , r.res_status_bo_key"
|
|
+ " , r.res_reservering_key"
|
|
+ " , r.res_rsv_ruimte_verwijder"
|
|
+ " , r.res_activiteit_key"
|
|
+ " , r.res_rsv_ruimte_afgerond"
|
|
+ " , ra.res_activiteit_notfrontend"
|
|
+ " , ra.res_activiteit_meteindtijd"
|
|
+ " FROM res_rsv_ruimte r,"
|
|
+ " res_activiteit ra"
|
|
+ " WHERE res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " AND r.res_activiteit_key = ra.res_activiteit_key";
|
|
var roRs = Oracle.Execute(sql);
|
|
|
|
var rsv_ruimte_verwijder = roRs("res_rsv_ruimte_verwijder").Value;
|
|
var res_reservering_key = roRs("res_reservering_key").Value;
|
|
var alg_ruimte_key = roRs("alg_ruimte_key").Value;
|
|
var status_fo_key = roRs("res_status_fo_key").Value;
|
|
var status_bo_key = roRs("res_status_bo_key").Value;
|
|
var rsv_ruimte_van = new Date(roRs("res_rsv_ruimte_van").Value);
|
|
var rsv_ruimte_tot = new Date(roRs("res_rsv_ruimte_tot").Value);
|
|
var rsv_ruimte_contact_key = roRs("res_rsv_ruimte_contact_key").Value;
|
|
var rsv_ruimte_host_key = roRs("res_rsv_ruimte_host_key").Value;
|
|
var res_activiteit_key = roRs("res_activiteit_key").Value;
|
|
var res_goedgekeurd = roRs("res_rsv_ruimte_afgerond").Value == 1;
|
|
var res_opstel_key = roRs("res_ruimte_opstel_key").Value;
|
|
var notfrontend = roRs("res_activiteit_notfrontend").Value;
|
|
var met_eindtijd = roRs("res_activiteit_meteindtijd").Value == 1;
|
|
|
|
// Bepaal discipline parkeerplaatsen voor reserveringen. Deze moet uitgesloten worden voor de autorisatie controle.
|
|
// Als de reservering *voor* earliest_expire ligt gaan we moeilijk doen
|
|
var earliest_expire_changeCV = new Date(1000, 1, 1); // Wijzigingshorizon CV
|
|
var earliest_expire_change = new Date(1000, 1, 1); // Wijzigingshorizon
|
|
var earliest_expire_cancel = new Date(1000, 1, 1); // Annuleringshorizon
|
|
|
|
var hasCV = false;
|
|
var max_dbkosten = 0; // Maximale doorberekeningskosten van alle disciplines binnen een reservering;
|
|
var canWritePresentPrk = true; // Kan ik de parkeerplaatsen die AANWEZIG zijn zien en wijzigen.
|
|
var disc_key_arr = [];
|
|
var expire_mode = (S("res_247organisation")==1? 2 : 0);
|
|
|
|
if (typeof pdisc_key != "undefined" && pdisc_key != null) // alleen pdisc, ongeacht of je hem al had
|
|
{
|
|
disc_key_arr = [pdisc_key];
|
|
var expire = res.discipline_expire(pdisc_key, expire_mode);
|
|
if (expire > earliest_expire_change) earliest_expire_change = expire;
|
|
var expire_cancel = res.discipline_expire(pdisc_key, 1);
|
|
if (expire_cancel > earliest_expire_cancel) earliest_expire_cancel = expire_cancel;
|
|
if (rsv_ruimte_van < expire_cancel)
|
|
{ // Doorberekeningskosten van de meegegeven discipline
|
|
var sql = "SELECT rdp.res_disc_params_kosten"
|
|
+ " FROM res_disc_params rdp"
|
|
+ " WHERE rdp.res_ins_discipline_key = " + pdisc_key;
|
|
var oRs1 = Oracle.Execute(sql);
|
|
max_dbkosten = oRs1("res_disc_params_kosten").Value;
|
|
oRs1.Close();
|
|
}
|
|
}
|
|
else // alle disciplines die je al had
|
|
{ // Bepaal alle CV disciplines waar we iets van hebben
|
|
var discs = "SELECT DISTINCT ra.res_discipline_key"
|
|
+ " , res_disc_params_kosten"
|
|
+ " FROM res_rsv_artikel rra"
|
|
+ " , res_artikel ra"
|
|
+ " , res_disc_params rdp"
|
|
+ " WHERE rra.res_artikel_key = ra.res_artikel_key"
|
|
+ " AND ra.res_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND rra.res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " UNION " // geen dubbelen nodig
|
|
+ "SELECT res_discipline_key"
|
|
+ " , 0" // Voor voorziening reserveringen met alleen reserveerbare objecten zijn de kosten altijd 0 en wordt niets doorberekend. Kostendoorberekening alleen voor ruimten en catering.
|
|
+ " FROM res_deel rd, res_rsv_deel rrd"
|
|
+ " WHERE rd.res_deel_key = rrd.res_deel_key"
|
|
+ " AND rrd.res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
var oRs = Oracle.Execute(discs);
|
|
|
|
if (!oRs.eof)
|
|
{
|
|
hasCV = true; // Er bestaan artikelen bij de reservering.
|
|
}
|
|
else
|
|
{ // Als er nog geen artikelen bij de reservering bestaan, dan kijken welke disciplines er mogelijk zijn.
|
|
oRs.Close();
|
|
// hasCV = false // we weten in deze tak al dat er geen CV is
|
|
var discs = "SELECT rdp.res_ins_discipline_key res_discipline_key"
|
|
+ " , rdp.res_disc_params_kosten"
|
|
+ " FROM res_disc_params rdp"
|
|
+ " , res_v_aanwezigDISCIPLINE d"
|
|
+ " WHERE ins_discipline_min_level = 2"
|
|
+ " AND d.ins_discipline_key IN"
|
|
+ " (SELECT ins_discipline_key"
|
|
+ " FROM fac_v_webgebruiker g"
|
|
+ " , fac_functie f"
|
|
+ " WHERE g.fac_functie_key = f.fac_functie_key"
|
|
+ " AND f.fac_functie_code IN ('WEB_RESFOF','WEB_RESBOF','WEB_RESUSE')"
|
|
+ " AND g.prs_perslid_key = " + user_key
|
|
+ " AND fac_gebruiker_prs_level_write < 9"
|
|
+ " AND fac_gebruiker_alg_level_write < 9"
|
|
+ ")"
|
|
+ " AND d.ins_discipline_key IN"
|
|
+ " (SELECT res_discipline_key"
|
|
+ " FROM res_v_srtartikel_onrgoed"
|
|
+ " WHERE alg_ruimte_key IN"
|
|
+ " (SELECT alg_ruimte_key"
|
|
+ " FROM res_v_rsv_ruimte_2_alg_ruimte "
|
|
+ " WHERE res_alg_ruimte_verwijder IS NULL"
|
|
+ " AND res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ ")"
|
|
+ ")"
|
|
+ " AND EXISTS (SELECT res_activiteit_key"
|
|
+ " FROM res_activiteitdiscipline rad"
|
|
+ " WHERE rad.res_discipline_key = d.ins_discipline_key"
|
|
+ " AND rad.res_activiteit_key = " + res_activiteit_key
|
|
+ ")"
|
|
+ " AND d.ins_discipline_key = rdp.res_ins_discipline_key";
|
|
var oRs = Oracle.Execute(discs);
|
|
}
|
|
|
|
while (!oRs.eof)
|
|
{
|
|
// Nieuwe catering wordt clientside gecontroleerd of deze binnen de expire tijd zitten. Dat is dus zo anders kom je hier niet.
|
|
// Disciplines met catering die binnen de expire tijd liggen kunnen niet open geklapt worden.
|
|
// 1) Als de reservering al voorzieningen had (hasCV = true) dan bevat oRs de discipline van deze voorzieningen
|
|
// Voor deze disciplines de expire (en cancel) tijd bepalen.
|
|
// 2) Als de reservering nog geen voorzieningen had (hasCV = false) dan bevat oRs alle disciplines waar user_key recht op heeft.
|
|
// Voor deze disciplines niet de expire (en cancel) tijd bepalen want je weet niet of er op deze disciplines nieuwe voorzieningen zijn geselecteerd.
|
|
// Als er nieuwe voorzieningen zijn geselecteerd dan vallen deze binnen de expire tijd (clientside gecontroleerd).
|
|
var expireCV = res.discipline_expire(oRs("res_discipline_key").Value, expire_mode);
|
|
var expire = expireCV;
|
|
var expire_cancel = res.discipline_expire(oRs("res_discipline_key").Value, 1);
|
|
if (hasCV)
|
|
{ // Wijzig earliest_expire_change, earliest_expire_changeCV en earliest_expire_cancel alleen als voor deze discipline ook echt catering/voorziening aanwezig is
|
|
if (expireCV > earliest_expire_changeCV) earliest_expire_changeCV = expireCV;
|
|
if (expire > earliest_expire_change) earliest_expire_change = expireCV;
|
|
if (expire_cancel > earliest_expire_cancel) earliest_expire_cancel = expire_cancel;
|
|
if ((rsv_ruimte_van < expire_cancel) && (max_dbkosten < oRs("res_disc_params_kosten").Value))
|
|
{ // Annuleringshorizon is verstreken en doorberekeningskosten zijn hoger dan die ik al heb (gevonden)
|
|
max_dbkosten = oRs("res_disc_params_kosten").Value;
|
|
}
|
|
}
|
|
|
|
if (oRs("res_discipline_key").Value != S("vis_parking_key"))
|
|
// Dicipline toevoegen
|
|
disc_key_arr.push(oRs("res_discipline_key").Value);
|
|
else
|
|
{ // Er is een parkeerplaats gereserveerd die ik niet moet toevoegen.
|
|
// Heb ik lees en wijzig rechten op "WEB_BEZPRK" (Kan ik parkeerplaatsen zien en reserveren).
|
|
var bresult = user.func_enabled("BEZ",
|
|
-1, // discipline key
|
|
-1, // alg_key
|
|
user_key,
|
|
false, // pessimist
|
|
false); // isOptional
|
|
|
|
// Kan ik de aanwezige parkeerplaatsen zien en reserveren (Alleen als parkeerplaatsen aanwezig zijn kan canWritePresentPrk false worden).
|
|
canWritePresentPrk = bresult.canRead("WEB_BEZPRK") && bresult.canWrite("WEB_BEZPRK")
|
|
}
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.Close();
|
|
}
|
|
|
|
// Na de disciplines van de voorzieningen nu als laatste de discipline van de ruimte van de reservering.
|
|
var canWrite_ruimte = true;
|
|
var res_ruimte_extern = false;
|
|
if (alg_ruimte_key == null && (typeof pdisc_key == "undefined" || pdisc_key == null))
|
|
{ // "R" reservering, bepaal *ook* discipline van de ruimte en alg_ruimte_key
|
|
var sql = "SELECT MIN (alg_ruimte_key) alg_ruimte_key"
|
|
+ " , rr.res_discipline_key"
|
|
+ " , rdp.res_disc_params_kosten"
|
|
+ " , rr.res_ruimte_extern_id"
|
|
+ " FROM res_ruimte_opstelling rro"
|
|
+ " , res_ruimte rr"
|
|
+ " , res_alg_ruimte rar"
|
|
+ " , res_disc_params rdp"
|
|
+ " WHERE rar.res_ruimte_key = rr.res_ruimte_key "
|
|
+ " AND rr.res_ruimte_key = rro.res_ruimte_key "
|
|
+ " AND rr.res_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND rro.res_ruimte_opstel_key = " + res_opstel_key;
|
|
var sqlG =" GROUP BY res_discipline_key"
|
|
+ " , rdp.res_disc_params_kosten"
|
|
+ " , rr.res_ruimte_extern_id";
|
|
var oRs = Oracle.Execute(sql + " AND res_alg_ruimte_verwijder IS NULL" + sqlG );
|
|
if (oRs.Eof) // Voor als *alle* onderliggende res_rsv_ruimte verwijderd
|
|
var oRs = Oracle.Execute( sql + sqlG );
|
|
var expire = res.discipline_expire(oRs("res_discipline_key").Value, expire_mode);
|
|
if (expire > earliest_expire_change) earliest_expire_change = expire;
|
|
var expire_cancel = res.discipline_expire(oRs("res_discipline_key").Value, 1);
|
|
if (expire_cancel > earliest_expire_cancel) earliest_expire_cancel = expire_cancel;
|
|
if (max_dbkosten < oRs("res_disc_params_kosten").Value)
|
|
{ // De doorberekeningskosten zijn hoger dan die ik al heb (gevonden).
|
|
if (((rsv_ruimte_van < expire_cancel) && (S("res_delete_ask_kosten") != 2)) || ((S("res_delete_ask_kosten") == 2) && (status_fo_key == 2)))
|
|
{ // Annuleringshorizon is verstreken OF definitieve reservering.
|
|
max_dbkosten = oRs("res_disc_params_kosten").Value;
|
|
}
|
|
}
|
|
var disc_key_r = oRs("res_discipline_key").Value;
|
|
alg_ruimte_key = oRs("alg_ruimte_key").Value;
|
|
res_ruimte_extern = oRs("res_ruimte_extern_id").Value != null;
|
|
disc_key_arr.push(disc_key_r);
|
|
oRs.Close();
|
|
// Rechten op ruimte controleren met afzonderlijke query (niet samen met catering).
|
|
// Dat gaat namelijk 'mis' als je *helemaal* geen rechten hebt voor de ruimte
|
|
// Dan geven we je uiteindelijk impliciet wel leesrechten
|
|
var auth_r = user.func_enabled2( "RES"
|
|
, { ins_discipline_key: disc_key_r
|
|
, alg_key: alg_ruimte_key
|
|
, prs_key: roRs("res_rsv_ruimte_contact_key").Value
|
|
, isOptional: true
|
|
}
|
|
);
|
|
canWrite_ruimte = auth_r.anyfound &&
|
|
auth_r.canWrite("WEB_RESFOF") ||
|
|
auth_r.canWrite("WEB_RESBOF") ||
|
|
auth_r.canWrite("WEB_RESUSE");
|
|
}
|
|
|
|
var rresult = user.func_enabled2("RES"
|
|
, { ins_discipline_key: disc_key_arr.join(",")
|
|
, alg_key: alg_ruimte_key
|
|
, prs_key: roRs("res_rsv_ruimte_contact_key").Value
|
|
, isOptional: (params.isOptional? params.isOptional : false)
|
|
, checkOptimistic: (params.checkOptimistic ? params.checkOptimistic : false)
|
|
}
|
|
);
|
|
roRs.Close();
|
|
// earliest_expire_change en earliest_expire_cancel hebben zeker een goede waarde van de ruimte discipline (startdatum 1/1/1000 is vervangen).
|
|
rresult.earliest_expire_change = earliest_expire_change;
|
|
rresult.earliest_expire_cancel = earliest_expire_cancel;
|
|
// Voorkom dat in earliest_expire_changeCV startdatum 1/1/1000 blijft staan.
|
|
// Als de earliest_expire_changeCV startdatum niet is gewijzigd, dan waren er geen artikelen geselecteerd. Dan op vandaag/nu zetten.
|
|
// Clientsite wordt wel gecontroleerd welke catalogus opengeklapt mag worden.
|
|
// MGE: Kunnen we niet initeel de waar de op vandaag/nu zetten?
|
|
rresult.earliest_expire_changeCV = (earliest_expire_changeCV.getTime() == (new Date(1000, 1, 1)).getTime() ? new Date(): earliest_expire_changeCV);
|
|
|
|
// Als er geen verbruiksartikelen zijn geboekt dan de canChange (ruimte) niet afhankelijk maken van de canChangeCV (artikelen).
|
|
if (hasCV && rresult.earliest_expire_changeCV > rresult.earliest_expire_change)
|
|
rresult.earliest_expire_change = rresult.earliest_expire_changeCV;
|
|
|
|
rresult.max_dbkosten = max_dbkosten;
|
|
rresult.res_reservering_key = res_reservering_key;
|
|
rresult.rsv_ruimte_verwijder = rsv_ruimte_verwijder;
|
|
rresult.res_met_eindtijd = met_eindtijd;
|
|
|
|
rresult.canReadNoShow = rresult.canRead("WEB_RESNOS");
|
|
rresult.canWriteNoShow = rresult.canWrite("WEB_RESNOS");
|
|
|
|
// PAS OP!!!: WEB_RESMSU is disciplineloos dus niet in cresult! Daardoor zijn cresult.canWrite("WEB_RESMSU") en cresult.canRead("WEB_RESMSU") altijd false.
|
|
var haveRESMSUrights = user.checkAutorisation("WEB_RESMSU", true) != null; // Pas op: disciplineloos dus niet in cresult!
|
|
var haveRESAFRrights = user.checkAutorisation("WEB_RESAFR", true) != null; // Pas op: disciplineloos dus niet in cresult!
|
|
|
|
if (S("facilities_flike_past") >= 0)
|
|
{
|
|
var vandaag = new Date();
|
|
var flike_days = vandaag.getTime() - rsv_ruimte_tot.getTime();
|
|
var flike_past = S("facilities_flike_past") * 1000 * 60 * 60 * 24;
|
|
flike_days = (flike_days < 0 ? flike_past+1 : flike_days); // Als flike_days < 0 dan is de reservering nog niet afgelopen, dus mag nog niet worden beoordeeld
|
|
rresult.canLike = (status_bo_key == 5 || status_bo_key == 6 || (flike_days < flike_past)) &&
|
|
(rsv_ruimte_contact_key == user_key || rsv_ruimte_host_key == user_key);
|
|
}
|
|
|
|
// -- CONTROLE LEESRECHTEN --
|
|
// als disc_key_arr leeg is hebben we nog 'niets' en zijn we heel soepel
|
|
rresult.canReadAny = !disc_key_arr.length||
|
|
rresult.canRead("WEB_RESBAC") ||
|
|
rresult.canRead("WEB_RESFOF") ||
|
|
rresult.canRead("WEB_RESBOF") ||
|
|
rresult.canRead("WEB_RESUSE");
|
|
|
|
// (als alleen) Frontend-rechten-->we controleren nog strenger
|
|
rresult.canReadFEOnly = false;
|
|
if ( rresult.canReadAny
|
|
&& !rresult.canRead("WEB_RESBAC")
|
|
&& !rresult.canRead("WEB_RESFOF")
|
|
&& !rresult.canRead("WEB_RESBOF")
|
|
)
|
|
{ // frontend controles
|
|
rresult.canReadFEOnly = true;
|
|
if ( rsv_ruimte_contact_key != user_key
|
|
&& rsv_ruimte_host_key != user_key
|
|
&& !user.isCollega(rsv_ruimte_contact_key)
|
|
&& !user.isCollega(rsv_ruimte_host_key))
|
|
{
|
|
rresult.canReadAny = false;// JGL: Kan dit nog legaal gebeuren?
|
|
}
|
|
}
|
|
|
|
rresult.canReadFO = rresult.canRead("WEB_RESFOF");
|
|
rresult.canReadBO = rresult.canRead("WEB_RESBOF");
|
|
|
|
// -- CONTROLE SCHRIJFRECHTEN --
|
|
// Je moet tenminste schrijfrechten hebben
|
|
rresult.canChange = rresult.canReadAny &&
|
|
(rresult.canWrite("WEB_RESFOF") ||
|
|
rresult.canWrite("WEB_RESBOF") ||
|
|
rresult.canWrite("WEB_RESUSE")) &&
|
|
canWritePresentPrk &&
|
|
(!res_goedgekeurd || (res_goedgekeurd && haveRESAFRrights)) &&
|
|
(!notfrontend || rresult.canWrite("WEB_RESFOF") || rresult.canWrite("WEB_RESBOF"));
|
|
rresult.canChangeCV = rresult.canChange;
|
|
|
|
// als disc_key_arr leeg is hebben we nog 'niets' en zijn we heel soepel
|
|
rresult.canChange = rresult.canChange || !disc_key_arr.length; // canChange is een boolean!
|
|
rresult.canChangeUrole = (typeof urole == "undefined" ? "" : urole); // (mld_close kent deze niet, en change-t ook niet interactief)
|
|
|
|
if (rresult.canChange && rresult.canChangeUrole == "mi") // mi kan zeker niet wijzigen
|
|
{
|
|
if (rresult.canWrite("WEB_RESFOF"))
|
|
rresult.canChangeUrole = "fo";
|
|
else if (rresult.canWrite("WEB_RESBOF"))
|
|
rresult.canChangeUrole = "bo";
|
|
else
|
|
rresult.canChangeUrole = "fe";
|
|
}
|
|
|
|
if (!rresult.canChange)
|
|
rresult.readoReason = L("lcl_res_reado_parts"); // geen schrijfrechten op alle onderdelen
|
|
|
|
// Vanaf hier heeft canChange betrekking op het bovenste deel van het scherm
|
|
// canChangeCV gaat over het onderste deel
|
|
rresult.canChange = rresult.canChange && canWrite_ruimte;
|
|
|
|
// Had ik deze kunnen aanmaken? Dan mag hij als bron van multi's dienen
|
|
rresult.couldCreate = rresult.canChange && !res_ruimte_extern;
|
|
|
|
// Reserveringen met openstaande meldingen kunnen niet worden verwijderd.
|
|
var openstaandemld = false;
|
|
if (S("res_with_mld") == 1)
|
|
{ // Er zijn meldingen bij een reservering mogelijk
|
|
var sql = "SELECT m.mld_melding_key"
|
|
+ " FROM mld_melding m"
|
|
+ " WHERE mld_melding_status IN (0, 2, 3, 4, 7)" // Openstaande melding
|
|
+ " AND m.res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.eof) // Er is nog een openstaande melding
|
|
openstaandemld = true;
|
|
oRs.Close();
|
|
}
|
|
|
|
rresult.canDelete = rresult.canChange && !openstaandemld && (!res_ruimte_extern || haveRESMSUrights); // Dan kun je ook alles er afhalen tenslotte met hetzelfde effect
|
|
|
|
rresult.canChangeFEOnly = false;
|
|
// (als alleen) Frontend-rechten-->we controleren nog strenger
|
|
if ( rresult.canChange
|
|
&& !rresult.canWrite("WEB_RESFOF")
|
|
&& !rresult.canWrite("WEB_RESBOF")
|
|
)
|
|
{ // frontend controles
|
|
rresult.canChangeFEOnly = true;
|
|
if (S("res_fe_edit_option_only") == 1 // Setting: Alleen opties mogen bewerkt
|
|
&& status_fo_key != 1)
|
|
{
|
|
rresult.canChange = false;
|
|
rresult.readoReason = L("lcl_res_fe_edit_option_only");
|
|
}
|
|
|
|
if (rresult.canChange && rsv_ruimte_van < rresult.earliest_expire_change)
|
|
{
|
|
rresult.canChange = false;
|
|
rresult.readoReason = L("lcl_res_reado_late"); // Ruimte of sommige voorzieningen mogen niet meer gewijzigd worden
|
|
}
|
|
rresult.canDelete = rresult.canChange && !openstaandemld && !res_ruimte_extern; // Annuleringshorizon (canDelete) i.p.v. wijzigingshorizon (canChange)
|
|
|
|
if (rresult.canDelete && rsv_ruimte_van < rresult.earliest_expire_cancel)
|
|
{
|
|
rresult.canDelete = false;
|
|
}
|
|
|
|
var sql_d = "SELECT SUM(aantal) aantal_cv"
|
|
+ " FROM (SELECT count(*) aantal"
|
|
+ " FROM res_rsv_deel"
|
|
+ " WHERE res_rsv_deel_verwijder IS NOT NULL"
|
|
+ " AND res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " UNION "
|
|
+ "SELECT count(*) aantal"
|
|
+ " FROM res_rsv_artikel"
|
|
+ " WHERE res_rsv_artikel_verwijder IS NULL"
|
|
+ " AND res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ ")";
|
|
oRs_d = Oracle.Execute(sql_d);
|
|
if (oRs_d("aantal_cv").value > 0)
|
|
rresult.canChangeCV = rresult.canChangeCV && (rsv_ruimte_van < rresult.earliest_expire_changeCV? false : true);
|
|
oRs_d.Close();
|
|
rresult.canChangeCV = (S("res_cat_with_expired_room") ? rresult.canChangeCV : rresult.canChange);
|
|
|
|
if ( rresult.canChange && rresult.canChangeUrole != "fo"
|
|
&& rsv_ruimte_contact_key != user_key
|
|
&& !user.isCollega(rsv_ruimte_contact_key)
|
|
&& !user.isCollega(rsv_ruimte_host_key))
|
|
{ // JGL: Volgens mij kan dit niet meer legaal gebeuren sinds 5.1.2RC2
|
|
rresult.canChange = false;
|
|
rresult.couldCreate = false;
|
|
rresult.readoReason = L("lcl_res_notself");
|
|
}
|
|
|
|
// Als FE mag je een aantal velden en kenmerken wel wijzigen in een reservering.
|
|
rresult.canChangeFEExtended = false;
|
|
// reservering is van mij of een collega (user.isCollega is altijd inclusief mezelf).
|
|
if ( user.isCollega(rsv_ruimte_contact_key)
|
|
|| user.isCollega(rsv_ruimte_host_key)
|
|
)
|
|
{
|
|
// status_bo is nog niet "afgemeld" (5) of "verwerkt" (6)
|
|
// status_fo is niet "vervallen" (4)
|
|
// en je bent nog niet voorbij de reserveringstijd
|
|
if (status_bo_key < 5 && status_fo_key != 4 && rsv_ruimte_tot > new Date() )
|
|
{
|
|
rresult.canChangeFEExtended = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Als *alle* R/C/V onderdelen 'verwerkt' zijn dan worden we ook readonly
|
|
// Let op: CV -reservering heeft geen bo-status in res_rsv_ruimte
|
|
var sql1 = "SELECT rd.res_status_bo_key"
|
|
+ " FROM res_v_aanwezigrsv_deel rd"
|
|
+ " WHERE rd.res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " UNION "
|
|
+ "SELECT ra.res_status_bo_key"
|
|
+ " FROM res_v_aanwezigrsv_artikel ra"
|
|
+ " WHERE ra.res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
|
|
var sql2 = "";
|
|
if (res_opstel_key != null)
|
|
{
|
|
sql2 = "SELECT res_status_bo_key"
|
|
+ " FROM res_v_aanwezigrsv_ruimte rs"
|
|
+ " WHERE rs.res_rsv_ruimte_key = " + rsv_ruimte_key;
|
|
}
|
|
sql = "SELECT MAX(res_status_bo_key) max_bo"
|
|
+ " , MIN (res_status_bo_key) min_bo"
|
|
+ " FROM (" + sql1 + (sql2 != ""? " UNION " + sql2 : "") + ")";
|
|
|
|
oRs = Oracle.Execute(sql);
|
|
rresult.min_bo = oRs("min_bo").Value;
|
|
rresult.max_bo = oRs("max_bo").Value;
|
|
oRs.Close();
|
|
if (rresult.min_bo && rresult.min_bo == 6) // verwerkt
|
|
{
|
|
rresult.canChange = false;
|
|
rresult.canChangeCV = false;
|
|
rresult.readoReason = L("lcl_res_reado_completed"); // Alles is al verwerkt;
|
|
}
|
|
else if (res_opstel_key != null) // CV of R kan ook afzonderlijk al de bo status 6 hebben en dus niet meer wijzigbaar zijn.
|
|
{ // Maar dan moet het wel een ruimte reservering zijn. Dan heeft sql2 ook een waarde.
|
|
sql = "SELECT MIN (res_status_bo_key) min_bo"
|
|
+ " FROM (" + sql1 + ")";
|
|
oRs = Oracle.Execute(sql);
|
|
if (oRs("min_bo").Value && oRs("min_bo").Value == 6)
|
|
rresult.canChangeCV = false;
|
|
|
|
sql = "SELECT MIN (res_status_bo_key) min_bo"
|
|
+ " FROM (" + sql2 + ")";
|
|
oRs = Oracle.Execute(sql);
|
|
if (oRs("min_bo").Value && oRs("min_bo").Value == 6)
|
|
rresult.canChange = false;
|
|
oRs.Close();
|
|
}
|
|
|
|
if (rresult.canDelete)
|
|
{ // Hij mag geen onderdelen hebben met status 6 (verwerkt)
|
|
if (rresult.max_bo && rresult.max_bo == 6)
|
|
rresult.canDelete = false;
|
|
}
|
|
|
|
rresult.canChangeKorting = rresult.canChange
|
|
&& (status_bo_key != 6)
|
|
&& ( (rresult.canWrite("WEB_RESFOF") && ((S("res_roompricingkorting") & 1) == 1))
|
|
|| (rresult.canWrite("WEB_RESBOF") && ((S("res_roompricingkorting") & 2) == 2))
|
|
);
|
|
|
|
rresult.canChangeTotaal = rresult.canChange
|
|
&& (status_bo_key != 6)
|
|
&& ( (rresult.canWrite("WEB_RESFOF") && ((S("res_roompricingtotaal") & 1) == 1))
|
|
|| (rresult.canWrite("WEB_RESBOF") && ((S("res_roompricingtotaal") & 2) == 2))
|
|
);
|
|
|
|
// Goedkeuren door aanmaker/besteller (of zijn/haar vervanger) nadat de reservering voorbij is (in het verleden ligt).
|
|
rresult.canGoedkeur = ((S("res_approval") == 1 && rsv_ruimte_tot < new Date()) || // Setting res_approval = 1: Als reservering is afgelopen.
|
|
(S("res_approval") == 2 && (rresult.min_bo && rresult.min_bo == 5))) && // Setting res_approval = 2: Als reservering is geheel verwerkt.
|
|
!res_goedgekeurd &&
|
|
rresult.canReadAny &&
|
|
(user.isCollega(rsv_ruimte_contact_key) || user.isCollega(rsv_ruimte_host_key));
|
|
|
|
if ((status_bo_key && status_bo_key < S("res_bo_status_key")) || // ruimte is af te melden
|
|
(rresult.min_bo && rresult.min_bo < S("res_bo_status_key"))) // CV is af te melden
|
|
{
|
|
rresult.canClose = rresult.canWrite("WEB_RESBOF"); // je moet wel rechten ervoor hebben
|
|
}
|
|
|
|
rresult.canWriteFlags = rresult.canWrite("WEB_RESBOF") || rresult.canWrite("WEB_RESFOF"); // Kan ik flags aanpassen.
|
|
|
|
return rresult;
|
|
},
|
|
|
|
// fnStep kan bijvoorbeeld 'parent.planStep' zijn en wordt (clientside!) aangeroepen
|
|
// als iemand 'eerder' of 'later' klikt met als parameter resp. (-1, -1) en (+1, +1)
|
|
build_planbord_tijdbalk : function (res_van, nr_days, hour_px, p_res_t1, p_res_t2, fnStep)
|
|
{
|
|
var html = [];
|
|
var size_px = hour_px * (p_res_t2-p_res_t1) + 1;
|
|
for (dagen = 1; dagen <= nr_days; dagen++)
|
|
{
|
|
var dttxt = "";
|
|
if (res_van)
|
|
{
|
|
var dt2 = new Date(res_van);
|
|
dt2.setDate(dt2.getDate() + dagen - 1);
|
|
dttxt = toDateString(dt2);
|
|
}
|
|
html.push("<td class='plantd tijdbalk' title='" + dttxt + "'><div class='tddiv' style='height:" + (dttxt? 32 : 16) + "px;'>");
|
|
html.push("<div style='height:" + (dttxt? 32 : 16) + "px;width:" + size_px + "px'> </div>");
|
|
|
|
var txtnp; // 'naast' de next-prev buttons
|
|
if (hour_px < 16) // Komt het op eigen regel
|
|
txtnp = ""
|
|
else
|
|
txtnp = "<span id='plandate'>"+dttxt+"</span>";
|
|
|
|
if (fnStep && dagen==1) // eerste dag
|
|
{
|
|
txtnp = "<span title='" + L("lcl_res_plan_tt_meer_eerder")
|
|
+ "' class='details' id='resplanmoreprev' onclick='" + fnStep + "(-1, 0)'>"
|
|
+ I("fa-plus-circle")
|
|
+ "</span> "
|
|
+ txtnp;
|
|
txtnp = "<span title='" + L("lcl_res_plan_tt_eerder")
|
|
+ "' class='details' id='resplanprev' onclick='" + fnStep
|
|
+ "(-1, -1)'>"
|
|
+ I("fa-arrow-left")
|
|
+ "</span> "
|
|
+ txtnp;
|
|
}
|
|
if (fnStep && dagen==nr_days) // laatste dag
|
|
{
|
|
txtnp = txtnp + " <span title='"+L("lcl_res_plan_tt_meer_later")+"' class='details' id='resplanmorenext' onclick='"+fnStep+"(0, +1)'>"+I("fa-plus-circle")+"</span>";
|
|
txtnp = txtnp + " <span title='"+L("lcl_res_plan_tt_later")+"' class='details' id='resplannext' onclick='"+fnStep+"(+1, +1)'>"+I("fa-arrow-right")+"</span>";
|
|
}
|
|
|
|
if (hour_px < 16 && dttxt) // alleen nog datum op losse regel
|
|
{
|
|
var px_start = (p_res_t2 - p_res_t1) / 2 * hour_px;
|
|
var txt = dttxt;
|
|
var width = 90;
|
|
if (hour_px<8)
|
|
{
|
|
txt = txt.substring(0, 8); // haal zelfs jaar er af
|
|
width=90;
|
|
}
|
|
var div = "<div class='plandate'"
|
|
+" style='left:" + (px_start-width / 2) + "px;width:" + width + "px'>"
|
|
+txt + "<br>" + txtnp + "</div>";
|
|
html.push("\n" + div);
|
|
}
|
|
else
|
|
{
|
|
if (txtnp)
|
|
{
|
|
var div = "<div class='plandate' style='width:100%'>"
|
|
+ txtnp + "</div>";
|
|
html.push(div);
|
|
}
|
|
|
|
var skiphours = 1;
|
|
if (hour_px < 48)
|
|
skiphours = 2;
|
|
if (hour_px < 24)
|
|
skiphours = 3;
|
|
|
|
var s = p_res_t1;
|
|
var i0 = -2;
|
|
for (s = p_res_t1; s <= p_res_t2; s += skiphours)
|
|
{
|
|
var h = Math.floor(s);
|
|
if (h < 10) h = "0" + h;
|
|
var m = Math.floor((s - h)*60);
|
|
if (m < 10) m = "0" + m;
|
|
m = ":" + m
|
|
|
|
var px_start = (s - p_res_t1) * hour_px;
|
|
var div = "<div class='plantime'"
|
|
+" style='left:" + (px_start - 19) + "px; top:" + (dttxt? 16 : 0) + "px'>"
|
|
+h + m + "</div>";
|
|
html.push("\n"+div);
|
|
}
|
|
}
|
|
|
|
html.push("</div></td>");
|
|
if (dagen<nr_days)
|
|
{
|
|
html.push('<td class="between"><div> </div></td>');
|
|
}
|
|
else
|
|
{
|
|
html.push('<td class="post"><div> </div></td>');
|
|
}
|
|
} // dagen
|
|
return html.join("");
|
|
},
|
|
|
|
// Deze view wil ik graag nog kwijt (of vooral: fac_v_my_res_rooms wil ik kwijt)
|
|
// Met 5.3.1 geen tijd meer ervoor..
|
|
fac_v_my_res_ruimte_write: // 'view' die je rechten op een res_ruimte oplevert
|
|
"(SELECT rr.res_ruimte_key,"
|
|
+ " fr.prs_perslid_key,"
|
|
+ " g.fac_functie_key,"
|
|
+ " rr.res_ruimte_verwijder"
|
|
+ " FROM res_ruimte rr,"
|
|
+ " fac_v_my_res_rooms fr,"
|
|
+ " fac_v_webgebruiker g"
|
|
+ " WHERE rr.res_ruimte_key = fr.res_ruimte_key"
|
|
+ " AND fr.prs_perslid_key = g.prs_perslid_key"
|
|
+ " AND niveau = g.fac_gebruiker_alg_level_write"
|
|
+ " AND rr.res_discipline_key = g.ins_discipline_key"
|
|
+ " AND g.fac_gebruiker_alg_level_write < 9)",
|
|
|
|
insert_reservering: function _insert_reservering(params)
|
|
{
|
|
// Placeholder, invulling te geven en te gebruiken vanuit de API en dergelijke
|
|
// fields = ...
|
|
/*
|
|
var resIns = buildInsert("res_reservering", resfields);
|
|
var reservering_key = resIns.sequences["res_reservering_key"];
|
|
var volgnr = 1;
|
|
Oracle.Execute(resIns.sql);
|
|
*/
|
|
},
|
|
|
|
get_rooms_for_planbord: function _get_rooms_for_planbord(params)
|
|
{
|
|
if (params.alg_locatie_plaats)
|
|
{
|
|
params.loc_key_arr = [-1]; // Voorkom dat we 'alles' krijgen bij niet gevonden plaats
|
|
var sql = "SELECT alg_locatie_key"
|
|
+ " FROM alg_v_aanweziglocatie"
|
|
+ " WHERE UPPER(alg_locatie_plaats) LIKE " + safe.quoted_sql_wild(params.alg_locatie_plaats + '%');
|
|
var oRs = Oracle.Execute(sql);
|
|
while (!oRs.Eof)
|
|
{
|
|
params.loc_key_arr.push(oRs("alg_locatie_key").Value);
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.Close();
|
|
}
|
|
params.ruimtecat = params.ruimtecat || [];
|
|
params.loc_key_arr = params.loc_key_arr || [];
|
|
var sql_loc_from = "";
|
|
var sql_loc_where = "";
|
|
if (params.rui > 0)
|
|
sql_loc_from = ", alg_ruimte r";
|
|
else if (params.dist < 0 && params.reg > 0)
|
|
sql_loc_from = ", alg_district d";
|
|
|
|
if ((params.res_ruimte_key > 0) && (params.loc > 0))
|
|
sql_loc_where = " AND fr.res_ruimte_key = " + params.res_ruimte_key;
|
|
if (params.rui > 0)
|
|
sql_loc_where = " AND r.alg_verdieping_key = rg.alg_verdieping_key"
|
|
+ " AND r.alg_ruimte_key = " + params.rui;
|
|
else if (params.ver > 0)
|
|
sql_loc_where = " AND rg.alg_verdieping_key = " + params.ver;
|
|
else if (params.bld > 0)
|
|
sql_loc_where = " AND rg.alg_gebouw_key = " + params.bld;
|
|
else if (params.loc > 0)
|
|
sql_loc_where = " AND rg.alg_locatie_key = " + params.loc;
|
|
else if (params.loc_key_arr.length)
|
|
sql_loc_where = " AND rg.alg_locatie_key IN (" + params.loc_key_arr.join(", ") + ")";
|
|
else if (params.dist > 0)
|
|
sql_loc_where = " AND l.alg_district_key = " + params.dist;
|
|
else if (params.reg > 0)
|
|
sql_loc_where = " AND l.alg_district_key = d.alg_district_key"
|
|
+ " AND d.alg_regio_key = " + params.reg;
|
|
|
|
var sati_sql = " (SELECT AVG(res_rsv_ruimte_satisfaction) "
|
|
+ " FROM res_rsv_ruimte rrr, res_ruimte_opstelling rro"
|
|
+ " WHERE rrr.res_ruimte_opstel_key = rro.res_ruimte_opstel_key"
|
|
+ " AND rro.res_ruimte_key = fr.res_ruimte_key"
|
|
+ " AND res_rsv_ruimte_van > SYSDATE - 180)";
|
|
|
|
var ora_date1 = params.res_van.beginToSQL();
|
|
// RES_RUIMTE informatie
|
|
// Deze query bepaalt het aantal regels in het planbord
|
|
var sql = "SELECT DISTINCT fr.res_ruimte_key"
|
|
+ " , " + lcl.xsqla('rg.res_ruimte_nr', 'rg.res_ruimte_key')
|
|
+ " , rg.res_ruimte_volgnummer"
|
|
+ " , bmin"
|
|
+ " , bmax"
|
|
+ " , alg_locatie_omschrijving"
|
|
+ " , alg_locatie_plaats"
|
|
+ " , alg_locatie_code"
|
|
+ " , " + lcl.xsqla('fr.res_ruimte_omschrijving', 'fr.res_ruimte_key')
|
|
+ " , fr.res_ruimte_begintijd"
|
|
+ " , fr.res_ruimte_eindtijd"
|
|
+ " , fr.res_ruimte_begintijdblok"
|
|
+ " , fr.res_ruimte_eindtijdblok"
|
|
+ " , fr.res_ruimte_image"
|
|
+ " , res_disc_params_preposttime"
|
|
+ " , fr.res_ruimte_prijs"
|
|
+ " ," + (params.with_satisfaction?sati_sql:"0") + " satisfaction"
|
|
+ " , rg.res_discipline_key"
|
|
+ " , fr.res_ruimte_extern_id"
|
|
+ " FROM alg_locatie l"
|
|
+ " , alg_gebouw g"
|
|
+ " , alg_srtgebouw sg"
|
|
+ " , opstel_bez"
|
|
+ " , res_ruimte fr"
|
|
+ " , res_v_res_ruimte_gegevens rg"
|
|
+ " , res_disc_params"
|
|
+ sql_loc_from
|
|
+ " WHERE rg.alg_locatie_key = l.alg_locatie_key "
|
|
+ " AND rg.alg_gebouw_key = g.alg_gebouw_key "
|
|
+ " AND sg.alg_srtgebouw_key(+) = g.alg_srtgebouw_key"
|
|
+ " AND sg.alg_srtgebouw_passief IS NULL"
|
|
+ " AND fr.res_ruimte_key = opstel_bez.res_ruimte_key"
|
|
+ " AND fr.res_ruimte_key = rg.res_ruimte_key"
|
|
+ " AND fr.res_ruimte_verwijder IS NULL"
|
|
+ " AND res_disc_params.res_ins_discipline_key = rg.res_discipline_key "
|
|
+ " AND (fr.res_ruimte_vervaldatum IS NULL OR fr.res_ruimte_vervaldatum > " + ora_date1 + ")"
|
|
+ sql_loc_where;
|
|
|
|
// Altijd 3D Rechten ook meenemen
|
|
sql = discxalg3d (sql,
|
|
"fr.res_discipline_key",
|
|
"rg.alg_regio_key",
|
|
"rg.alg_district_key",
|
|
"rg.alg_locatie_key",
|
|
"rg.alg_gebouw_key",
|
|
"rg.alg_verdieping_key",
|
|
"rg.alg_ruimte_key",
|
|
params.authparams.autfunction,
|
|
params.ruimtecat.length?params.ruimtecat.join(",") : '',
|
|
params.forSelectRoom, // forWrite
|
|
3); // minlevel 3: alleen ruimte catalogie beschouwen
|
|
|
|
sql = "WITH opstel_bez"
|
|
+ " AS (SELECT res_ruimte_key"
|
|
+ " , MIN (res_ruimte_opstel_bezoekers) bmin"
|
|
+ " , MAX (res_ruimte_opstel_bezoekers) bmax"
|
|
+ " FROM res_ruimte_opstelling"
|
|
+ " WHERE res_ruimte_opstel_verwijder IS NULL"
|
|
+ " GROUP BY res_ruimte_key)"
|
|
+ " SELECT * FROM (" + sql + ") rg WHERE"; // 1 = 1;
|
|
|
|
sql += (params.init_res_ruimte_key ? " (rg.res_ruimte_key = " + params.init_res_ruimte_key + ") OR" : "") + " (1 = 1"
|
|
+ (params.ruimtecat.length ? " AND res_discipline_key IN (" + params.ruimtecat.join(",") + ")" : "")
|
|
+ ((params.res_ruimte_key && !params.forSelectRoom)? " AND rg.res_ruimte_key = " + params.res_ruimte_key : "")
|
|
+ ((params.vis)? " AND bmax >= " + params.vis : "")
|
|
+ ((params.activiteit_key)
|
|
? " AND EXISTS (SELECT res_activiteit_key FROM res_activiteitdiscipline rad"
|
|
+ " WHERE rad.res_discipline_key = rg.res_discipline_key"
|
|
+ " AND rad.res_activiteit_key = " + params.activiteit_key + ")"
|
|
: "")
|
|
+ ((!params.activiteit_key && params.srtact > 0)
|
|
? " AND EXISTS (SELECT ra.res_activiteit_key"
|
|
+ " FROM res_activiteitdiscipline rad"
|
|
+ " , res_activiteit ra"
|
|
+ " WHERE rad.res_discipline_key = rg.res_discipline_key"
|
|
+ " AND rad.res_activiteit_key = ra.res_activiteit_key"
|
|
+ " AND ra.res_srtactiviteit_key = " + params.srtact + ")"
|
|
: "")
|
|
+ ")"
|
|
+ " ORDER BY "
|
|
+ " rg.res_ruimte_volgnummer," // Sorteren op volgnummer gaat voor, dan afhankelijk van instelling res_room_order:
|
|
+ (S("res_room_order") == 0
|
|
? (params.forSelectRoom? " bmin," : "") + lcl.xsql('rg.res_ruimte_nr', 'rg.res_ruimte_key') + ", alg_locatie_omschrijving"// Eerst sorteren op capaciteit
|
|
: lcl.xsql('rg.res_ruimte_nr', 'rg.res_ruimte_key') + ", alg_locatie_omschrijving" + (params.forSelectRoom? ", bmin" : "")); // Eerst sorteren op ruimte nummer
|
|
return sql;
|
|
},
|
|
|
|
get_deepurl: function (params)
|
|
{
|
|
if (params.mobile)
|
|
{
|
|
var deepurl = HTTP.urlzelf() + "/pda/reservering.asp";
|
|
}
|
|
else
|
|
{
|
|
var deepurl = HTTP.urlzelf() + "/?fac_id=" + customerId + "&u=reservering";
|
|
}
|
|
return deepurl;
|
|
},
|
|
|
|
// Levert voldoende informatie op voor een planbord voor een bepaalde periode
|
|
// In het bijzonder: alle mogelijke zalen en de bestaande bezetting
|
|
// Let op: S("res_t1") en S("res_t2") kunnen tijdelijk gewijzigd zijn
|
|
plan_rooms_info: function _plan_rooms_info (params)
|
|
{
|
|
var sql = res.get_rooms_for_planbord(params);
|
|
|
|
// Verklein de setting S("res_t1") en S("res_t2") indien geen enkele ruimte zo ruim mag.
|
|
var sqlminmax = "SELECT MIN(coalesce(res_ruimte_begintijd," + S("res_t1") + ")) tmin"
|
|
+ " , MAX(coalesce(res_ruimte_eindtijd, " + S("res_t2") + ")) tmax"
|
|
+ " FROM (" + sql + ")";
|
|
var oRs = Oracle.Execute(sqlminmax);
|
|
settings.overrule_setting("res_t1", oRs("tmin").Value || S("res_t1"));
|
|
settings.overrule_setting("res_t2", oRs("tmax").Value || S("res_t2"));
|
|
|
|
// Extra wrapper omdat ADO anders komt met 'Operation not allowed when object is closed'
|
|
// Blijkbaar snapt die de WITH constructie vooraan niet zo
|
|
sql = "SELECT * FROM (" + sql + ")"
|
|
oRs = Oracle.Execute(sql);
|
|
|
|
var all_rooms = []; // Hierin bouwen alle ruimtes op
|
|
if (params.get_deepurl)
|
|
{ // Bepaal de URL waarmee straks een boeking uitgevoerd kan worden
|
|
var deepurl = res.get_deepurl(params);
|
|
}
|
|
|
|
while (!oRs.eof)
|
|
{
|
|
var room = { res_ruimte_key: oRs("res_ruimte_key").Value,
|
|
res_ruimte_nr : oRs("res_ruimte_nr").Value,
|
|
bMin : oRs("bMin").Value,
|
|
bMax : oRs("bMax").Value,
|
|
prepost_time : oRs("res_disc_params_preposttime").Value,
|
|
begintijd : oRs("res_ruimte_begintijd").Value || S("res_t1"),
|
|
eindtijd : oRs("res_ruimte_eindtijd").Value || S("res_t2"),
|
|
begintijdblok : oRs("res_ruimte_begintijdblok").Value,
|
|
eindtijdblok : oRs("res_ruimte_eindtijdblok").Value,
|
|
image : oRs("res_ruimte_image").Value,
|
|
omschrijving : oRs("res_ruimte_omschrijving").Value,
|
|
locatie : oRs("alg_locatie_omschrijving").Value,
|
|
plaats : oRs("alg_locatie_plaats").Value,
|
|
satisfaction : oRs("satisfaction").Value,
|
|
prijs : oRs("res_ruimte_prijs").Value,
|
|
extern_id : oRs("res_ruimte_extern_id").Value
|
|
};
|
|
if (room.begintijd < S("res_t1")) room.begintijd = S("res_t1");
|
|
if (room.eindtijd > S("res_t2")) room.eindtijd = S("res_t2");
|
|
if (room.begintijd > room.eindtijd) room.begintijd = room.eindtijd;
|
|
if (params.get_deepurl)
|
|
{
|
|
room.deepurl = deepurl;
|
|
if (oRs("res_ruimte_image").Value)
|
|
room.image_url = HTTP.urlzelfnoroot() + S("res_image_path") + oRs("res_ruimte_image").Value;
|
|
}
|
|
else
|
|
{
|
|
if (oRs("res_ruimte_image").Value)
|
|
room.image_url = S("res_image_path") + oRs("res_ruimte_image").Value;
|
|
}
|
|
all_rooms.push(room);
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.Close();
|
|
__Log("done plan_rooms_info met {0} ruimtes.".format(all_rooms.length));
|
|
return all_rooms;
|
|
},
|
|
//
|
|
// Bestaande reserveringen
|
|
//
|
|
// Voor de API zetten we params.anonymous zodat minimale informatie wordt opgeleverd
|
|
// TODO: Of op basis van fe-geheim?
|
|
plan_bezet_info: function _plan_bezet_info (params)
|
|
{
|
|
// Pas allerlei filtering toe om te zorgen dat we niet te veel ophalen
|
|
// Dat is slecht voor de performance en (API) misschien geheim
|
|
var room_sql = res.get_rooms_for_planbord(params); // Deze heeft ook autorisatie in zich
|
|
var deepurl = res.get_deepurl(params);
|
|
|
|
// Determine all existing reservations and store them in an array 'existing_res'
|
|
var sql = "SELECT DISTINCT rv.res_rsv_ruimte_van"
|
|
+ " , rv.res_rsv_ruimte_tot"
|
|
+ " , rv.res_rsv_ruimte_dirtlevel"
|
|
+ " , res_ruimte_key_1"
|
|
+ " , rv.res_status_fo_key"
|
|
+ " , rv.res_rsv_ruimte_flag"
|
|
+ " , rv.res_reservering_key"
|
|
+ (params.anonymous?", res_srtactiviteit_prefix || TO_CHAR (rv.res_reservering_key) || '/' || rv.res_rsv_ruimte_volgnr resid":"")
|
|
+ " , res_rsv_ruimte_volgnr"
|
|
+ " , rv.res_rsv_ruimte_key"
|
|
+ " , res_ruimte_key_2"
|
|
+ " , rv.res_rsv_ruimte_host_key"
|
|
+ " , rv.res_rsv_ruimte_contact_key"
|
|
+ " , rv.res_rsv_ruimte_omschrijving"
|
|
+ " , (SELECT count(1) FROM res_v_aanwezigrsv_artikel rra"
|
|
+ " WHERE rra.res_rsv_ruimte_key = rv.res_rsv_ruimte_key) aantalA" // dat de CV dirty kan zijn negeren we.
|
|
+ " , (SELECT count(1) FROM res_v_aanwezigrsv_deel rrd"
|
|
+ " WHERE rrd.res_rsv_ruimte_key = rv.res_rsv_ruimte_key"
|
|
+ " AND rrd.bez_bezoekers_key IS NULL) aantalD" // Uitsluiten parkeerplaatsen met een bez_bezoekers_key.
|
|
+ " FROM res_v_aanwezigrsv_ruimte rv"
|
|
+ " , res_ruimte_opstelling ro"
|
|
+ (params.anonymous?", res_activiteit ra, res_srtactiviteit rsa":"")
|
|
// ///////Koppelzalen meenemen want daardoor kunnen we ook bezet raken
|
|
+ " , ( SELECT DISTINCT r1.res_ruimte_key res_ruimte_key_1, r2.res_ruimte_key res_ruimte_key_2, r2.alg_ruimte_key "
|
|
+ " FROM res_alg_ruimte r1, res_alg_ruimte r2 "
|
|
+ " WHERE r1.alg_ruimte_key = r2.alg_ruimte_key"
|
|
+ " AND r1.res_alg_ruimte_verwijder IS NULL"
|
|
+ " AND r2.res_alg_ruimte_verwijder IS NULL"
|
|
+ " ) X"
|
|
+ " WHERE rv.res_rsv_ruimte_van between " + params.res_van.toSQL() + " AND " + params.res_tot.endToSQL()
|
|
+ " AND rv.res_ruimte_opstel_key = ro.res_ruimte_opstel_key"
|
|
+ " AND X.res_ruimte_key_2 = ro.res_ruimte_key"
|
|
+ (params.anonymous
|
|
? " AND rv.res_activiteit_key = ra.res_activiteit_key"
|
|
+ " AND ra.res_srtactiviteit_key = rsa.res_srtactiviteit_key"
|
|
: "")
|
|
+ (params.res_ruimte_key && !params.forSelectRoom
|
|
? " AND res_ruimte_key_1=" + params.res_ruimte_key
|
|
: "")
|
|
+ " AND res_ruimte_key_1 IN (SELECT res_ruimte_key FROM (" + room_sql + "))"
|
|
+ " ORDER BY res_ruimte_key_1"
|
|
+ " , (res_rsv_ruimte_tot - res_rsv_ruimte_van) DESC" // langste reserveringen eerst/onderop
|
|
+ " , rv.res_rsv_ruimte_dirtlevel ASC"
|
|
|
|
var existing_res = {};
|
|
var nnres = 0;
|
|
var nnroom = 0;
|
|
var oRs = Oracle.Execute(sql);
|
|
while (!oRs.eof)
|
|
{
|
|
nnres ++;
|
|
var res_ruimte_key = oRs("res_ruimte_key_1").Value;
|
|
if (!existing_res[res_ruimte_key])
|
|
{
|
|
// if (S("res_plan_max_bezet") > 0 && nnres > S("res_plan_max_bezet"))
|
|
// abort_with_warning("Dit kost veel te veel geheugen");
|
|
// 105282 bezettingen was ongeveer 280 MB geheugen
|
|
existing_res[res_ruimte_key] = [];
|
|
nnroom++;
|
|
}
|
|
// existing_res kan bij grotere periodes heel groot worden (100.000+ records)
|
|
// Daarom is data zwaar geoptimaliseerd: geen properties zetten die 0/null zijn
|
|
var data = { res_van : new Date(oRs("res_rsv_ruimte_van").Value),
|
|
res_tot : new Date(oRs("res_rsv_ruimte_tot").Value),
|
|
fo_status : oRs("res_status_fo_key").Value
|
|
};
|
|
if (oRs("res_rsv_ruimte_flag").Value)
|
|
data.flag_status = oRs("res_rsv_ruimte_flag").Value;
|
|
if (oRs("res_ruimte_key_1").Value != oRs("res_ruimte_key_2").Value)
|
|
data.na_koppel = 1;
|
|
if (oRs("res_rsv_ruimte_dirtlevel").Value)
|
|
data.dirtlevel = oRs("res_rsv_ruimte_dirtlevel").Value;
|
|
|
|
if (params.anonymous && data.dirtlevel > 0)
|
|
{
|
|
oRs.MoveNext();
|
|
continue; // die zijn niet nodig
|
|
}
|
|
|
|
if (!params.anonymous)
|
|
{
|
|
data.rsv_ruimte_key = oRs("res_rsv_ruimte_key").Value;
|
|
data.host_key = oRs("res_rsv_ruimte_host_key").Value;
|
|
if (oRs("res_rsv_ruimte_contact_key").Value != data.host_key)
|
|
data.contact_key = oRs("res_rsv_ruimte_contact_key").Value;
|
|
if (oRs("aantalA").Value)
|
|
data.aantalA = oRs("aantalA").Value;
|
|
if (oRs("aantalD").Value)
|
|
data.aantalD = oRs("aantalD").Value;
|
|
}
|
|
else if (oRs("res_rsv_ruimte_host_key").Value == params.prs_key || oRs("res_rsv_ruimte_contact_key").Value == params.prs_key)
|
|
{
|
|
// Tooltip via res_load_title_rsv.asp is te complex, zou een api zijn
|
|
data.extern = { res_nr : oRs("resid").Value,
|
|
omschrijving : oRs("res_rsv_ruimte_omschrijving").Value,
|
|
deepurl : deepurl + "&k=" + oRs("res_rsv_ruimte_key").Value
|
|
}
|
|
}
|
|
existing_res[res_ruimte_key].push(data);
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.close();
|
|
__Log("done plan_bezet_info met {0} bezettingen voor {1} ruimtes.".format(nnres, nnroom));
|
|
|
|
return existing_res;
|
|
},
|
|
//
|
|
// Bestaande res_deel reserveringen
|
|
//
|
|
//
|
|
plan_deel_bezet_info: function _plan_deel_bezet_info (params)
|
|
{
|
|
var existing_res = {};
|
|
|
|
var ora_date1 = params.res_van.beginToSQL();
|
|
var ora_date2 = params.res_tot.endToSQL();
|
|
var disc_key = params.disc_key; // Nog verplicht
|
|
// var res_ruimte_key = params.res_ruimte_key||-1;
|
|
|
|
// Determine all existing reserved objects and store them in an array 'existing_res'
|
|
// Via gewone reserveringen, die hebben res_rsv_ruimte_key
|
|
sql = "SELECT rrd.res_rsv_deel_van"
|
|
+ " , rrd.res_rsv_deel_tot"
|
|
+ " , rd.res_deel_key"
|
|
+ " , rr.res_status_fo_key"
|
|
+ " , rr.res_rsv_ruimte_flag"
|
|
+ " , rrd.res_rsv_deel_key"
|
|
+ " , rrd.res_rsv_deel_dirtlevel"
|
|
+ " , rrd.res_rsv_ruimte_key"
|
|
+ " , rr.alg_ruimte_key"
|
|
+ " , rr.res_rsv_ruimte_host_key "
|
|
+ " , rr.res_rsv_ruimte_contact_key "
|
|
+ " , -1 bez_bezoekers_key"
|
|
+ " , rrd.res_status_bo_key"
|
|
+ " , rd.res_ins_deel_key"
|
|
+ " , rd.res_discipline_key"
|
|
+ " , 1 type"
|
|
+ " , rr.res_reservering_key"
|
|
+ " FROM res_v_aanwezigrsv_ruimte rr"
|
|
+ " , res_v_aanwezigdeel rd"
|
|
+ " , res_v_aanwezigrsv_deel rrd"
|
|
+ " WHERE rrd.res_rsv_deel_tot >= " + ora_date1
|
|
+ " AND rrd.res_rsv_deel_van <= " + ora_date2
|
|
+ " AND rrd.res_deel_key = rd.res_deel_key"
|
|
+ " AND rrd.res_rsv_ruimte_key = rr.res_rsv_ruimte_key"
|
|
+ " AND rd.res_discipline_key = " + disc_key
|
|
// Gereserveerde objecten uit andere disciplines maar hetzelfde object
|
|
// (zelfde ins_deel) als object in gekozen discipline
|
|
// JGL: Dit is vergelijkbaar met koppelzalen bij ruimtes. De code daarvan heeft lost het
|
|
// anders op met na_koppel. Ooit hier herzien?
|
|
+ " UNION "
|
|
+ "SELECT DISTINCT rrd.res_rsv_deel_van"
|
|
+ " , rrd.res_rsv_deel_tot"
|
|
+ " , rd.res_deel_key"
|
|
+ " , rr.res_status_fo_key"
|
|
+ " , rr.res_rsv_ruimte_flag"
|
|
+ " , rrd.res_rsv_deel_key"
|
|
+ " , rrd.res_rsv_deel_dirtlevel"
|
|
+ " , rrd.res_rsv_ruimte_key"
|
|
+ " , rr.alg_ruimte_key"
|
|
+ " , rr.res_rsv_ruimte_host_key "
|
|
+ " , rr.res_rsv_ruimte_contact_key "
|
|
+ " , -1 bez_bezoekers_key"
|
|
+ " , rrd.res_status_bo_key"
|
|
+ " , rd.res_ins_deel_key"
|
|
+ " , rd.res_discipline_key"
|
|
+ " , 2 type"
|
|
+ " , rr.res_reservering_key"
|
|
+ " FROM res_v_aanwezigrsv_ruimte rr"
|
|
+ ", res_v_aanwezigdeel rd"
|
|
+ ", res_v_aanwezigrsv_deel rrd"
|
|
+ ", res_v_aanwezigdeel rd2"
|
|
+ " WHERE rrd.res_rsv_deel_tot >= " + ora_date1
|
|
+ " AND rrd.res_rsv_deel_van <= " + ora_date2
|
|
+ " AND rrd.res_deel_key = rd.res_deel_key"
|
|
+ " AND rrd.res_rsv_ruimte_key = rr.res_rsv_ruimte_key"
|
|
+ " AND rd.res_discipline_key != " + disc_key
|
|
+ " AND rd.res_ins_deel_key = rd2.res_ins_deel_key"
|
|
+ " AND rd2.res_discipline_key = " + disc_key;
|
|
|
|
// MGE: Als S("vis_parking_key") een waarde heeft dan wordt de discipline niet getoond
|
|
// door toevoeging van AND aan querie in res_edit_objcat.asp "(AND dis.ins_discipline_key != " + S("vis_parking_key"))
|
|
// Dan is de dicipline parkeerplaatsen dus nooit aanwezig is volgende if
|
|
// voorwaarde dus nooit true omdat disc_key van parkeerplaaten nooit voorkomt.
|
|
// Lijkt me dat de volgende if dus verwijderd kan worden??
|
|
if (disc_key == S("vis_parking_key"))
|
|
sql = sql + " UNION ALL " //Die via afspraak/bezoekers (parkeerplaatsen)
|
|
+ "SELECT rrd.res_rsv_deel_van"
|
|
+ " , rrd.res_rsv_deel_tot"
|
|
+ " , rd.res_deel_key"
|
|
+ " , 2 res_status_fo_key" // altijd definitief
|
|
+ " , 0 res_rsv_ruimte_flag" // hier niet van toepassing
|
|
+ " , rrd.res_rsv_deel_key"
|
|
+ " , rrd.res_rsv_deel_dirtlevel"
|
|
+ " , rrd.res_rsv_ruimte_key"
|
|
+ " , -1 alg_ruimte_key"
|
|
+ " , -1 res_rsv_ruimte_host_key "
|
|
+ " , -1 res_rsv_ruimte_contact_key "
|
|
+ " , rrd.bez_bezoekers_key"
|
|
+ " , rrd.res_status_bo_key"
|
|
+ " , rd.res_ins_deel_key"
|
|
+ " , rd.res_discipline_key"
|
|
+ " , 1 type"
|
|
+ " , 0 res_reservering_key"
|
|
+ " FROM res_v_aanwezigdeel rd"
|
|
+ " , res_v_aanwezigrsv_deel rrd"
|
|
+ " , bez_bezoekers b"
|
|
+ " , bez_afspraak a"
|
|
+ " WHERE rrd.res_rsv_deel_tot >= " + ora_date1
|
|
+ " AND rrd.res_rsv_deel_van <= " + ora_date2
|
|
+ " AND rrd.res_deel_key = rd.res_deel_key"
|
|
+ " AND rrd.bez_bezoekers_key = b.bez_bezoekers_key"
|
|
+ " AND b.bez_afspraak_key = a.bez_afspraak_key"
|
|
+ " AND rrd.res_rsv_ruimte_key IS NULL"
|
|
+ " AND rd.res_discipline_key = " + disc_key
|
|
|
|
sql += " ORDER BY type"
|
|
var oRs = Oracle.Execute(sql);
|
|
while (!oRs.eof)
|
|
{
|
|
var ins_d_key = oRs("res_ins_deel_key").Value;
|
|
|
|
if (!existing_res[ins_d_key]) existing_res[ins_d_key] = new Array();
|
|
|
|
// In het bijzondere geval als initeel meerdere res_delen van hetzelfde ins_deel worden geselecteerd kunnen meerdere regels voor een res_deel worden opgeleverd.
|
|
var doubledeel = false;
|
|
if (oRs("type").Value == 2) {
|
|
for (var i = 0; i < existing_res[ins_d_key].length; i++)
|
|
{ // Controleer op dezelfde rsv_ruimte_key. Dan te maken met dezelfde deelreservering
|
|
//__Log ("Checking ins/res_deel " + ins_d_key+"/"+oRs("res_deel_key").Value + "("+i+"): "+ existing_res[ins_d_key][i].rsv_ruimte_key + " vs. " +oRs("res_rsv_ruimte_key").Value);
|
|
if (existing_res[ins_d_key][i].rsv_ruimte_key == oRs("res_rsv_ruimte_key").Value)
|
|
{ // Er was al een res_deel van hetzelfde ins_deel aanwezig in deze lijst. Deze bevat al de juiste waarden.
|
|
// __Log(".. double");
|
|
doubledeel = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!doubledeel)
|
|
{
|
|
existing_res[ins_d_key].push({res_deel_key: oRs("res_deel_key").Value,
|
|
res_van: new Date(oRs("res_rsv_deel_van").Value),
|
|
res_tot: new Date(oRs("res_rsv_deel_tot").Value),
|
|
rsv_ruimte_key: oRs("res_rsv_ruimte_key").Value,
|
|
status_fo_key: oRs("res_status_fo_key").Value,
|
|
dirtlevel: oRs("res_rsv_deel_dirtlevel").Value,
|
|
rsv_deel_key: oRs("res_rsv_deel_key").Value,
|
|
alg_ruimte_key: oRs("alg_ruimte_key").Value,
|
|
bez_key: oRs("bez_bezoekers_key").Value,
|
|
host_key: oRs("res_rsv_ruimte_host_key").Value,
|
|
contact_key: oRs("res_rsv_ruimte_contact_key").Value,
|
|
res_status: oRs("res_status_bo_key").Value,
|
|
res_flag: oRs("res_rsv_ruimte_flag").Value || 0,
|
|
res_key: oRs("res_reservering_key").Value
|
|
});
|
|
}
|
|
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.close();
|
|
|
|
return existing_res;
|
|
},
|
|
|
|
// Wordt bij Share&Meet via API opgevraagd
|
|
user_lopend_info: function _user_lopend_info (params)
|
|
{
|
|
var showall = false; // TODO?
|
|
// ....
|
|
var sql = "SELECT rr.res_rsv_ruimte_host_key prs_perslid_key"
|
|
+ " , res_srtactiviteit_prefix || TO_CHAR (rr.res_reservering_key) || '/' || rr.res_rsv_ruimte_volgnr item"
|
|
+ " , rr.res_rsv_ruimte_key item_key"
|
|
+ " , 'reservering' xmlnode"
|
|
+ " , rr.res_rsv_ruimte_van datum"
|
|
+ " , COALESCE (rr.res_rsv_ruimte_omschrijving, " + lcl.xsql('ra.res_activiteit_omschrijving', 'res_activiteit_key') + ") detail"
|
|
+ " , ' ' status"
|
|
+ " , res_rsv_ruimte_satisfaction satisfaction"
|
|
+ " , res_rsv_ruimte_satisfaction_op satisfaction_op"
|
|
+ " , DECODE (res_rsv_ruimte_dirtlevel, 0, rr.res_status_fo_key, -1) status_key"
|
|
+ " , rr.res_status_bo_key bo_status_key"
|
|
//+ sqlTracking("rr.res_rsv_ruimte_key","reservering")
|
|
+ " FROM res_v_aanwezigrsv_ruimte rr"
|
|
+ " , res_activiteit ra"
|
|
+ " , res_srtactiviteit rsa"
|
|
+ " , fac_tracking tr"
|
|
+ " , fac_srtnotificatie str"
|
|
+ " WHERE rr.res_activiteit_key = ra.res_activiteit_key"
|
|
+ " AND ra.res_srtactiviteit_key = rsa.res_srtactiviteit_key"
|
|
+ " AND ( ( rr.res_status_bo_key IN (4, 3, 2, 7))"
|
|
+ " OR ( rr.res_status_bo_key IN (5, 6) "
|
|
+ " AND tr.fac_tracking_datum > SYSDATE - " + S("facilities_flike_past")
|
|
+ " AND str.fac_srtnotificatie_code = 'RESAFM')"
|
|
+ " OR ( rr.res_status_bo_key NOT IN (5, 6) "
|
|
+ " AND rr.res_rsv_ruimte_tot > SYSDATE - " + S("facilities_flike_past") + ")"
|
|
+ " )"
|
|
+ " AND rr.res_rsv_ruimte_key = tr.fac_tracking_refkey(+)"
|
|
+ " AND tr.fac_srtnotificatie_key = str.fac_srtnotificatie_key(+)"
|
|
+ (!showall
|
|
? " AND (rr.res_rsv_ruimte_van BETWEEN SYSDATE - " + S("facilitiespast_res") + " AND SYSDATE + " + S("facilitiesfuture_res") + " OR rr.res_rsv_ruimte_van IS NULL)"
|
|
: "")
|
|
+ " UNION "
|
|
+ "SELECT rr.res_rsv_ruimte_contact_key prs_perslid_key"
|
|
+ " , res_srtactiviteit_prefix || TO_CHAR (rr.res_reservering_key) || '/' || rr.res_rsv_ruimte_volgnr item"
|
|
+ " , rr.res_rsv_ruimte_key"
|
|
+ " , 'reservering' xmlnode"
|
|
+ " , rr.res_rsv_ruimte_van datum"
|
|
+ " , COALESCE (rr.res_rsv_ruimte_omschrijving, " + lcl.xsql('ra.res_activiteit_omschrijving', 'res_activiteit_key') + ") detail"
|
|
+ " , ' ' status"
|
|
+ " , res_rsv_ruimte_satisfaction satisfaction"
|
|
+ " , res_rsv_ruimte_satisfaction_op satisfaction_op"
|
|
+ " , DECODE (res_rsv_ruimte_dirtlevel, 0, rr.res_status_fo_key, -1) status_key"
|
|
+ " , rr.res_status_bo_key bo_status_key"
|
|
//+ sqlTracking("rr.res_rsv_ruimte_key","reservering")
|
|
+ " FROM res_v_aanwezigrsv_ruimte rr"
|
|
+ " , res_activiteit ra"
|
|
+ " , res_srtactiviteit rsa"
|
|
+ " WHERE rr.res_activiteit_key = ra.res_activiteit_key"
|
|
+ " AND ra.res_srtactiviteit_key = rsa.res_srtactiviteit_key"
|
|
+ " AND rr.res_status_bo_key IN (4, 3, 2, 7)"
|
|
+ (!showall
|
|
? " AND (rr.res_rsv_ruimte_van BETWEEN SYSDATE - " + S("facilitiespast_res") + " AND SYSDATE + " + S("facilitiesfuture_res") + " OR rr.res_rsv_ruimte_van IS NULL)"
|
|
: "");
|
|
|
|
var sqln = "SELECT prs_perslid_key"
|
|
+ " , item"
|
|
+ " , item_key"
|
|
+ " , xmlnode"
|
|
+ " , datum"
|
|
+ " , detail"
|
|
+ " , status"
|
|
+ " , satisfaction"
|
|
+ " , satisfaction_op"
|
|
+ " , status_key"
|
|
// + " , recentdatum"
|
|
+ " , bo_status_key"
|
|
+ " FROM (" + sql + ")"
|
|
+ " WHERE prs_perslid_key = " + params.prs_key
|
|
// + module_filter
|
|
+ " ORDER by datum";
|
|
var oRs = Oracle.Execute(sqln);
|
|
var user_res = Oracle.rs2hash(oRs);
|
|
oRs.Close();
|
|
|
|
// Bepaal de URL waar user straks op kan klikken
|
|
if (params.mobile)
|
|
var deepurl = HTTP.urlzelf() + "/appl/pda/reservering.asp?fac_id=" + customerId + "&rsv_ruimte_key=";
|
|
else
|
|
var deepurl = HTTP.urlzelf() + "/?fac_id=" + customerId + "&u=reservering&k=" ;
|
|
for (var r in user_res)
|
|
{
|
|
user_res[r].deepurl = deepurl + user_res[r].item_key
|
|
}
|
|
|
|
return user_res;
|
|
},
|
|
getremotes_sql: function (autfunction)
|
|
{
|
|
var sql = "SELECT dis.ins_discipline_key,"
|
|
+ " "+ lcl.xsqla('dis.ins_discipline_omschrijving','dis.ins_discipline_key') +","
|
|
+ " res_disc_params_remoteurl"
|
|
+ " FROM res_v_aanwezigdiscipline dis, res_disc_params rdp"
|
|
+ " WHERE dis.ins_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND ins_discipline_min_level = 3" // Alleen nog Ruimte
|
|
+ " AND res_disc_params_remoteurl IS NOT NULL"
|
|
+ " AND dis.ins_discipline_key IN("
|
|
+ " SELECT g.ins_discipline_key FROM fac_v_webgebruiker g, fac_functie f "
|
|
+ " WHERE g.fac_functie_key = f.fac_functie_key "
|
|
+ " AND f.fac_functie_code = " + safe.quoted_sql(autfunction)
|
|
+ " AND g.fac_gebruiker_alg_level_write < 9"
|
|
+ " AND g.fac_gebruiker_prs_level_write < 9"
|
|
+ " AND g.prs_perslid_key = " + user_key + ")";
|
|
return sql;
|
|
},
|
|
anyremotes: function () // TODO: Bij veel aanroepen gaan cachen in session?
|
|
{
|
|
var sql = res.getremotes_sql("WEB_RESUSE");
|
|
var oRs = Oracle.Execute(sql);
|
|
var any = !oRs.EOF;
|
|
oRs.Close()
|
|
return any;
|
|
},
|
|
hour_px: function (width_px, nr_days)
|
|
{
|
|
var nr_hours = nr_days * (S("res_t2") - S("res_t1"));
|
|
var targethour_px = width_px / nr_hours;
|
|
var hour_px = 96;
|
|
if (targethour_px < 96) hour_px = 72;
|
|
if (targethour_px < 72) hour_px = 60;
|
|
if (targethour_px < 60) hour_px = 48;
|
|
if (targethour_px < 48) hour_px = 36;
|
|
if (targethour_px < 36) hour_px = 24;
|
|
if (targethour_px < 24) hour_px = 16;
|
|
if (targethour_px < 16) hour_px = 8;
|
|
if (targethour_px < 8) hour_px = 4;
|
|
return hour_px;
|
|
},
|
|
max_duration_r: function (act_key, disc_key, duration_hours)
|
|
{
|
|
var result = { err: false, message: "", maxhours: 0};
|
|
var sql = "SELECT rad.res_activiteit_key"
|
|
+ " , rdp.res_disc_params_maxduur"
|
|
+ " FROM res_activiteitdiscipline rad"
|
|
+ " , res_disc_params rdp"
|
|
+ " WHERE rad.res_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND rad.res_discipline_key = " + disc_key
|
|
+ " AND rad.res_activiteit_key = " + act_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
if (oRs.Eof)
|
|
{
|
|
result.message = L("lcl_res_bad_activity");
|
|
result.err = true;
|
|
}
|
|
else
|
|
{
|
|
var maxHours = oRs("res_disc_params_maxduur").Value;
|
|
// Controle op maximale tijdsduur reservering.
|
|
if ((maxHours > 0) && (maxHours < duration_hours))
|
|
{
|
|
result.message = L("lcl_res_bad_maxperiod").format(maxHours);
|
|
result.maxhours = maxHours;
|
|
result.err = true;
|
|
}
|
|
}
|
|
oRs.close();
|
|
return result;
|
|
},
|
|
max_duration_cv: function (rsv_ruimte_key, duration_hours)
|
|
{
|
|
var result = { err: false, message: "", maxhours: 0};
|
|
if (rsv_ruimte_key > 0)
|
|
{
|
|
var sql = "SELECT rdp.res_disc_params_maxduur"
|
|
+ " FROM res_rsv_artikel rsva"
|
|
+ " , res_artikel ra"
|
|
+ " , res_rsv_ruimte rsv"
|
|
+ " , res_activiteitdiscipline rad"
|
|
+ " , res_disc_params rdp"
|
|
+ " WHERE rsva.res_artikel_key = ra.res_artikel_key"
|
|
+ " AND rsva.res_rsv_ruimte_key = rsv.res_rsv_ruimte_key"
|
|
+ " AND rad.res_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND rad.res_discipline_key = ra.res_discipline_key"
|
|
+ " AND rad.res_activiteit_key = rsv.res_activiteit_key"
|
|
+ " AND rsv.res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " UNION "
|
|
+ "SELECT rdp.res_disc_params_maxduur"
|
|
+ " FROM res_rsv_deel rsvd"
|
|
+ " , res_deel rd"
|
|
+ " , res_rsv_ruimte rsv"
|
|
+ " , res_activiteitdiscipline rad"
|
|
+ " , res_disc_params rdp"
|
|
+ " WHERE rsvd.res_deel_key = rd.res_deel_key"
|
|
+ " AND rsvd.res_rsv_ruimte_key = rsv.res_rsv_ruimte_key"
|
|
+ " AND rad.res_discipline_key = rdp.res_ins_discipline_key"
|
|
+ " AND rad.res_discipline_key = rd.res_discipline_key"
|
|
+ " AND rad.res_activiteit_key = rsv.res_activiteit_key"
|
|
+ " AND rsv.res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " AND rad.res_discipline_key != " + S("vis_parking_key") // Parkeerplaatsen doen we niet moeilijk over
|
|
+ " ORDER BY 1";
|
|
var oRs = Oracle.Execute(sql);
|
|
var min_hours = 0;
|
|
while (!oRs.eof)
|
|
{
|
|
var maxHours = oRs("res_disc_params_maxduur").Value;
|
|
// Controle op maximale tijdsduur reservering.
|
|
if ((maxHours > 0) && (maxHours < duration_hours))
|
|
{
|
|
if ((min_hours == 0) || (maxHours < min_hours))
|
|
{
|
|
min_hours = maxHours;
|
|
result.message = L("lcl_res_bad_maxperiod").format(maxHours);
|
|
result.maxhours = maxHours;
|
|
result.err = true;
|
|
}
|
|
}
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.close();
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// Later nog: p_alg_ruimte_key zelf bepalen uit p_rsv_ruimte_key
|
|
/* Vier varianten
|
|
A) p_res_ruimte_key gegeven van een 'CV'. We zijn een CV reservering aan het bewerken en hebben dus een alg_ruimte
|
|
Toon alleen datgene wat gereserveerd kan worden in die ruimte
|
|
A) p_alg_ruimte_key gegeven van een 'R'. We zijn een R reservering aan het bewerken en hebben dus een res_ruimte
|
|
Toon alleen datgene wat gereserveerd kan worden in die res_ruimte
|
|
C) Geen p_rsv_ruimte_key maar wel een loc_key
|
|
Toon alleen datgene wat gereserveerd kan worden op die locatie
|
|
D) Geen p_rsv_ruimte_key en geen loc_key
|
|
Toon alleen datgene wat gereserveerd kan worden
|
|
*/
|
|
|
|
function get_res_deel_sql (params)
|
|
{
|
|
params.alg_ruimte_key = params.alg_ruimte_key || -1;
|
|
params.res_ruimte_key = params.res_ruimte_key || -1;
|
|
|
|
if (params.res_tot)
|
|
var res_tot = new Date(params.res_tot);
|
|
else
|
|
var res_tot = new Date();
|
|
if (params.rsv_ruimte_key > 0)
|
|
{
|
|
sql = "SELECT res_rsv_ruimte_tot"
|
|
+ " FROM res_rsv_ruimte"
|
|
+ " WHERE res_rsv_ruimte_key = " + params.rsv_ruimte_key;
|
|
oRs = Oracle.Execute(sql);
|
|
var res_tot = new Date(oRs("res_rsv_ruimte_tot").Value);
|
|
}
|
|
var ora_date2 = res_tot.endToSQL();
|
|
|
|
var sql1 = "SELECT " + params.select_fields
|
|
+ " FROM ins_deel d"
|
|
+ " , res_v_aanwezigdeel r"
|
|
+ " , res_disc_params rdp"
|
|
+ " , (SELECT aob.alg_regio_key, aob.alg_district_key, aob.alg_locatie_key, aob.alg_gebouw_key, aob.alg_verdieping_key, aob.alg_ruimte_key "
|
|
+ " FROM "
|
|
+ (params.res_ruimte_key > 0
|
|
? " res_v_aanwezigalg_ruimte rrr,"
|
|
: "")
|
|
+ " alg_v_onrgoed_boom aob"
|
|
+ " WHERE 1 = 1"
|
|
+ ((params.reg_key || -1) > -1
|
|
? " AND aob.alg_regio_key=" + params.reg_key
|
|
: "")
|
|
+ ((params.dist_key || -1) > -1
|
|
? " AND aob.alg_district_key=" + params.dist_key
|
|
: "")
|
|
+ ((params.loc_key || -1) > -1
|
|
? " AND aob.alg_locatie_key=" + params.loc_key
|
|
: "")
|
|
+ ((params.geb_key || -1) > -1
|
|
? " AND aob.alg_gebouw_key=" + params.geb_key
|
|
: "")
|
|
+ ((params.ver_key || -1) > -1
|
|
? " AND aob.alg_verdieping_key=" + params.ver_key
|
|
: "")
|
|
+ ((params.res_ruimte_key > 0)
|
|
? " AND res_ruimte_key = " + params.res_ruimte_key + " AND rrr.alg_ruimte_key = aob.alg_ruimte_key"
|
|
: "")
|
|
+ ((params.alg_ruimte_key > 0)
|
|
? " AND aob.alg_ruimte_key = " + params.alg_ruimte_key
|
|
: "")
|
|
+ " ) scope"
|
|
+ " , res_v_deelscope ds"
|
|
+ " WHERE r.res_ins_deel_key = d.ins_deel_key"
|
|
+ " AND rdp.res_ins_discipline_key = r.res_discipline_key"
|
|
+ (params.sdisc
|
|
? " AND r.res_discipline_key = " + params.sdisc
|
|
: "")
|
|
+ " AND COALESCE(d.ins_alg_ruimte_type_org, d.ins_alg_ruimte_type) IN ('R','T')";
|
|
|
|
sql1 += " AND "
|
|
+ " ( ds.alg_regio_key = scope.alg_regio_key"
|
|
+ " OR ds.alg_district_key = scope.alg_district_key"
|
|
+ " OR ds.alg_locatie_key = scope.alg_locatie_key"
|
|
+ " OR ds.alg_gebouw_key = scope.alg_gebouw_key"
|
|
+ " OR ds.alg_verdieping_key = scope.alg_verdieping_key"
|
|
+ " OR ds.alg_ruimte_key = scope.alg_ruimte_key"
|
|
+ " OR ds.res_deel_alg_level = -1)"
|
|
+ " AND r.res_deel_key = ds.res_deel_key"
|
|
+ " AND (r.res_deel_vervaldatum IS NULL OR r.res_deel_vervaldatum > " + ora_date2 + ")"
|
|
|
|
if (params.res_ruimte_key < 0 && (params.alg_ruimte_key < 0))
|
|
{ // Locatie scope of nog groter. Rechten ook meenemen
|
|
sql1 = discxalg3d (sql1,
|
|
"r.RES_DISCIPLINE_KEY",
|
|
"scope.alg_regio_key",
|
|
"scope.alg_district_key",
|
|
"scope.alg_locatie_key",
|
|
"scope.alg_gebouw_key",
|
|
"scope.alg_verdieping_key",
|
|
"scope.alg_ruimte_key",
|
|
params.autfunction,
|
|
typeof params.sdisc == "number"? params.sdisc : '');
|
|
}
|
|
sql1 += (params.group_by || "");
|
|
return sql1;
|
|
}
|
|
|
|
function planbordTooltipShowing(res_rsv_ruimte_key)
|
|
{
|
|
var tonen = false;
|
|
var disc = null;
|
|
if (res_rsv_ruimte_key) // Hebben we niet bij een afspraak
|
|
{
|
|
var sql = "SELECT res_srtactiviteit_anonym, "
|
|
+ " res_discipline_key "
|
|
+ " FROM res_srtactiviteit sa,"
|
|
+ " res_activiteit ra,"
|
|
+ " res_rsv_ruimte rrr,"
|
|
+ " res_ruimte_opstelling rro,"
|
|
+ " res_ruimte rr"
|
|
+ " WHERE sa.res_srtactiviteit_key = ra.res_srtactiviteit_key"
|
|
+ " AND ra.res_activiteit_key = rrr.res_activiteit_key"
|
|
+ " AND rrr.res_rsv_ruimte_key = " + rsv_ruimte_key
|
|
+ " AND rrr.res_ruimte_opstel_key = rro.res_ruimte_opstel_key(+)"
|
|
+ " AND rro.res_ruimte_key = rr.res_ruimte_key(+)";
|
|
var oRs = Oracle.Execute(sql);
|
|
var disc = oRs("res_discipline_key").Value;
|
|
tonen = (oRs("res_srtactiviteit_anonym").Value != 1);
|
|
oRs.Close();
|
|
}
|
|
// FOF mag het wel zien als hij rechten heeft op de (ruimte)discipline.
|
|
// Bij voorzieningreserveringen mag je het met any FOF altijd zien.
|
|
var canFOF = user.checkAutorisation("WEB_RESFOF", true, disc);
|
|
if (canFOF)
|
|
tonen = true;
|
|
|
|
return tonen;
|
|
}
|
|
|
|
Date.prototype.getFloatHours = function getFloatHours()
|
|
{
|
|
return this.getHours() + (this.getMinutes()/60);
|
|
}
|
|
// Noot: rondt af op S("res_h")!
|
|
// levert een nieuw date-object op
|
|
Date.prototype.setFloatHours = function setFloatHours(hrs)
|
|
{
|
|
var dd = new Date(this);
|
|
hrs = Math.floor((hrs / S("res_h")) + 0.5) * S("res_h");
|
|
var hh = Math.floor(hrs);
|
|
var mm = (hrs * 60) % 60;
|
|
dd.setHours(hh, mm, 0, 0);
|
|
return dd;
|
|
}
|
|
// Noot: rondt af op S("res_h")!
|
|
// levert een nieuw date-object op
|
|
Date.prototype.addFloatHours = function addFloatHours(hrs)
|
|
{
|
|
return this.setFloatHours(this.getFloatHours() + hrs);
|
|
}
|
|
|
|
%>
|