1192 lines
56 KiB
Plaintext
1192 lines
56 KiB
Plaintext
<%@ language = "JavaScript" %>
|
|
<% /*
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: pda/reserveringen.asp
|
|
Description: Toont gegevens van een res_ruimte of res_deel en biedt optie te boeken
|
|
|
|
|
|
Parameters: res_ruimte_key (of eventueel als alg_ruimte_key)
|
|
res_deel_key (of eventueel als ins_deel_key)
|
|
link2res (default 1) om een link naar de eigen reservering te tonen(1) of niet (0)
|
|
Context:
|
|
Notes: De user moet geauthenticeerd zijn en WEB_RESUSE (read) rechten hebben. Met write rechten kan ook
|
|
daadwerkelijk gereserveerd worden, indien de zaal nu vrij is.
|
|
Merk op: het feit dat deze functie (mobiel) kan worden aangeroepen betekent dat er fysiek aan de
|
|
ALG-scope voldaan wordt ("ik mag hier kennelijk komen").
|
|
Het echt reserveren doen we met een post naar rsv_edit_ruimte_save.asp
|
|
Vanaf 2023.2 is (alleen) WEB_RESFOF ook voldoende
|
|
|
|
Dit is zowel een lijst als een detailscherm, een bijzondere situatie.
|
|
|
|
Er is dus een RuimteMode en een DeelMode.
|
|
|
|
Sinds 2020.1d is er ook een PlanMode, waarbij een datum res_van is gedefinieerd. Dan reserveer je
|
|
op die dag in plaats van Vandaag. Dat is met name gerealiseerd voor (werkplek)objecten en daartussenin
|
|
gewurmd met de bedoeling de rest intact te laten. Daar moeten we nog wel wat mee. Het is niet zo dat je
|
|
nu vanzelf ruimtes op andere dagen kunt gaan reserveren. Om nog meer spaghetti te voorkomen moeten we
|
|
dat snel uitsluiten, anders maken we het ons erg moeilijk?
|
|
De PlanMode krijg je automatisch als je een res_van meegeeft, of als je planmode=1 meegeeft, dan is het vanaf nu
|
|
Zo kun je de intervallen ook in bv een bookmark oproepen.
|
|
|
|
Met restrict2res_disc kun je een res_disciplinekey (typisch via de klik-url vanuit de tekening) meegeven,
|
|
dan wordt het (ins_key) object gevalideerd tegen deze catalogus. Als dat niet matcht, kun je toch niet reserveren.
|
|
Beetje suf wellicht, maar soms prettig.
|
|
|
|
Future extensions:
|
|
- indien de huidige reserving bijna klaar is ook vanaf-eind + 1 of 2 uur kunnen claimen
|
|
- (dan ook) de schoonmaaktijd-volgend-op de lopende-reservering in acht nemen? Dat gaat natuurlijk niet werken,
|
|
omdat de afruimploeg in principe uit zou kunnen gaan van speling (want is erna toch vrij).
|
|
|
|
*/
|
|
%>
|
|
<!-- #include file="../Shared/common.inc" -->
|
|
<!-- #include file="../Shared/persoonselector.inc" -->
|
|
<!-- #include file="./mobile.inc" -->
|
|
<!-- #include file="../res/res_plan_room_v2.inc" -->
|
|
<!-- #include file="../res/res.inc" -->
|
|
<!-- #include file="../res/res_flexkenmerk.inc" -->
|
|
<!-- #include file="./iface.inc" -->
|
|
<!-- #include file="../Shared/discxalg3d.inc"-->
|
|
<%
|
|
FCLTHeader.Requires({ plugins: ["kenmerk"], css: [rooturl+"/appl/res/res.css"] });
|
|
var RuimteMode = false;
|
|
var DeelMode = false;
|
|
var ArtikelMode = false;
|
|
var isMobile = getQParamInt("ismobile", 0); // Wordt vanuit reservering_new_by_placetime.asp (mobile weergave) op 1 gezet. Vanuit desktop weergave word thet niet gezet.
|
|
var res_noshowgrace = 5*60*1000 ; // hoeveel milliseconden na aanvang mag je een (lege) bezette ruimte afpakken?
|
|
var adhoc_threshold = S("res_adhoc_threshold"); // Hoeveel minuten voor het aflopen van de huidige reservering mag je zelf alvast reserveren?
|
|
|
|
var ins_key = getQParamInt("ins_key", -1);
|
|
var res_ruimte_key = -1;
|
|
var res_deel_key = getQParamInt("res_deel_key", -1);
|
|
var res_artikel_key = getQParamInt("res_artikel_key", -1);
|
|
var res_van = getQParamDate("res_van", null);
|
|
var act_key = getQParamInt("act_key", -1);
|
|
|
|
var restrict2res_disc_key_array = getQParamIntArray("restrict2res_disc",[]);
|
|
|
|
var PlanMode = (res_van != null); // Anders ad-hoc *nu* modes
|
|
// variant 2
|
|
if (!PlanMode && res_van == null) // dubbelop, maar voor de zekerheid ;-)
|
|
{
|
|
PlanMode = getQParamInt("planmode", 0) == 1;
|
|
res_van = new Date();
|
|
}
|
|
|
|
var server_tz = S("fac_server_timezone");
|
|
var local_tz = server_tz;
|
|
|
|
var link2res = getQParamInt("link2res", 1);
|
|
|
|
if (ins_key != -1 || res_deel_key != -1)
|
|
{
|
|
// Objectenmode
|
|
DeelMode = true;
|
|
if (res_deel_key == -1)
|
|
{
|
|
var sql = "SELECT MAX(res_deel_key) res_deel_key"
|
|
+ " FROM res_deel "
|
|
+ "WHERE res_deel_verwijder IS NULL"
|
|
+ " AND (res_deel_vervaldatum IS NULL or res_deel_vervaldatum > sysdate)"
|
|
+ (restrict2res_disc_key_array.length? " AND res_discipline_key IN (" + restrict2res_disc_key_array.join(",") + ")" : "")
|
|
+ " AND res_ins_deel_key = " + ins_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs("res_deel_key").value)
|
|
{
|
|
shared.simpel_page(L("lcl_pda_res_nietres"));
|
|
}
|
|
res_deel_key = oRs("res_deel_key").value;
|
|
oRs.Close();
|
|
}
|
|
var sql = "SELECT ins_deel_omschrijving"
|
|
+ " , ins_alg_ruimte_key"
|
|
+ " FROM res_deel rd"
|
|
+ " , ins_deel id"
|
|
+ " WHERE rd.res_deel_key = " + res_deel_key
|
|
+ " AND rd.res_ins_deel_key = id.ins_deel_key ";
|
|
oRs = Oracle.Execute(sql);
|
|
var alg_ruimte_key = oRs("ins_alg_ruimte_key").value;
|
|
oRs.Close();
|
|
local_tz = res.getTimezoneByRuimte(alg_ruimte_key, "ALG");
|
|
}
|
|
else if (res_artikel_key != -1)
|
|
{
|
|
// UNSUPPORTED; local_tz = ?
|
|
// ArtikelMode
|
|
ArtikelMode = true;
|
|
}
|
|
else
|
|
{
|
|
// Ruimtemode
|
|
RuimteMode = true;
|
|
var alg_ruimte_key = getQParamInt("alg_ruimte_key", -1);
|
|
if (alg_ruimte_key == -1)
|
|
{
|
|
res_ruimte_key = getQParamInt("res_ruimte_key");
|
|
local_tz = res.getTimezoneByRuimte(res_ruimte_key, "RES");
|
|
}
|
|
else
|
|
{
|
|
local_tz = res.getTimezoneByRuimte(alg_ruimte_key, "ALG");
|
|
// Dit moet nog uitgebreid worden zodat het meerdere "enkele_ruimten" in verschillende catalogi kan handelen
|
|
// voor nu MAX() om AiAi uit te voorkomen
|
|
var enkele_ruimte = "(SELECT MAX(ra.res_ruimte_key)"
|
|
+ " FROM res_alg_ruimte ra"
|
|
+ " WHERE ra.res_alg_ruimte_verwijder IS NULL"
|
|
+ " AND ra.alg_ruimte_key="+alg_ruimte_key
|
|
+ " AND 1= (SELECT COUNT(*)"
|
|
+ " FROM res_alg_ruimte sra"
|
|
+ " WHERE sra.res_alg_ruimte_verwijder IS NULL"
|
|
+ " AND sra.res_ruimte_key = ra.res_ruimte_key"
|
|
+ ")"
|
|
+ ")";
|
|
var koppel_ruimte = "(SELECT MAX(res_ruimte_key) res_ruimte_key"
|
|
+ " FROM res_alg_ruimte"
|
|
+ " WHERE res_alg_ruimte_verwijder IS NULL"
|
|
+ " AND alg_ruimte_key="+alg_ruimte_key
|
|
+ ")";
|
|
var sql = "SELECT COALESCE("+enkele_ruimte+","+koppel_ruimte+") res_ruimte_key"
|
|
+ " FROM dual";
|
|
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.eof) {
|
|
res_ruimte_key = oRs("res_ruimte_key").value||-1;
|
|
}
|
|
oRs.Close();
|
|
}
|
|
// res_ruimte_key is nu geldig of null
|
|
}
|
|
var submitting = getQParamInt("submit", 0) == 1;
|
|
var qrc = getQParamInt("qrc", 0) != 0;
|
|
|
|
function toLocalDate(expr) {
|
|
return convertToLocalTimeSQL(expr, local_tz);
|
|
}
|
|
function toServerDate(expr) {
|
|
return convertToServerTimeSQL(expr, local_tz);
|
|
}
|
|
|
|
var transitParam = buildTransitParam(["res_ruimte_key", "res_deel_key"]);
|
|
|
|
if (res_ruimte_key < 0 && res_deel_key < 0 && res_artikel_key < 0)
|
|
{
|
|
shared.simpel_page(L("lcl_pda_res_nietres"));
|
|
}
|
|
|
|
// Zoek 'default' activiteit
|
|
if (RuimteMode)
|
|
{
|
|
sql = " SELECT rr.res_discipline_key "
|
|
+ " FROM res_ruimte rr"
|
|
+ " WHERE rr.res_ruimte_key = " + res_ruimte_key;
|
|
var soort = 0; // reserveerbare ruimtes
|
|
}
|
|
else if (ArtikelMode)
|
|
{
|
|
var sql = "SELECT ra.res_discipline_key"
|
|
+ " FROM res_artikel ra"
|
|
+ " WHERE ra.res_artikel_key = " + res_artikel_key;
|
|
var soort = 1; // algemene ruimtes
|
|
}
|
|
else // Deelmode dan dus?
|
|
{
|
|
sql = " SELECT rd.res_discipline_key "
|
|
+ " FROM res_deel rd"
|
|
+ " WHERE rd.res_deel_key = " + res_deel_key;
|
|
if (restrict2res_disc_key_array.length)
|
|
{
|
|
sql = "SELECT MIN(d.res_discipline_key) res_discipline_key"
|
|
+ " FROM (" + sql
|
|
+ " UNION"
|
|
+ " SELECT rd.ins_discipline_key"
|
|
+ " FROM res_discipline rd"
|
|
+ " WHERE rd.ins_discipline_key IN (" + restrict2res_disc_key_array.join(",") + ")"
|
|
+ " ) d"
|
|
+ " , res_disc_params p"
|
|
+ " , fac_v_webgebruiker w"
|
|
+ " WHERE d.res_discipline_key = p.res_ins_discipline_key"
|
|
+ " AND d.res_discipline_key = w.ins_discipline_key"
|
|
+ " AND p.res_disc_params_intervals IS NOT NULL"
|
|
+ " AND w.prs_perslid_key = " + user_key;
|
|
}
|
|
var soort = 1; // algemene ruimtes
|
|
}
|
|
oRs = Oracle.Execute(sql);
|
|
var res_disc_key = oRs("res_discipline_key").value;
|
|
oRs.Close();
|
|
|
|
sql = "SELECT MIN (ra.res_activiteit_key) res_activiteit_key"
|
|
+ " , MIN(rs.res_srtactiviteit_key) res_srtactiviteit_key"
|
|
+ " , MIN(res_activiteit_master_key) res_activiteit_master_key"
|
|
+ " FROM res_activiteitdiscipline ad, "
|
|
+ " res_activiteit ra,"
|
|
+ " res_srtactiviteit rs"
|
|
+ " WHERE ad.res_discipline_key = " + res_disc_key
|
|
+ " AND ra.res_activiteit_key = ad.res_activiteit_key"
|
|
+ " AND rs.res_srtactiviteit_key = ra.res_srtactiviteit_key"
|
|
+ " AND res_srtactiviteit_soort = " + soort
|
|
+ (act_key > 0? " AND ra.res_activiteit_key = " + act_key:"");
|
|
oRs = Oracle.Execute(sql);
|
|
var res_activiteit_key = oRs("res_activiteit_key").value;
|
|
var res_srtactiviteit_key = oRs("res_srtactiviteit_key").Value;
|
|
var isChild = oRs("res_activiteit_master_key").Value > 0;
|
|
|
|
oRs.Close();
|
|
|
|
if (!res_activiteit_key)
|
|
_AiAi("INTERNAL_ERROR: Geen activiteit gevonden die hoort bij catalogus met key = {0}".format(res_disc_key));
|
|
|
|
lcl.set_dialect(res_srtactiviteit_key, "RES_SRTACTIVITEIT_KEY");
|
|
|
|
if (PlanMode)
|
|
{
|
|
sql = "SELECT ogb.alg_gebouw_key"
|
|
+ " FROM alg_v_onrgoed_boom ogb"
|
|
+ " WHERE ogb.alg_ruimte_key = "
|
|
+ ( alg_ruimte_key == -1
|
|
? "( SELECT alg_ruimte_key FROM res_alg_ruimte WHERE res_ruimte_key = " + res_ruimte_key + ")"
|
|
: alg_ruimte_key
|
|
);
|
|
var oRs = Oracle.Execute(sql);
|
|
var alg_gebouw_key = oRs("alg_gebouw_key").Value;
|
|
oRs.Close();
|
|
if (DeelMode && !isChild)
|
|
{
|
|
var bloktijden = res.getBloktijdenDisc(res_disc_key, res_van, alg_gebouw_key) // Deelmode
|
|
}
|
|
else
|
|
{
|
|
var bloktijden = res.getBloktijden(res_activiteit_key, res_disc_key, res_van, alg_gebouw_key); // RuimteMode of master/sub deelmode
|
|
}
|
|
}
|
|
|
|
// Nu we de discipline hebben kunnen we ook wat autorisatiecontrole doen
|
|
// Omdat PDA reserveren vaak ad-hoc is zijn we wat flexibeler over
|
|
// alg_scope en dergelijke dan anders
|
|
restrict2res_disc_key_array = restrict2res_disc_key_array.concat([res_disc_key]);
|
|
var authRES = user.func_enabled2("RES", { ins_discipline_key: restrict2res_disc_key_array });
|
|
var urole = "fe";
|
|
if (authRES.canWrite("WEB_RESFOF")) {
|
|
urole = "fo";
|
|
}
|
|
|
|
%>
|
|
<html>
|
|
<head>
|
|
<% FCLTMHeader.Generate({title: L("lcl_mobile_reserveringen")});
|
|
|
|
var modal = getQParamInt("modal", 0) == 1;
|
|
if (modal)
|
|
{ // Voorkom te groot scherm als modal popup
|
|
%>
|
|
<style>
|
|
.ui-mobile,.ui-mobile .ui-page {min-height:100px}
|
|
</style>
|
|
<% } %>
|
|
<script type='text/javascript'>
|
|
var modal = <%=modal ? 1 : 0%>;
|
|
|
|
function reserveer_callback(result) {
|
|
if (result.success) { <% /* Dit is altijd waar, en anders knallen we er wel eerder uit */ %>
|
|
window.location.href = window.location.href + "&submit=1&res_rsv_ruimte_key=" + result.rsv_ruimte_key;
|
|
}
|
|
}
|
|
|
|
<% if (PlanMode) { %>
|
|
|
|
async function reserveer()
|
|
{
|
|
var $selected = $("input[name=timeslots]:checked");
|
|
var van = $selected.data("van");
|
|
var tot = $selected.data("tot");
|
|
var master_key = $selected.data("master-key");
|
|
|
|
<% if (DeelMode && (!bloktijden.length || !("multiperday" in bloktijden[0]) || !bloktijden[0].multiperday))
|
|
{
|
|
%>
|
|
var double_reservations = await handle_double_reservations(van, tot);
|
|
if (double_reservations === false) { /* Error */
|
|
return false;
|
|
}
|
|
if (double_reservations.length > 0)
|
|
{
|
|
var replaceLcl = $("#person").val() == <%=user_key%>
|
|
? "<%=safe.jsstring(L('lcl_res_deel_replace'))%>"
|
|
: "<%=safe.jsstring(L('lcl_res_deel_replace_fof'))%>";
|
|
return new Promise((resolve) => {
|
|
FcltMgr.confirm(replaceLcl, {
|
|
fncancel: () => {
|
|
resolve(false);
|
|
}
|
|
},
|
|
() => {
|
|
var index;
|
|
for (index = 0; index < double_reservations.length; index++)
|
|
{
|
|
var data = {};
|
|
data["has_" + double_reservations[index].res_deel_key] = "";
|
|
if (index == 0) {
|
|
data["chk_<%=res_deel_key%>"] = "on";
|
|
_proceed_reserveer(van, tot, double_reservations[index].res_rsv_ruimte_key);
|
|
}
|
|
protectRequest.dataToken(data);
|
|
$.post("<%=rooturl%>/appl/res/res_edit_objcat_save.asp?urole=<%=urole%>&verynew=0&rsv_ruimte_key=" + double_reservations[index].res_rsv_ruimte_key,
|
|
data,
|
|
null,
|
|
"json");
|
|
}
|
|
resolve(true);
|
|
});
|
|
});
|
|
}
|
|
else
|
|
|
|
<% } /* !meerperdag */ %>
|
|
|
|
{
|
|
_proceed_reserveer(van, tot);
|
|
return true;
|
|
}
|
|
|
|
function _proceed_reserveer(van, tot, rsv_ruimte_key)
|
|
{
|
|
$.post("<%=rooturl%>/appl/res/res_edit_rsv_ruimte_save.asp?urole=<%=urole%>&adhoc=1&res_deel_key=<%=res_deel_key%>" + (rsv_ruimte_key ? "&rsv_ruimte_key="+rsv_ruimte_key : ""),
|
|
getPostData(van, tot, master_key), McltCallbackAndThen(reserveer_callback), "json");
|
|
}
|
|
}
|
|
|
|
<% } else { %> // !PlanMode
|
|
|
|
function reserveer()
|
|
{
|
|
$.post("<%=rooturl%>/appl/res/res_edit_rsv_ruimte_save.asp?urole=<%=urole%>&adhoc=1&res_deel_key=<%=res_deel_key%>",
|
|
getPostData(), McltCallbackAndThen(reserveer_callback), "json");
|
|
return true;
|
|
}
|
|
|
|
<% } %> // !PlanMode
|
|
|
|
function getPostData(van, tot, master_key)
|
|
{
|
|
if (typeof van == "undefined")
|
|
{
|
|
var $selected = $("input[name=timeslots]:checked");
|
|
var van = $selected.data("van");
|
|
var tot = $selected.data("tot");
|
|
var master_key = $selected.data("master-key");
|
|
}
|
|
var data_arr = [];
|
|
var data = { <% if (RuimteMode) { %>
|
|
restype: "R",
|
|
res_ruimte_key: <%=res_ruimte_key%>,
|
|
<% } else if (ArtikelMode) { %>
|
|
restype: "CV",
|
|
<% } else { %>
|
|
restype: "CV",
|
|
ruimtekey: <%=alg_ruimte_key%>,
|
|
<% } %>
|
|
date_from: van, // Doorgaans tijd waarop dialoog geopend. Voorkomt dat als je na een paar
|
|
date_to: tot, // minuten klikt de tijdsduur mogelijk te kort geworden is
|
|
master_key: master_key,
|
|
sel_activity: <%=(res_activiteit_key || -1)%>,
|
|
ab_mode: 0+2, // altijd 'afhalen' in de ruimte zelf, meteen vastzetten
|
|
status_fo: 2,
|
|
account: -1,
|
|
nodirty: 1, // willen we echt niet
|
|
// person: $("#person").val(), Deze komt met de <form> mee
|
|
personH: $("#person").val(),
|
|
descript: "<%=safe.jsstring(PlanMode ? L("lcl_res_planmode_gereserveerd") : L("lcl_pda_res_gereserveerd"))%>",
|
|
opmerk: "<%=safe.jsstring(PlanMode ? L("lcl_res_planmode_geresopmerk") : L("lcl_pda_res_geresopmerk"))%>"
|
|
};
|
|
<% protectRequest.dataToken("data"); %>
|
|
|
|
data_arr.push($.param(data));
|
|
|
|
// Dit voegt de kenmerken toe
|
|
data_arr.push($("form[name=resform]").serialize());
|
|
|
|
return data_arr.join("&")
|
|
}
|
|
|
|
async function res_submit()
|
|
{
|
|
document.activeElement.blur(); // trigger laatste onChanges
|
|
|
|
// Standaard checks op verplichte velden, datum formaat, numeriek en float formaat, currency formaat.
|
|
if (!await validateForm("resform"))
|
|
return false;
|
|
|
|
return reserveer();
|
|
}
|
|
|
|
function resShow(key, welniet)
|
|
{
|
|
data = { bezshown: 0,
|
|
reseteindtijd: 1
|
|
};
|
|
if (welniet == 1)
|
|
data.resetshown = 1;
|
|
<% protectRequest.dataToken("data"); %>
|
|
$.post("<%=rooturl%>/appl/res/res_noshow_save.asp?rsv_ruimte_key=" + key, data, McltCallbackRefresh, "json");
|
|
}
|
|
|
|
function resCountShow(key)
|
|
{
|
|
data = { bezshown: $("#bezshown").val()
|
|
, reseteindtijd: 0
|
|
, resetshown: 0
|
|
};
|
|
<% protectRequest.dataToken("data"); %>
|
|
$.post("<%=rooturl%>/appl/res/res_noshow_save.asp?rsv_ruimte_key=" + key, data, McltCallbackClose, "json");
|
|
}
|
|
|
|
$(function ()
|
|
{
|
|
$("[data-role=collapsible]").on("collapsibleexpand collapsiblecollapse", function(event, ui) {
|
|
FcltMgr.resized();
|
|
});
|
|
|
|
window.fcltmobile = !modal;
|
|
});
|
|
|
|
</script>
|
|
</head>
|
|
<%
|
|
if (RuimteMode)
|
|
{
|
|
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_image,"
|
|
+ " COALESCE(res_ruimte_begintijd, " + S("res_t1") + ") begintijd,"
|
|
+ " COALESCE(res_ruimte_eindtijd, " + S("res_t2") + ") eindtijd,"
|
|
+ " rr.res_discipline_key"
|
|
+ " 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";
|
|
oRs = Oracle.Execute(sql);
|
|
var res_ruimte_nr = oRs("res_ruimte_nr").Value;
|
|
var foto = oRs("res_ruimte_image").Value;
|
|
var ruimte_omschrijving = oRs("res_ruimte_omschrijving").Value;
|
|
var rbegintijd = oRs("begintijd").Value;
|
|
var reindtijd = oRs("eindtijd").Value;
|
|
oRs.Close();
|
|
|
|
if (rbegintijd < S("res_t1")) rbegintijd = S("res_t1");
|
|
if (reindtijd > S("res_t2")) reindtijd = S("res_t2");
|
|
if (rbegintijd > reindtijd) rbegintijd = reindtijd;
|
|
}
|
|
else if (ArtikelMode)
|
|
{
|
|
var sql = "SELECT " + lcl.xsqla("res_artikel_omschrijving", "res_artikel_key")
|
|
+ " , res_artikel_image"
|
|
+ " FROM res_artikel ra"
|
|
+ " WHERE ra.res_artikel_key = " + res_artikel_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var res_deel_omschrijving = oRs("res_artikel_omschrijving").Value;
|
|
var foto = oRs("res_artikel_image").Value;
|
|
oRs.Close();
|
|
rbegintijd = S("res_t1");
|
|
reindtijd = S("res_t2");
|
|
}
|
|
else // Deelmode
|
|
{
|
|
var sql = "SELECT " + lcl.xsqla("res_deel_omschrijving", "res_deel_key")
|
|
+ " , res_deel_image"
|
|
+ " , res_deel_opmerking"
|
|
+ " FROM res_deel rd"
|
|
+ " WHERE rd.res_deel_key = " + res_deel_key;
|
|
oRs = Oracle.Execute(sql);
|
|
var res_deel_omschrijving = oRs("res_deel_omschrijving").Value;
|
|
var res_deel_opmerking = oRs("res_deel_opmerking").Value;
|
|
var foto = oRs("res_deel_image").Value;
|
|
oRs.Close();
|
|
if (!foto && ins_key != -1) {
|
|
var insDeelFotoMode = true;
|
|
sql = "SELECT ins_deel_image"
|
|
+ " FROM ins_deel"
|
|
+ " WHERE ins_deel_key = " + ins_key;
|
|
oRs = Oracle.Execute(sql);
|
|
if (!oRs.EoF) {
|
|
foto = oRs("ins_deel_image").Value;
|
|
}
|
|
oRs.Close();
|
|
}
|
|
rbegintijd = S("res_t1");
|
|
reindtijd = S("res_t2");
|
|
}
|
|
|
|
// Suggestie: t1 niet aanbieden als dat minder dan 15 minuten is
|
|
|
|
// Selecteer de nabije reserveringen van deze ruimte, lopende of aanstaand
|
|
// Werkt niet goed bij de dagovergangen (waar alleen ontwikkelaars last van hebben)
|
|
|
|
if (RuimteMode) // TODO: DIT HOUDT NOG GEEN REKENING MET KOPPELZALEN!
|
|
{
|
|
// Zoek alle bestaande reserveringen op deze ruimte die nog bezig zijn of komen
|
|
var localResVanExpr = toLocalDate("rm.res_rsv_ruimte_van");
|
|
var localResTotExpr = toLocalDate("rm.res_rsv_ruimte_tot");
|
|
sql = "SELECT rm.res_reservering_key,"
|
|
+ " rm.res_rsv_ruimte_volgnr,"
|
|
+ " rm.res_rsv_ruimte_key,"
|
|
+ " rm.res_rsv_ruimte_omschrijving,"
|
|
+ " rm.res_rsv_ruimte_van,"
|
|
+ " rm.res_rsv_ruimte_tot,"
|
|
+ " " + localResVanExpr + " AS local_van,"
|
|
+ " " + localResTotExpr + " AS local_tot,"
|
|
+ " res_disc_params_preposttime,"
|
|
+ " (SELECT prs_perslid_naam_friendly FROM prs_v_perslid_fullnames pf WHERE pf.prs_perslid_key = rm.res_rsv_ruimte_host_key) host,"
|
|
+ " rm.res_rsv_ruimte_host_key host_key,"
|
|
+ " rm.res_rsv_ruimte_bezoekers,"
|
|
+ " rm.res_rsv_ruimte_bezoekers_shown"
|
|
+ " FROM res_disc_params dp, "
|
|
+ " res_rsv_ruimte rm,"
|
|
+ " res_ruimte_opstelling ro,"
|
|
+ " res_ruimte r";
|
|
if (PlanMode) // wil ik alles van res_van weten
|
|
{
|
|
// res_van is de lokale dag (geTRUNC'd dus)
|
|
var serverResdateRangeStart = toServerDate(res_van.toSQL());
|
|
var serverResdateRangeEnd = serverResdateRangeStart + " + 1 - (1 / 24 / 60 / 60)";
|
|
sql += " WHERE rm.res_rsv_ruimte_van < " + serverResdateRangeEnd
|
|
+ " AND rm.res_rsv_ruimte_tot > " + serverResdateRangeStart;
|
|
}
|
|
else // Ad-hoc
|
|
{
|
|
var serverResdateRangeEnd = toServerDate("TRUNC(" + toLocalDate("SYSDATE") + ") + 1 - (1 / 24 / 60 / 60)");
|
|
sql += " WHERE rm.res_rsv_ruimte_van < " + serverResdateRangeEnd
|
|
+ " AND rm.res_rsv_ruimte_tot > SYSDATE"; // Alleen vandaag en alleen lopende en toekomstige reserveringen
|
|
}
|
|
sql += " AND rm.res_ruimte_opstel_key = ro.res_ruimte_opstel_key"
|
|
+ " AND ro.res_ruimte_key = r.res_ruimte_key"
|
|
+ " AND r.res_ruimte_key = " + res_ruimte_key
|
|
+ " AND r.res_discipline_key = dp.res_ins_discipline_key"
|
|
+ " AND rm.res_rsv_ruimte_verwijder IS NULL"
|
|
+ " AND (res_rsv_ruimte_bezoekers_shown IS NULL OR res_rsv_ruimte_bezoekers_shown > 0)" // NoShow?
|
|
+ " AND rm.res_rsv_ruimte_dirtlevel = 0"
|
|
+ " ORDER BY res_rsv_ruimte_van"; // Eerste vooraan.
|
|
} else {
|
|
var localResVanExpr = toLocalDate("rm.res_rsv_ruimte_van");
|
|
var localResTotExpr = toLocalDate("rm.res_rsv_ruimte_tot");
|
|
sql = "SELECT rm.res_reservering_key,"
|
|
+ " rm.res_rsv_ruimte_volgnr,"
|
|
+ " rm.res_rsv_ruimte_key,"
|
|
+ " rm.res_rsv_ruimte_omschrijving,"
|
|
+ " rm.res_rsv_ruimte_van,"
|
|
+ " rm.res_rsv_ruimte_tot,"
|
|
+ " " + localResVanExpr + " AS local_van ,"
|
|
+ " " + localResTotExpr + " AS local_tot ,"
|
|
+ " 0 res_disc_params_preposttime,"
|
|
+ " (SELECT prs_perslid_naam_friendly FROM prs_v_perslid_fullnames pf WHERE pf.prs_perslid_key = rm.res_rsv_ruimte_host_key) host,"
|
|
+ " rm.res_rsv_ruimte_host_key host_key,"
|
|
+ " rd.res_deel_key"
|
|
+ " FROM res_rsv_ruimte rm,"
|
|
+ " res_rsv_deel rd,"
|
|
+ " res_deel d";
|
|
if (PlanMode) // wil ik alles van res_van weten
|
|
{
|
|
// res_van is de lokale dag (geTRUNC'd dus)
|
|
var serverResdateRangeStart = toServerDate(res_van.toSQL());
|
|
var serverResdateRangeEnd = serverResdateRangeStart + " + 1 - (1 / 24 / 60 / 60)";
|
|
sql += " WHERE rm.res_rsv_ruimte_van < " + serverResdateRangeEnd
|
|
+ " AND rm.res_rsv_ruimte_tot > " + serverResdateRangeStart;
|
|
}
|
|
else
|
|
{
|
|
var serverResdateRangeEnd = "SYSDATE + 1 - (1 / 24 / 60 / 60)";
|
|
sql += " WHERE rm.res_rsv_ruimte_van < " + serverResdateRangeEnd
|
|
+ " AND rm.res_rsv_ruimte_tot > SYSDATE"; // Alleen vandaag en alleen lopende en toekomstige reserveringen
|
|
}
|
|
// sql for check on existing workplace reservations
|
|
var sql_pers = sql
|
|
+ " AND rd.res_deel_key = d.res_deel_key"
|
|
+ " AND d.res_discipline_key = " + res_disc_key
|
|
+ " AND rd.res_rsv_ruimte_key = rm.res_rsv_ruimte_key"
|
|
+ " AND rm.res_rsv_ruimte_host_key = " + user_key
|
|
+ " AND rm.res_rsv_ruimte_verwijder IS NULL"
|
|
+ " AND rd.res_rsv_deel_verwijder IS NULL"
|
|
+ " AND rd.res_rsv_deel_dirtlevel = 0"
|
|
+ " ORDER BY rm.res_rsv_ruimte_van"; // Eerste vooraan.
|
|
sql +=" AND rd.res_rsv_ruimte_key = rm.res_rsv_ruimte_key"
|
|
+ " AND rd.res_deel_key = d.res_deel_key"
|
|
+ " AND rd.res_deel_key = " + res_deel_key
|
|
+ " AND rm.res_rsv_ruimte_verwijder IS NULL"
|
|
+ " AND rd.res_rsv_deel_verwijder IS NULL"
|
|
+ " AND rd.res_rsv_deel_dirtlevel = 0"
|
|
+ " ORDER BY rm.res_rsv_ruimte_van"; // Eerste vooraan.
|
|
}
|
|
%>
|
|
<body class="resruimte">
|
|
<%
|
|
// TODO: een list(!) van de reserveringen vanaf nu (reeds begonnen) tot einde van de dag
|
|
// Daar kan ik op klikken en dan.... of...?
|
|
// BLOCK_START({collapsed: false, title: L("lcl_mobile_res_today")});
|
|
|
|
if (RuimteMode)
|
|
var periods = S("res_pda_room_times"); // Let op: alles moet deelbaar zijn door 'blokgrootte' S("res_h") en groter zijn dan S("res_block")
|
|
else
|
|
var periods = S("res_pda_deel_times"); // ['15','30','60','120','240']
|
|
for (var i in periods) // Het zijn altijd strings
|
|
periods[i] = parseInt(periods[i]);
|
|
|
|
// Van een noshow is de eindtijd op de Oracle TRUNC(SYSDATE, 'MI') gezet en je komt anders in de de problemen als Oracle een minuut voorloopt
|
|
var oRs = Oracle.Execute("SELECT " + toLocalDate("TRUNC(SYSDATE, 'MI')") + " FROM DUAL");
|
|
var now = new Date(oRs(0).Value);
|
|
oRs.Close();
|
|
|
|
var maxTime = now.setFloatHours(reindtijd);
|
|
var minuten = now.getHours() * 60 + now.getMinutes();
|
|
var blokstart = Math.ceil(minuten / (S("res_h")*60)) * S("res_h")*60; // omhoog afgerond op period[0]
|
|
var times = [];
|
|
if ((blokstart/60) < reindtijd)
|
|
{ // Start reservering is voor dag eind tijd (res_t2)
|
|
for (var i in periods)
|
|
{
|
|
var blokend = blokstart + periods[i];
|
|
var tm = new Date(now);
|
|
tm.setHours(Math.floor(blokend / 60));
|
|
tm.setMinutes(blokend % 60, 0, 0);
|
|
// Voor tmplus periods[0] toegevoegd: Als er in de tijd die overblijft toch geen reservering meer kan plaatsvinden dan eindtijd gelijk maken aan de eindtijd van de dag.
|
|
// Hiervoor tmplus voor gebruiken (tm + periods[0] > maxTime) => (tmplus > maxTime). Als (tmplus = maxTime) dan kan er nog een reservering met periods[0] plaatsvinden
|
|
var blokend = blokstart + periods[i] + periods[0];
|
|
var tmplus = new Date(now);
|
|
tmplus.setHours(Math.floor(blokend / 60));
|
|
tmplus.setMinutes(blokend % 60, 0, 0);
|
|
if (tmplus > maxTime) // periods[0] toegevoegd: Als er in de tijd die overblijft toch geen reservering meer kan plaatsvinden dan eindtijd gelijk maken aan de eindtijd van de dag.
|
|
{
|
|
times.push(maxTime);
|
|
break; // Voorkom nog een regel tot eindtijd
|
|
}
|
|
else
|
|
times.push(tm);
|
|
}
|
|
}
|
|
// times bevat nu potentiele start-tijdstippen
|
|
|
|
var nubezet = false;
|
|
var lopendeRes = false;
|
|
var helemaalvrij = false;
|
|
if (PlanMode) // dan gaan we het heel anders doen
|
|
{
|
|
var oRs = Oracle.Execute( sql );
|
|
while (!oRs.Eof)
|
|
{
|
|
var server_van = new Date(oRs("res_rsv_ruimte_van").Value);
|
|
var server_tot = new Date(oRs("res_rsv_ruimte_tot").Value);
|
|
var local_van = new Date(oRs("local_van").Value);
|
|
var local_tot = new Date(oRs("local_tot").Value);
|
|
|
|
// Let op: hier wordt voor elk gedefinieerd interval bekeken of deze reservering die bezet, om aan het einde te weten
|
|
// welke intervallen er dus nog helemaal vrij zijn. Afhankelijk van de gedefinieerde intervallen kan een reservering
|
|
// in meerdere intervallen vallen, voorbeeld 10-12 valt zowel in Ochtend als in Hele dag. Welke blokken je bezet zegt
|
|
// dus niet per se iets over hoe lang je reservering duurt.
|
|
// Ik denk dat ik daarom ook de echte onderliggende van en tot nodig heb, om dat later te kunnen vertellen
|
|
// zonder weer opnieuw die reserveringen te moeten zoeken
|
|
for (var i = 0; i < bloktijden.length; i++)
|
|
{
|
|
if (local_van < bloktijden[i].einddatum && local_tot > bloktijden[i].startdatum)
|
|
{
|
|
bloktijden[i].bezet = oRs("host").Value;
|
|
bloktijden[i].bezet_key = oRs("host_key").Value;
|
|
bloktijden[i].res_rsv_ruimte_key = oRs("res_rsv_ruimte_key").Value;
|
|
bloktijden[i].res_reservering_nr = oRs("res_reservering_key").Value+"/"+oRs("res_rsv_ruimte_volgnr").Value;
|
|
bloktijden[i].resvan = local_van;
|
|
bloktijden[i].restot = local_tot;
|
|
}
|
|
}
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.Close();
|
|
}
|
|
else
|
|
{
|
|
var oRs = Oracle.Execute(sql);
|
|
helemaalvrij = oRs.eof;
|
|
while (!oRs.eof) {
|
|
var rsv_omschrijving = oRs("res_rsv_ruimte_omschrijving").Value;
|
|
var rsv_host = oRs("host").Value;
|
|
var rsv_ruimte_key = oRs("res_rsv_ruimte_key").Value;
|
|
var server_van = new Date(oRs("res_rsv_ruimte_van").Value);
|
|
var server_tot = new Date(oRs("res_rsv_ruimte_tot").Value);
|
|
var local_van = new Date(oRs("local_van").Value);
|
|
var local_tot = new Date(oRs("local_tot").Value);
|
|
if (RuimteMode) {
|
|
var bezoekers_expected = oRs("res_rsv_ruimte_bezoekers").Value;
|
|
var bezoekers_shown = oRs("res_rsv_ruimte_bezoekers_shown").Value;
|
|
}
|
|
var prepost = oRs("res_disc_params_preposttime").Value || 0; // in uren
|
|
var totMinusThreshold = new Date(local_tot).setMinutes(local_tot.getMinutes() - adhoc_threshold);
|
|
if (totMinusThreshold <= now) { // Deze afspraak loopt nog, maar ik mag al wel vast boeken
|
|
now = new Date(local_tot); // Nieuwe startdatum (niet 'now', maar straks dus)
|
|
lopendeRes = true;
|
|
oRs.moveNext(); // Kijk of de volgende afspraak niet blokkeert
|
|
continue;
|
|
}
|
|
var schoonvan = new Date(local_van);
|
|
schoonvan.setMinutes(schoonvan.getMinutes() - prepost * 60);
|
|
if (schoonvan < times[0] && local_tot > now) { // Bezig of begint binnen schoonmaaktijd
|
|
var nubezet = true;
|
|
}
|
|
oRs.moveNext();
|
|
}
|
|
oRs.Close();
|
|
|
|
if (!helemaalvrij) { // Verwijder timeslots die een te korte reservering zouden maken
|
|
for (var i = times.length - 1; i >= 0; i--) {
|
|
var tmp = new Date(times[i]);
|
|
tmp.setMinutes(tmp.getMinutes() - prepost * 60);
|
|
if (tmp - now.getTime() < S("res_block") * 60 * 60 * 1000) { // Reservering te kort
|
|
times.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!times.length) {
|
|
nubezet = true;
|
|
}
|
|
}
|
|
|
|
// Maak een mooie header als er een foto is, met de beschrijving er overheen
|
|
var headerImageUrl;
|
|
if (foto && !foto.match(/^http/)) {
|
|
var module;
|
|
if (RuimteMode) {
|
|
module = "RESPHR";
|
|
} else if (DeelMode) {
|
|
if (typeof insDeelFotoMode !== "undefined") {
|
|
module = "INSPHD";
|
|
} else {
|
|
module = "RESPHD";
|
|
}
|
|
} else if (ArtikelMode) {
|
|
module = "RESPHA";
|
|
}
|
|
headerImageUrl = flexProps(module).RelativePath + foto;
|
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|
if (fso.FileExists(Server.MapPath(headerImageUrl))) {
|
|
var hasImageHeader = true;
|
|
}
|
|
}
|
|
|
|
PAGE_START({pclass: (nubezet ? "pbezet" : "pvrij"), headerImage: headerImageUrl });
|
|
HEADER ({title: RuimteMode ? res_ruimte_nr : res_deel_omschrijving , back:!qrc, home: !qrc});
|
|
CONTENT_START({pclass: (nubezet ? "dbezet" : "dvrij") });
|
|
FORM_START("resform", {action: "reserveringen.asp?submit=1" + transitParam, method: "post"});
|
|
|
|
if (authRES.canWrite("WEB_RESUSE") || authRES.canWrite("WEB_RESFOF"))
|
|
{
|
|
var timeslotAvailable = false;
|
|
var timeslot_radios = [];
|
|
if (PlanMode)
|
|
{
|
|
var myres = false;
|
|
var mystart;
|
|
var myend;
|
|
var myres_reservering_nrs = [];
|
|
var myres_rsv_ruimte_key;
|
|
for (var i = 0; i < bloktijden.length; i++)
|
|
{
|
|
if (bloktijden[i].bezet)
|
|
{
|
|
if (bloktijden[i].bezet_key == user_key) // = Mijn reservering
|
|
{
|
|
myres = true; // at least one of these is mine
|
|
mystart = (!mystart ? bloktijden[i].resvan : (bloktijden[i].resvan < mystart ? bloktijden[i].resvan : mystart));
|
|
myend = (!myend ? bloktijden[i].restot : (bloktijden[i].restot > myend ? bloktijden[i].restot : myend));
|
|
myres_rsv_ruimte_key = (!myres_rsv_ruimte_key ? bloktijden[i].res_rsv_ruimte_key : myres_rsv_ruimte_key);
|
|
// Als er verschillende reserveringsnummers zijn, wil ik die elk maar 1 keer tonen
|
|
// dit zal niet veel voorkomen, maar dan tonen we alle nummers, maar slechts 1 key
|
|
if (myres_reservering_nrs.length > 0)
|
|
{
|
|
var fnd = false;
|
|
for (var ii = 0; ii < myres_reservering_nrs.length; ii++)
|
|
{
|
|
if (myres_reservering_nrs[ii] === bloktijden[i].res_reservering_nr)
|
|
fnd = true;
|
|
}
|
|
if (!fnd)
|
|
{
|
|
myres_reservering_nrs.push(bloktijden[i].res_reservering_nr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
myres_reservering_nrs.push(bloktijden[i].res_reservering_nr);
|
|
}
|
|
}
|
|
else // if (bloktijden[i].bezet_key != user_key)
|
|
{
|
|
var reserver = new Perslid(bloktijden[i].bezet_key);
|
|
var show_name = reserver.prs_perslid_visibility();
|
|
if ( (bloktijden[i].startdatum.getTime() == bloktijden[i].resvan.getTime())
|
|
&& (bloktijden[i].einddatum.getTime() == bloktijden[i].restot.getTime())
|
|
)
|
|
{
|
|
if (!show_name && authRES.canWrite("WEB_RESFOF")) { // Als ik voor deze prs mag/mocht reserveren, mag ik z'n naam ook zien
|
|
var xfunc = user.func_enabled("RES", res_disc_key, null, bloktijden[i].bezet_key, null, true);
|
|
show_name = xfunc.canRead("WEB_RESFOF");
|
|
}
|
|
}
|
|
else
|
|
{ // bloktijd is niet de reservering
|
|
show_name = false;
|
|
}
|
|
|
|
var label = bloktijden[i].name + " " + (show_name ? L("lcl_mobile_res_intervalbezetvoor").format(bloktijden[i].bezet)
|
|
: L("lcl_mobile_res_intervalbezet"));
|
|
timeslot_radios.push({
|
|
id: "blok_" + i,
|
|
value: "",
|
|
disabled: true,
|
|
label: label
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
timeslot_radios.push({
|
|
id: "blok_" + i,
|
|
value: "",
|
|
checked: !timeslotAvailable,
|
|
label: bloktijden[i].name,
|
|
data: {
|
|
van: bloktijden[i].startdatum.getTime(),
|
|
tot: bloktijden[i].einddatum.getTime(),
|
|
"master-key": (bloktijden[i].rsv_ruimte_master_key || "")
|
|
}
|
|
});
|
|
timeslotAvailable = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (var tm in times)
|
|
{
|
|
if ( helemaalvrij
|
|
|| ( !nubezet
|
|
&& ( ( typeof schoonvan === "undefined" && lopendeRes)
|
|
|| ( times[tm] <= schoonvan )
|
|
)
|
|
)
|
|
)
|
|
{
|
|
timeslot_radios.push({
|
|
id: "tot_" + tm,
|
|
value: "",
|
|
checked: !timeslotAvailable,
|
|
label: L("lcl_pda_res_ruimtereserveer").format(toTimeString(times[tm], { isLocal: true })),
|
|
data: {
|
|
van: now.getTime(),
|
|
tot: times[tm].getTime()
|
|
}
|
|
});
|
|
timeslotAvailable = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (PlanMode && link2res == 1) {
|
|
if (submitting) { // Laat na een reservering eerst de feedback voor die exacte reservering zien.
|
|
timeslotAvailable = false; // Niet direct weer tijdslots tonen
|
|
|
|
var myres_rsv_ruimte_key = getQParamInt("res_rsv_ruimte_key", -1);
|
|
if (myres_rsv_ruimte_key > 0) { // Altijd?
|
|
sql_vt = "SELECT " + toLocalDate("res_rsv_ruimte_van") + " res_rsv_ruimte_van"
|
|
+ " , " + toLocalDate("res_rsv_ruimte_tot") + " res_rsv_ruimte_tot"
|
|
+ " , res_reservering_key"
|
|
+ " , res_rsv_ruimte_volgnr"
|
|
+ " FROM res_rsv_ruimte"
|
|
+ " WHERE res_rsv_ruimte_key = " + myres_rsv_ruimte_key;
|
|
oRs_vt = Oracle.Execute(sql_vt);
|
|
var mystart = oRs_vt("res_rsv_ruimte_van").Value;
|
|
var myend = oRs_vt("res_rsv_ruimte_tot").Value;
|
|
myres_reservering_nrs = [oRs_vt("res_reservering_key").Value + "/" + oRs_vt("res_rsv_ruimte_volgnr").Value];
|
|
myres = true;
|
|
oRs_vt.Close();
|
|
}
|
|
}
|
|
|
|
if (myres) { // Als we niet zojuist hebben gereserveerd (!submitting), laat dan al je eigen reserveringen zien (if any)
|
|
Response.write("<div class='modconfirm'>"+L("lcl_res_deel_planmode_confirm").format((RuimteMode ? safe.html(res_ruimte_nr) : safe.html(res_deel_omschrijving)),
|
|
toDateString(res_van, { noDay: true, isLocal: true }),
|
|
toTimeString(mystart, { isLocal: true }),
|
|
toTimeString(myend, { isLocal: true }),
|
|
myres_reservering_nrs.join(", "),
|
|
rooturl + "/?u=reservering&k=" + myres_rsv_ruimte_key) + "</div>");
|
|
}
|
|
}
|
|
|
|
if (submitting) // Niet direct weer tijdslots tonen
|
|
timeslotAvailable = false;
|
|
|
|
if (PlanMode)
|
|
{
|
|
// make existing reservations clientside available
|
|
%>
|
|
<script>
|
|
var res_pers = { "<%=user_key%>": [] };
|
|
<%
|
|
var oRs_pers = Oracle.Execute( RuimteMode ? sql : sql_pers );
|
|
while (!oRs_pers.Eof)
|
|
{
|
|
var server_van = new Date(oRs_pers("res_rsv_ruimte_van").Value);
|
|
var server_tot = new Date(oRs_pers("res_rsv_ruimte_tot").Value);
|
|
var local_van = new Date(oRs_pers("local_van").Value);
|
|
var local_tot = new Date(oRs_pers("local_tot").Value);
|
|
%>
|
|
res_pers["<%=user_key%>"].push({
|
|
bezet: "<%=safe.jsstring(oRs_pers("host").Value)%>",
|
|
bezet_key: <%=oRs_pers("host_key").Value%>,
|
|
res_deel_key: <%=(RuimteMode ? "null" : oRs_pers("res_deel_key").Value)%>,
|
|
res_rsv_ruimte_key: <%=oRs_pers("res_rsv_ruimte_key").Value%>,
|
|
res_reservering_nr: "<%=oRs_pers("res_reservering_key").Value + "/" + oRs_pers("res_rsv_ruimte_volgnr").Value%>",
|
|
resvan_ms: <%=local_van.getTime()%>,
|
|
restot_ms: <%=local_tot.getTime()%>
|
|
});
|
|
<%
|
|
oRs_pers.MoveNext();
|
|
}
|
|
oRs_pers.Close();
|
|
%>
|
|
// Gebruikt global res_pers
|
|
async function handle_double_reservations(from, to) {
|
|
var prs_key = $("#person").val();
|
|
if (!res_pers.hasOwnProperty(prs_key)) {
|
|
var data = {
|
|
"prs_key": prs_key,
|
|
"discipline": <%=res_disc_key%>,
|
|
"res_van": <%=res_van.getTime()%>
|
|
}
|
|
await $.post("../RES/get_res_info_ajax.asp?req_info=res_pers",
|
|
data,
|
|
FcltCallbackAndThen((json) => {
|
|
res_pers[prs_key] = json.rsv;
|
|
}), "json");
|
|
}
|
|
|
|
var return_doubles = [];
|
|
var index = 0;
|
|
if (!(prs_key in res_pers)) {
|
|
return false;
|
|
}
|
|
for (index = 0; index < res_pers[prs_key].length; index++) {
|
|
if (from < res_pers[prs_key][index].restot_ms && to > res_pers[prs_key][index].resvan_ms) {
|
|
return_doubles.push(res_pers[prs_key][index]);
|
|
}
|
|
}
|
|
return return_doubles;
|
|
}
|
|
|
|
$(_ => {
|
|
FcltMgr.resized();
|
|
});
|
|
</script>
|
|
<% }
|
|
else if (nubezet)
|
|
{
|
|
%><div class="cbezet"><%
|
|
// We zeggen tot wanneer de huidige reservering loopt. Garandeert niet dat die erna wel vrij is
|
|
// Functioneel zou je je het einde van de laatste (aansluitende) reservering willen laten zien
|
|
// Dus wanneer is-ie weer vrij (binnen de openingstijden).
|
|
// Response.write("<div class='bezet'>"+L("lcl_mobile_ruimtebezet").format(toTimeString(tot))+"</div>"); Staat nu onderaan
|
|
// Dit is eigenlijk niet relevant voor een normale gebruiker
|
|
// maar voor een eventuele noshow wel!
|
|
// KFNS#35010: ook tonen als het toch geen geheim is
|
|
if (user.checkAutorisation("WEB_RESNOS", true) || (planbordTooltipShowing(rsv_ruimte_key) == 0)) {
|
|
if (!times.length) {
|
|
Response.write("<span class='bezetinfo'>" + I("fa-ban fa-xl") + " " + L("lcl_mobile_none_beschik") + "</span>");
|
|
} else if (local_van) {
|
|
Response.write("<span class='bezetinfo'>"+toTimeString(local_van, { isLocal: true })+" - "+toTimeString(local_tot, { isLocal: true })
|
|
+" "+ L("lcl_pda_res_gereserveerd_door")
|
|
+" "+ safe.html(rsv_host) +"/"+ safe.html(rsv_omschrijving)
|
|
+"</span>");
|
|
}
|
|
}
|
|
%></div><%
|
|
}
|
|
else {
|
|
if (!hasImageHeader) // Dan maar saai zonder plaatje
|
|
{
|
|
%><div class="cvrij"><%
|
|
Response.write("<div class='vrij'>"+safe.html(RuimteMode ? res_ruimte_nr : res_deel_omschrijving)+"</div>")
|
|
%></div><%
|
|
local_van = null; // er is geen eerstvolgende in de weg
|
|
}
|
|
}
|
|
|
|
if (timeslotAvailable)
|
|
{
|
|
FCLTpersoonselector("person",
|
|
"sgPerson",
|
|
{ label: L("lcl_res_reserve_for"),
|
|
perslidKey: !authRES.canWrite("WEB_RESFOF") || S("res_fo_default_user") ? user_key : -1,
|
|
autlevel: authRES._funcodes["WEB_RESFOF"] && authRES._funcodes["WEB_RESFOF"].PRSwritelevel,
|
|
required: true,
|
|
hidden: !authRES.canWrite("WEB_RESFOF"),
|
|
mobile: true,
|
|
embedded: true
|
|
});
|
|
|
|
// Flexkenmerken
|
|
generateFlexKenmerkBlock({ urole: urole,
|
|
disc_key : res_disc_key,
|
|
act_key_arr : (res_activiteit_key > -1) ? [res_activiteit_key] : [],
|
|
rsv_ruimte_key: -1,
|
|
reado: false,
|
|
reqId: user_key,
|
|
mobile: true
|
|
});
|
|
}
|
|
|
|
if (PlanMode)
|
|
{
|
|
if (!submitting && timeslot_radios.length)
|
|
{
|
|
if (timeslotAvailable) {
|
|
Response.write("<div class='modhint text-center'>"+L("lcl_res_deel_planmode_hint" + (submitting ? "2" : "1")).format(toDateString(res_van, { isLocal: true }).toLowerCase(), res_deel_opmerking||"")+"</div>");
|
|
}
|
|
CONTROLGROUP_START({ id: "bloktijden" });
|
|
RADIO_GROUP("timeslots", timeslot_radios, { big: true });
|
|
CONTROLGROUP_END();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!submitting && timeslot_radios.length)
|
|
{
|
|
CONTROLGROUP_START({ id: "adhoctijden" });
|
|
RADIO_GROUP("timeslots", timeslot_radios, { big: true });
|
|
CONTROLGROUP_END();
|
|
}
|
|
|
|
if (nubezet && now - local_van > res_noshowgrace
|
|
&& res_noshowgrace > -1 /* EN minstens res_noshowgrace na aanvang */
|
|
&& !DeelMode // ondersteunen we (nog) niet
|
|
&& user.checkAutorisation( "WEB_RESNOS", true))
|
|
{
|
|
if (rsv_ruimte_key > 0 && S("res_noshow_detailed") == 1)
|
|
{
|
|
var bezoekers_aantal = (bezoekers_shown ? bezoekers_shown : bezoekers_expected);
|
|
RWFIELD("bezshown", L("lcl_res_real_visitors") , bezoekers_aantal, {datatype: "number", maxlength: 5});
|
|
BUTTON(L("lcl_res_show"), {click: "resCountShow("+rsv_ruimte_key+")", icon: "fa-check"});
|
|
}
|
|
else
|
|
{
|
|
// Maybe next time: BUTTON(L("lcl_res_show"), {click: "resShow("+rsv_ruimte_key+", 1)", icon: "fa-check"});
|
|
BUTTON(L("lcl_res_no_show"), {click: "resShow("+rsv_ruimte_key+", 0)", icon: "fa-times"});
|
|
}
|
|
}
|
|
}
|
|
|
|
if (timeslotAvailable)
|
|
{
|
|
CONTROLGROUP_START({ horizontal: true });
|
|
BUTTON( L("lcl_submit")
|
|
, { click: "res_submit()"
|
|
, icon: myres ? "fa-plus" : "fa-fclt-save"
|
|
, singlepress: true
|
|
});
|
|
BUTTON( submitting ? L("lcl_close_window") : L("lcl_cancel")
|
|
, { click: "if (modal == 1) {FcltMgr.closeDetail(window, { cancel: true }); } else { window.location.href = 'Facilitor.asp'; }"
|
|
, icon: (submitting ? "fa-check" : "fa-fclt-cancel")
|
|
, singlepress: true
|
|
});
|
|
CONTROLGROUP_END();
|
|
// opslaan
|
|
// annuleren
|
|
}
|
|
else
|
|
{
|
|
CONTROLGROUP_START();
|
|
%>
|
|
<script>
|
|
function inviteColleagues()
|
|
{
|
|
var url = "../pda/wp_add.asp?urole=<%=urole%>&ismobile=<%=isMobile%>"
|
|
+ "&modal=" + modal
|
|
+ "&rsv_copy_key=<%=myres_rsv_ruimte_key%>"
|
|
+ "#page-2-<%=myres_rsv_ruimte_key%>"; // Direct door naar het kiezen van de werkplek
|
|
window.location.href = url;
|
|
}
|
|
|
|
function btn_ready()
|
|
{
|
|
if (modal == 1)
|
|
{
|
|
FcltMgr.closeDetail(window, { cancel: true });
|
|
}
|
|
else
|
|
{
|
|
window.location.href = 'Facilitor.asp';
|
|
};
|
|
}
|
|
</script>
|
|
<%
|
|
var sql = "SELECT " + lcl.xsql("d.ins_discipline_omschrijving", "d.ins_discipline_key") + " disc_name"
|
|
+ " , ins_discipline_min_level"
|
|
+ " FROM ins_tab_discipline d"
|
|
+ " WHERE d.ins_discipline_key = " + res_disc_key;
|
|
var oRs = Oracle.Execute(sql);
|
|
var res_disc_name = oRs("disc_name").Value;
|
|
var isWerkplekCatalogus = oRs("ins_discipline_min_level").Value == 5;
|
|
oRs.Close();
|
|
if (isWerkplekCatalogus && myres_rsv_ruimte_key) { // myres_rsv_ruimte_key is alleen defined als het om mijn reservering gaat, en deze knop moet er alleen dan staan
|
|
// aantal beschikbare werkplekken
|
|
var beschikbaar_sql = res.getNearestWP_sql(myres_rsv_ruimte_key, {});
|
|
var oRs = Oracle.Execute("SELECT COUNT(*) aantal FROM ("+beschikbaar_sql+")");
|
|
var max_aantal = oRs("aantal").Value;
|
|
oRs.Close();
|
|
if (max_aantal > 0)
|
|
{
|
|
BUTTON( L("lcl_res_werkplek_extra").format("", res_disc_name)
|
|
, { id: "uitnodiging"
|
|
, click: "inviteColleagues()"
|
|
, icon: "fa-user-plus"
|
|
, singlepress: true
|
|
});
|
|
}
|
|
}
|
|
BUTTON( L("lcl_pda_ready")
|
|
, { click: "btn_ready()"
|
|
, icon: "fa-check"
|
|
, singlepress: true
|
|
});
|
|
CONTROLGROUP_END();
|
|
}
|
|
}
|
|
FORM_END();
|
|
/* Hier een stukje om te illustreren hoe de nabije toekomst van dit object er uit ziet */
|
|
if (!PlanMode) {
|
|
if (helemaalvrij) { %>
|
|
<div class="next-res-title"><%=L("lcl_mobile_rsv_next")%></div>
|
|
<div class="next-res-descr"><%=L("lcl_none")%></div>
|
|
<% } else {
|
|
var local_van = schoonvan || local_van;
|
|
var isToday = !PlanMode || new Date().midnight().getTime() === new Date(local_van).midnight().getTime();
|
|
var local_van = isToday ? toTimeString(local_van, { isLocal: true }) : toDateTimeString(local_van, { noDay: true, noMidnight: true, isLocal: true });
|
|
var local_tot = isToday ? toTimeString(local_tot, { isLocal: true }) : toDateTimeString(local_tot, { noDay: true, noMidnight: true, isLocal: true });
|
|
if (nubezet || lopendeRes) {
|
|
if (lopendeRes) { %>
|
|
<div class="next-res-title"><%=I("fa-exclamation-triangle")%></div>
|
|
<% } %>
|
|
<div class="next-res-descr"><%=L("lcl_mobile_ruimtebezet").format(local_tot)%></div>
|
|
<% } else if (!myres) { %>
|
|
<div class="next-res-title"><%=L("lcl_mobile_rsv_next")%></div>
|
|
<div class="next-res-descr"><%=local_van%> tot <%=local_tot%>: <%=L("lcl_pda_res_gereserveerd_door")+" " +safe.html(rsv_host) +"/"+ safe.html(rsv_omschrijving)%></div>
|
|
<% }
|
|
}
|
|
}
|
|
CONTENT_END();
|
|
FOOTER({modal: qrc});
|
|
PAGE_END();
|
|
PDA_PAGE_END(); %>
|
|
</body>
|
|
</html>
|
|
<% ASPPAGE_END(); %>
|