Files
Facilitor/APPL/PDA/reserveringen.asp
Erik Groener 2154db4a27 MENZ#87867 Werkplek lijkt dubbel bezet
svn path=/Website/trunk/; revision=71072
2025-11-27 11:05:30 +00:00

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(); %>