<% /*
     $Revision$
     $Id$
*/ %>

<!-- #include file="../Shared/status.inc" -->

<%
bez =
{
    getgebouwterrein_sql:
        function (bez_afspraak_begin, bez_afspraak_eind, locatie_key)
        {
          // Wat zijn voor mij geldige terreinen?
            // JGL: Onderstaande joint alg_v_aanwezigterreinsector terwijl die ook
            //       al in  alg_v_allonrgoed_gegevens zit. Die heeft helaas
            //       t.prs_afdeling_key (nog) niet

            var sql_terr = "SELECT alg_terreinsector_key"
                         + "  FROM alg_v_aanwezigterreinsector t WHERE 1=1";
            var pafparams = user.checkAutorisation("WEB_BEZPAF", true);
            var autlevel = 9;
            if (pafparams)
            {
                autlevel = pafparams.PRSwritelevel;
            }
            if (autlevel == 9)
            {
                sql_terr += " AND t.prs_afdeling_key is null"; // efficient
            }
            else if (autlevel > 0)
            {
                sql_terr += " AND (t.prs_afdeling_key is null or t.prs_afdeling_key IN "
                          + "    (SELECT prs_afdeling_key FROM prs_v_afdeling_familie a"
                          + "      WHERE a.prs_afdeling_elder_key IN"
                          + "        (SELECT aa.prs_afdeling_elder_key"
                          + "           FROM prs_v_afdeling_familie aa"
                          + "          WHERE aa.prs_afdeling_key = " + user.prs_afdeling_key()
                          + "            AND aa.niveau = " + autlevel + ")))";
            }
            else if (autlevel == 0)
            {
                sql_terr += " AND (t.prs_afdeling_key is null or t.prs_afdeling_key IN (SELECT a.prs_afdeling_key"
                          + " FROM prs_v_afdeling a"
                          + " WHERE a.prs_bedrijf_key = " + user.afdeling().prs_bedrijf_key() + " ))";
            }

          var preposttime = "(SELECT COALESCE(rdp.res_disc_params_preposttime, 0) / 24"
                          + "  FROM res_disc_params rdp"
                          + " WHERE rdp.res_ins_discipline_key = " + S("vis_parking_key") + ")";

          return   " SELECT park.alg_type"
                 + ", park.alg_gebouw_key"
                 + ", park.gebouw_naam"
                 + ", park.gebouw_toon_telefoon"
                 + ", park.gebouw_toon_email"
                 + ", park.gebouw_toon_kenteken"
                 + ", park.alg_terreinsector_key"
                 + ", park.terreinsector_naam"
                 + ", park.alg_onroerendgoed_omschrijving"
                 + ", COUNT (park.alg_gebouw_key) aantalr"
                 + ", COUNT (park.alg_terreinsector_key) aantalt"
                 + ", COUNT (park.reserved) bezet"
                 + ", CASE park.alg_type"
                   + " WHEN 'R'"
                   + " THEN COUNT (park.alg_gebouw_key) - COUNT (park.reserved)"
                   + " ELSE COUNT (park.alg_terreinsector_key) - COUNT (park.reserved)"
                   + " END vrij"
                 + " FROM"
                   + " (SELECT org.alg_type"
                   + ", org.alg_gebouw_key"
                   + ", org.alg_gebouw_code || ' ' || org.alg_gebouw_naam gebouw_naam"
                   + ", org.alg_gebouw_toon_telefoon gebouw_toon_telefoon"
                   + ", org.alg_gebouw_toon_email gebouw_toon_email"
                   + ", org.alg_gebouw_toon_kenteken gebouw_toon_kenteken"
                   + ", org.alg_terreinsector_key"
                   + ", org.alg_terreinsector_code || ' ' || org.alg_terreinsector_naam terreinsector_naam"
                   + ", org.alg_onroerendgoed_omschrijving"
                   + ", (SELECT MIN (rd.res_deel_key)"
                     + " FROM res_v_aanwezigrsv_deel rd"
                     + " WHERE d.res_deel_key = rd.res_deel_key"
                     + " AND rd.res_rsv_deel_van BETWEEN TRUNC(" + bez_afspraak_begin.toSQL(true) + ")"
                       + " AND " + bez_afspraak_eind.toSQL(true) + " - 1 / 1440 + " + preposttime
                     + " AND rd.res_rsv_deel_tot BETWEEN"
                       + " " + bez_afspraak_begin.toSQL(true) + " + 1 / 1440 - " + preposttime
                       + " AND TRUNC(" + bez_afspraak_eind.toSQL(true) + ")" + " + 1"
                       + " AND rd.res_rsv_deel_van < " + bez_afspraak_eind.toSQL(true) + " - 1 / 1440 + " + preposttime
                       + " AND rd.res_rsv_deel_tot > " + bez_afspraak_begin.toSQL(true) + " + 1 / 1440 - " + preposttime
                       + " AND d.res_discipline_key = " + S("vis_parking_key") + ") reserved"
                   + " FROM res_v_aanwezigdeel d"
                   + ", ins_v_aanwezigdeel id"
                   + ", alg_v_allonrgoed_gegevens org"
                   + " WHERE d.res_ins_deel_key = id.ins_deel_key"
                   + " AND id.ins_alg_ruimte_key = org.alg_onroerendgoed_keys"
                   + " AND (id.ins_deel_vervaldatum IS NULL OR id.ins_deel_vervaldatum > TRUNC(SYSDATE))"
                   + (locatie_key > -1
                     ? " AND id.ins_alg_locatie_key = " + locatie_key
                     : "")
                   + " AND (org.alg_type = 'R'"
                    + "     OR (org.alg_type = 'T' AND org.alg_terreinsector_key IN (" + sql_terr + ")))"
                   // Is de parkeerplaats reserveerbaar op de begindag. Meerdaagse parkeerplaatsen worden niet ondersteund.
                   // (bits & (2^(dow-1))) = (2^(dow-1))
                   + " AND BITAND(d.res_deel_beschikbaar_bits,"
                   + "            POWER(2,"
                   + "                  (fac.getweekdaynum(TRUNC(" + bez_afspraak_begin.toSQL(true) + ")) - 1))) ="
                   + "     POWER(2, (fac.getweekdaynum(TRUNC (" + bez_afspraak_begin.toSQL(true) + ")) - 1))"
                   + " AND d.res_discipline_key = " + S("vis_parking_key")
                   + " AND (   d.res_deel_vervaldatum IS NULL "
                   + "      OR d.res_deel_vervaldatum > " + bez_afspraak_begin.toSQL(true) + " ) ) park"
                 + " GROUP BY park.alg_type"
                 + ", park.alg_gebouw_key"
                 + ", park.gebouw_naam"
                 + ", park.gebouw_toon_telefoon"
                 + ", park.gebouw_toon_email"
                 + ", park.gebouw_toon_kenteken"
                 + ", park.alg_terreinsector_key"
                 + ", park.terreinsector_naam"
                 + ",  park.alg_onroerendgoed_omschrijving"
                 + " ORDER BY terreinsector_naam, gebouw_naam";
        },

    bez_getnewdates: function _bez_getnewdates(params)
        {
          var result = {};
          var bez_new_dates = [];
          var limitDate = null;
          var limiet = ((params.urole== "fe" && S("vis_fe_afspraak_limiet") > 0) ? S("vis_fe_afspraak_limiet") : S("vis_afspraak_limiet"));
          if (limiet > 0)
          {
            limitDate = new Date();
            limitDate.setDate(limitDate.getDate() + limiet);
          }
          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, ismjob); (Moment modus dus geen mjob)
            var ora_date1 = nextDate.beginToSQL();
            var sql = "SELECT fac.nextcyclusdate (" + ora_date1 + ", 0, 3, 1, " + params.bits + ", 1, 0) 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();
            if (limitDate && nextDate > limitDate)
            {
              overflow = true;
              break;
            }
            // Checkbox "Alleen werkdagen" is niet aanwezig voor "Maandelijks". Hiermee dus geen rekening houden.
            bez_new_dates.push(nextDate.getTime());
          };

          var result = { bez_new_dates: bez_new_dates, message: message };
          if (overflow)
            result.message += (message != ""? "<br>" : "") + L("lcl_bez_date_limit_reached") + toDateString(limitDate);

          return result;
        },

    bez_getnrperiods: function _bez_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 bez_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);
            bez_steps = oRs("steps").Value;
            oRs.Close();
          }
          var result = { bez_steps: bez_steps, message: message };

          return result;
        },

    bez_prkinfo:
        function (loc_key, bez_afspraak_begin, bez_afspraak_eind)
        {
            var gebtersql = bez.getgebouwterrein_sql(bez_afspraak_begin, bez_afspraak_eind, loc_key);
            var oRs = Oracle.Execute(gebtersql);

            var prk_bezet = 0;
            var prk_vrij = 0;
            var prk_array = [];
            while (!oRs.eof)
            {
              prk_bezet += oRs("bezet").Value;
              prk_vrij += oRs("vrij").Value;
              var alg_type = oRs("alg_type").Value;
              prk_array.push({key: (alg_type == "R"? oRs("alg_gebouw_key").Value : oRs("alg_terreinsector_key").Value),
                              naam: (alg_type == "R"? oRs("gebouw_naam").Value : oRs("terreinsector_naam").Value) + " [" + (oRs("vrij").Value > 0? oRs("vrij").Value + " - " + L("lcl_bez_vrij") : L("lcl_bez_vol")) + "]",
                              bezet: oRs("bezet").Value,
                              vrij: oRs("vrij").Value,
                              toon_telefoon: oRs("gebouw_toon_telefoon").Value,
                              toon_email: oRs("gebouw_toon_email").Value,
                              toon_kenteken: oRs("gebouw_toon_kenteken").Value
                             });
              oRs.MoveNext();
            }
            oRs.Close();
            result = {loc_key: loc_key,
                      prk_aantal: prk_bezet + prk_vrij,
                      prk_bezet: prk_bezet,
                      prk_vrij: prk_vrij,
                      prk_array: prk_array};

            return result;
        },

    bez_getactiegroep:
        function _bez_getactiegroep(bld_key)
        {
            var actiegrp_key = -1;
            var sql = "SELECT actie_groep_key"
                    + "  FROM ( SELECT COALESCE( a.bez_actie_groep_key"
                                           + " , (SELECT MIN(bez_actie_groep_key)"
                                           + "      FROM bez_actie_groep"
                                           + "     WHERE bez_actie_groep_verwijder IS NULL"
                                           + "       AND bez_actie_groep_default = 1"
                                           + "   )"
                                           + " , (SELECT MIN(bez_actie_groep_key)"
                                           + "      FROM bez_actie_groep"
                                           + "     WHERE bez_actie_groep_verwijder IS NULL"
                                           + "   )"
                                           + " ) actie_groep_key"
                             + "  FROM alg_gebouw a"
                             + " WHERE alg_gebouw_key = " + bld_key
                    + "       )"
                    + " WHERE actie_groep_key IS NOT NULL";
            var oRs = Oracle.Execute(sql);
            if (!oRs.eof)
            {
                actiegrp_key = oRs("actie_groep_key").Value;
            }
            oRs.Close();
            return actiegrp_key;
        },

    bez_getacties:
        function _bez_getacties(loc_arr, bld_arr, show_groep)
        {
            var locatie_key_arr = loc_arr;
            var gebouw_key_arr = bld_arr;
            if (gebouw_key_arr.length == 0 && locatie_key_arr.length > 0)
            {   // Gebouwen van locatie(s).
                var sql = "SELECT alg_gebouw_key"
                        + "  FROM alg_gebouw"
                        + " WHERE alg_gebouw_verwijder IS NULL"
                        + "   AND alg_locatie_key IN (" + locatie_key_arr.join(",") + ")";
                var oRs = Oracle.Execute(sql);
                while (!oRs.eof)
                {
                    gebouw_key_arr.push(oRs("alg_gebouw_key").Value);
                    oRs.MoveNext();
                }
                oRs.Close();
            }

            // actie_groepen van gebouwen.
            var actiegroep_arr = [];
            if (gebouw_key_arr.length > 0)
            {
                var sql = "SELECT actie_groep"
                        + "  FROM ( SELECT COALESCE( bez_actie_groep_key"              // actie_groep van gebouw heeft hoogste prioriteit
                                + "                , (SELECT MIN(bez_actie_groep_key)" // Als gebouw geen actie_groep heeft neem dan de default waarde
                                + "                     FROM bez_actie_groep"
                                + "                    WHERE bez_actie_groep_verwijder IS NULL"
                                + "                      AND bez_actie_groep_default = 1"
                                + "                  )"
                                + "                , (SELECT MIN(bez_actie_groep_key)" // Als er voor geen enkele actie_groep de default is gezet
                                + "                     FROM bez_actie_groep"          // neem dan maar de eerste.
                                + "                    WHERE bez_actie_groep_verwijder IS NULL"
                                + "                  )"
                                + "                ) actie_groep"
                                + "   FROM alg_gebouw"
                                + "  WHERE alg_gebouw_key IN (" + gebouw_key_arr.join(",") + ")"
                        + "       )"
                        + " WHERE actie_groep IS NOT NULL";
                var oRs = Oracle.Execute(sql);
                while (!oRs.eof)
                {
                    actiegroep_arr.push(oRs("actie_groep").Value);
                    oRs.MoveNext();
                }
                oRs.Close();
            }

            // Als er maar uit 1 actiegroep geselecteerd wordt dan hoeft de actiegroep er niet bij.
            show_groep = show_groep && (actiegroep_arr.length > 1);

            // de mogelijke bez_actie-s bij deze gebouwen.
            var sql = "SELECT a.bez_actie_key"
                    + "     , " + lcl.xsql("a.bez_actie_omschrijving", "a.bez_actie_key")
                                + ( show_groep
                                  ? "||' ('|| g.bez_actie_groep_omschrijving ||')'"
                                  : ""
                                  )
                                + " bez_actie_omschrijving"
                    + "     , bez_actie_default"
                    + "  FROM bez_actie a"
                    + "     , bez_actie_groep g"
                    + " WHERE a.bez_actie_groep_key = g.bez_actie_groep_key(+)"
                    + "   AND a.bez_actie_verwijder IS NULL"
                    + "   AND g.bez_actie_groep_verwijder IS NULL"
                    + "   AND BITAND(a.bez_actie_flags, 1) = 0" // Niet de oproepers, die alleen via reservering
                    + ( actiegroep_arr.length > 0
                      ? " AND a.bez_actie_groep_key IN (" + actiegroep_arr.join(",") + ")"
                      : " AND a.bez_actie_groep_key = (SELECT MIN(bez_actie_groep_key)"
                                                    + "  FROM bez_actie_groep"
                                                    + " WHERE bez_actie_groep_verwijder IS NULL"
                                                    + "   AND bez_actie_groep_default = 1"
                                                    + ")"
                      )
                    + " ORDER BY g.bez_actie_groep_omschrijving"
                    + "        , a.bez_actie_omschrijving";
            var result = [];
            var oRs = Oracle.Execute(sql);
            while (!oRs.eof)
            {
                result.push( {key: oRs("bez_actie_key").Value, omschr: oRs("bez_actie_omschrijving").Value, isdefault: oRs("bez_actie_default").Value });
                oRs.MoveNext();
            }
            oRs.Close();
            return {sql: sql, data: result};
        },

    bez_fields:
        function _bez_fields(params)
        {
            params = params || {};

            var sql = " SELECT alg_type"
                    + "      , alg_gebouw_key"
                    + "      , alg_terreinsector_key"
                    + "      , alg_gebouw_toon_telefoon"
                    + "      , alg_gebouw_toon_email"
                    + "      , alg_gebouw_toon_kenteken"
                    + "   FROM alg_v_allonrgoed_gegevens"
                    + "  WHERE alg_type = 'G'"
                    + (params.bld_key > 0
                      ? "  AND alg_gebouw_key = "  + params.bld_key   // Hier zijn geen terreinen te kiezen
                      : (params.loc_key > 0
                        ? "  AND alg_locatie_key = " + params.loc_key
                        : ""));
            var oRs = Oracle.Execute(sql);

            var result = [];
            while (!oRs.eof)
            {
                var alg_type = oRs("alg_type").Value;
                result.push({
                    key: (alg_type == "G" ? oRs("alg_gebouw_key").Value : oRs("alg_terreinsector_key").Value),
                    toon_telefoon: oRs("alg_gebouw_toon_telefoon").Value,
                    toon_email: oRs("alg_gebouw_toon_email").Value,
                    toon_kenteken: oRs("alg_gebouw_toon_kenteken").Value
                });
                oRs.MoveNext();
            }
            oRs.Close();
            return result;
        },

    moveAfspraakTracking:
        // Als de afspraak van een reservering is verwijderd dan tracking van afspraak onder die reservering hangen (enigszins illegaal).
        function _moveAfspraakTracking(afspraak_key, rsv_ruimte_key)
        {
            if (!rsv_ruimte_key)
            {
                // Is dit een afspraak van een reservering?
                var sql = "SELECT res_rsv_ruimte_key"
                        + "  FROM bez_afspraak "
                        + " WHERE bez_afspraak_key = " + afspraak_key;
                var oRs = Oracle.Execute(sql);
                if (oRs.EoF || !oRs("res_rsv_ruimte_key").value)
                {
                    oRs.Close();
                    return; // quick exit
                }

                var rsv_ruimte_key = oRs("res_rsv_ruimte_key").value;
                oRs.Close();
            }

            var sql = "SELECT sn.fac_srtnotificatie_key"
                    + "  FROM fac_srtnotificatie sn"
                    + " WHERE sn.fac_srtnotificatie_code LIKE 'RESUPD'";
            var oRs = Oracle.Execute(sql);
            var snkeyRESUPD = oRs("fac_srtnotificatie_key").value;
            oRs.Close();

            // Alle tracking die een omschrijving heeft kan direct omgezet worden
            sql = "UPDATE fac_tracking"
                + "   SET fac_srtnotificatie_key = " + snkeyRESUPD
                + "     , fac_tracking_refkey = " + rsv_ruimte_key
                + " WHERE fac_tracking_key IN"
                + "       (SELECT ft.fac_tracking_key"
                + "          FROM fac_tracking ft"
                + "             , fac_srtnotificatie sn"
                + "         WHERE ft.fac_srtnotificatie_key = sn.fac_srtnotificatie_key"
                + "           AND sn.fac_srtnotificatie_code LIKE 'BEZ%'"
                + "           AND ft.fac_tracking_oms IS NOT NULL"
                + "           AND fac_tracking_refkey = " + afspraak_key + ")";
            Oracle.Execute(sql);

            // Alle tracking die geen omschrijving heeft, de omschrijving vullen met standaard srtnotificatietext (fallback voor ongedefineerde teksten)
            sql = "SELECT ft.fac_tracking_key"
                + "     , sn.fac_srtnotificatie_code"
                + "  FROM fac_tracking ft"
                + "     , fac_srtnotificatie sn"
                + " WHERE ft.fac_srtnotificatie_key = sn.fac_srtnotificatie_key"
                + "   AND sn.fac_srtnotificatie_code LIKE 'BEZ%'"
                + "   AND ft.fac_tracking_oms IS NULL"
                + "   AND fac_tracking_refkey = " + afspraak_key;
            oRs = Oracle.Execute(sql);
            while (!oRs.EoF)
            {
              sql = "UPDATE fac_tracking"
                  + "   SET fac_srtnotificatie_key = " + snkeyRESUPD
                  + "     , fac_tracking_refkey = " + rsv_ruimte_key
                  + "     , fac_tracking_oms = " + safe.quoted_sql(status.getsrtnotificatietext(oRs("fac_srtnotificatie_code").value))
                  + " WHERE fac_tracking_key = " + oRs("fac_tracking_key").value;
              Oracle.Execute(sql);
              oRs.MoveNext();
            }
            oRs.Close();
        },

    deleteAfspraak:
        function _deleteAfspraak(pAfspr_key)
        {
          var pResult = new HookResult();
          var bez_arr = [];
          var sql = "SELECT b.bez_bezoekers_key"
                  + "  FROM bez_bezoekers b"
                  + " WHERE b.bez_afspraak_key = " + pAfspr_key;
          var oRs = Oracle.Execute(sql);
          while (!oRs.eof)
          {
            bez_arr.push(oRs("bez_bezoekers_key").Value);
            oRs.MoveNext();
          }
          oRs.Close();

          for (var i=0; i<bez_arr.length; i++)
          {
            if (!custfunc.bez_predelete(bez_arr[i], pResult))
            {
              abort_with_warning(pResult.errmsg);
            }
          }

          var sql = "DELETE FROM bez_afspraak"
                  + " WHERE bez_afspraak_key = " + pAfspr_key;
          Oracle.Execute(sql);

          for (var i=0; i<bez_arr.length; i++)
          {
            if (!custfunc.bez_postdelete(bez_arr[i], pResult))
            {
              abort_with_warning(pResult.errmsg);
            }
          }
        },

    // Verwijder afspraak als geen enkele bezoeker over.
    cleanAfspraak:
        function _cleanAfspraak(pAfspr_key, moveTracking)
        {
            var sql = "SELECT count(*)"
                    + "  FROM bez_bezoekers b"
                    + " WHERE b.bez_afspraak_key = " + pAfspr_key;
            var oRs = Oracle.Execute(sql);

            var count_bez = oRs(0).Value;

            var deleted = false;
            if (count_bez == 0)
            {
              if (moveTracking)
                bez.moveAfspraakTracking(pAfspr_key);
              bez.deleteAfspraak(pAfspr_key);
              deleted = true;
            }
            oRs.Close();
            return deleted;
        },

    deleteBezoekers:
        function _deleteBezoekers(pBez_key, clean, moveTracking)
        {
          var pResult = new HookResult();
          var lmessage;
          // Gooi een bezoeker weg. Als het de enige is, dan wordt de
          // afspraak ook verwijderd, anders niet
          var sql = "SELECT b.bez_afspraak_key"
                  + "  FROM bez_bezoekers b"
                  + " WHERE b.bez_bezoekers_key = " + pBez_key;
          var oRs = Oracle.Execute(sql);
          // Extra controle tbv nogmaals deleten van een zojuist gedelete
          if (!oRs.eof)
          {
              var afspr_key = oRs(0).Value;
              if (!custfunc.bez_predelete(pBez_key, pResult))
              {
                abort_with_warning(pResult.errmsg);
              }

              // delete parking place is done by database cascade constraint
              sql = "DELETE FROM bez_bezoekers"
                  + " WHERE bez_bezoekers_key = " + pBez_key;
              Oracle.Execute(sql);

              if (!custfunc.bez_postdelete(pBez_key, pResult))
              {
                abort_with_warning(pResult.errmsg);
              }

              if (clean)
                var afspr_deleted = bez.cleanAfspraak(afspr_key, moveTracking);
          } else {
             lmessage = L("lcl_bez_already_deleted");
          }
          oRs.Close();
          return lmessage;
        },

    trackafspraakupdate:
        // Let op: dit moet wellicht niet altijd (aangeroepen na save)
        function (bez_key, ptxt, noNoti)
        {
            shared.trackaction((noNoti ? "#" : "") + "BEZUPD", bez_key, ptxt);
        },

    func_enabled_parkeerplaats: // Wat mag ik op parkeerplaatsen?
        function _func_enabled_parkeerplaats()
        {
            var authparams = user.checkAutorisation("WEB_BEZPRK", true);
            return { canWritePrk: authparams && authparams.PRSwritelevel < 9 && authparams.ALGwritelevel < 9 }
        },

    bez_afspraak_info:
        function _bez_afspraakinfo(afspr_key)
        {
            var sql = "SELECT ba.prs_perslid_key invoerder_key"
                    + "     , ba.bez_afspraak_gastheer gastheer"
                    + "     , ba.bez_afspraak_telefoonnr"
                    + "     , ba.bez_afspraak_datum"
                    + "     , ba.bez_afspraak_eind"
                    + "     , ba.bez_actie_key actie_key"
                    + "     , ba.bez_afspraak_ruimte"
                    + "     , COALESCE( ba.bez_afspraak_ruimte"
                    + "         , CASE WHEN ba.alg_onrgoed_keys IS NULL"
                    + "                THEN (SELECT alg_locatie_code FROM alg_locatie WHERE alg_locatie_key = ba.alg_locatie_key)"
                    + "                ELSE (SELECT alg_plaatsaanduiding FROM alg_v_allonrgoed_gegevens WHERE alg_onroerendgoed_keys = ba.alg_onrgoed_keys)"
                    + "           END"
                    + "         ) bez_afspraak_ruimte_code"
                    + "     , ba.bez_afspraak_opmerking"
                    + "     , " + lcl.xsqla('x.bez_actie_omschrijving', 'x.bez_actie_key')
                    + "     , ba.alg_locatie_key locatie_key"
                    + "     , ba.alg_onrgoed_keys alg_onrg_key"
                    + "     , ba.bez_afspraak_host_key gastheer_key"
                    + "     , ba.bez_afspraak_contact_key contact_key"
                    + "     , ba.res_rsv_ruimte_key"
                    + "     , ba.mld_opdr_key"
                    + "     , " + S("prs_pers_string") + " aanvrager"
                    + "     , rrr.res_reservering_key"
                    + "     , rrr.res_rsv_ruimte_volgnr"
                    + "     , rrr.res_rsv_ruimte_omschrijving"
                    + "     , rr.res_ruimte_extern_id"
                    + "     , rrr.res_activiteit_key"
                    + "  FROM bez_afspraak ba"
                    + "     , prs_perslid p"
                    + "     , bez_actie x"
                    + "     , res_rsv_ruimte rrr"
                    + "     , res_ruimte_opstelling ro"
                    + "     , res_ruimte rr"
                    + " WHERE ba.bez_afspraak_contact_key = p.prs_perslid_key"
                    + "   AND ba.bez_actie_key = x.bez_actie_key(+)"
                    + "   AND ba.res_rsv_ruimte_key = rrr.res_rsv_ruimte_key(+)"
                    + "   AND rrr.res_ruimte_opstel_key = ro.res_ruimte_opstel_key(+)"
                    + "   AND ro.res_ruimte_key = rr.res_ruimte_key(+)"
                    + "   AND ba.bez_afspraak_key = " + afspr_key;
            var oRs = Oracle.Execute(sql);
            if (oRs.Eof)
             shared.record_not_found("<!--" + afspr_key + "-->");

            var result = { invoerder_key: oRs("invoerder_key").Value,
                           gastheer: oRs("gastheer").Value,
                           contact_key: oRs("contact_key").Value,
                           aanvrager: oRs("aanvrager").Value,
                           telf_nr: oRs("bez_afspraak_telefoonnr").Value,
                           bez_afspraak_datum: new Date(oRs("bez_afspraak_datum").Value),
                           bez_afspraak_eind: new Date(oRs("bez_afspraak_eind").Value),
                           actie_key: oRs("actie_key").Value,
                           ruimte: oRs("bez_afspraak_ruimte").Value,
                           ruimte_code: oRs("bez_afspraak_ruimte_code").Value,
                           opm: oRs("bez_afspraak_opmerking").Value,
                           actie_omschrijving: oRs("bez_actie_omschrijving").Value,
                           locatie_key: oRs("locatie_key").Value,
                           alg_onrg_key: oRs("alg_onrg_key").Value,
                           res_rsv_ruimte_key: oRs("res_rsv_ruimte_key").Value,
                           mld_opdr_key: oRs("mld_opdr_key").Value,
                           gastheer_key: oRs("gastheer_key").Value,
                           res_reservering_key: oRs("res_reservering_key").Value,
                           res_rsv_ruimte_volgnr: oRs("res_rsv_ruimte_volgnr").Value,
                           res_rsv_ruimte_omschrijving: oRs("res_rsv_ruimte_omschrijving").Value,
                           res_ruimte_extern: oRs("res_ruimte_extern_id").Value != null,
                           activiteit_key: oRs("res_activiteit_key").Value
                          };
            oRs.Close();

            if (result.ruimte)
            {   // Voor afspraak die niet aan reservering gekoppeld is de plaatsaanduiding
               //  terug herleiden naar ruimtenummer + ruimteomschrijving.
                var sql = "SELECT o.alg_onroerendgoed_code ||"
                        + "       CASE WHEN o.alg_onroerendgoed_omschrijving IS NOT NULL"
                        + "            THEN ' (' || o.alg_onroerendgoed_omschrijving || ')'"
                        + "            ELSE ''"
                        + "       END ruimte_code"
                        + "  FROM alg_v_plaatsaanduiding p"
                        + "     , alg_v_allonrgoed_gegevens o"
                        + " WHERE p.alg_onroerendgoed_keys = o.alg_onroerendgoed_keys"
                        + "   AND p.alg_onroerendgoed_type = o.alg_type"
                        + "   AND p.alg_plaatsaanduiding = " + safe.quoted_sql(result.ruimte)
                        + "   AND o.alg_locatie_key = " + result.locatie_key;
                var oRs = Oracle.Execute(sql);
                if (!oRs.eof)
                {
                    result.ruimte_code = oRs("ruimte_code").Value;
                }
                oRs.Close();
            }

            // Voor een reserervingsafspraak wil ik wat activiteitsinfo weten.
            if (result.activiteit_key > 0)
            {
              var sql = "SELECT res_activiteit_image"
                        + ", " + lcl.xsqla("a.res_activiteit_omschrijving", "a.res_activiteit_key")
                        + "  FROM res_activiteit a"
                        + " WHERE res_activiteit_key = " + result.activiteit_key;
              var oRs = Oracle.Execute(sql);
              if (oRs.Eof)
                shared.record_not_found("<!--" + result.activiteit_key + "-->");

              result.activiteit_image = oRs("res_activiteit_image").Value || "fa-users"; // zo doen we dat bij RES ook
              result.activiteit_omschrijving = oRs("res_activiteit_omschrijving").Value;
              oRs.Close();
            }

            // Voor een meldingen opdrachtafspraak wil ik wat vakgroep-melding info weten.
            if (result.mld_opdr_key > 0)
            {
              var sql = "SELECT mto.mld_typeopdr_image"
                      + "     , td.ins_discipline_omschrijving || ' / ' || sm.mld_stdmelding_omschrijving stdmelding_omschrijving"
                      + "     , sd.ins_srtdiscipline_prefix || m.mld_melding_key || '/' || mo.mld_opdr_bedrijfopdr_volgnr mld_opdr_id"
                      + "     , mto.mld_typeopdr_omschrijving"
                      + "  FROM mld_opdr mo"
                      + "     , mld_melding m"
                      + "     , mld_stdmelding sm"
                      + "     , ins_tab_discipline td"
                      + "     , ins_srtdiscipline sd"
                      + "     , mld_typeopdr mto"
                      + " WHERE mo.mld_melding_key = m.mld_melding_key"
                      + "   AND m.mld_stdmelding_key = sm.mld_stdmelding_key"
                      + "   AND sm.mld_ins_discipline_key = td.ins_discipline_key"
                      + "   AND td.ins_srtdiscipline_key = sd.ins_srtdiscipline_key"
                      + "   AND mo.mld_typeopdr_key = mto.mld_typeopdr_key"
                      + "   AND mo.mld_opdr_key = " + result.mld_opdr_key;
              var oRs = Oracle.Execute(sql);
              if (oRs.Eof)
                shared.record_not_found("<!--" + result.mld_opdr_key + "-->");
              result.mld_typeopdr_image = oRs("mld_typeopdr_image").Value || "fa-file-signature"; // zo doen we dat bij OPDR ook
              result.stdmelding_omschrijving = oRs("stdmelding_omschrijving").Value;
              result.mld_opdr_id = oRs("mld_opdr_id").Value;
              result.typeopdr_omschrijving = oRs("mld_typeopdr_omschrijving").Value;
              oRs.Close();
            }

            if (S("vis_afspraak_onrgoed_uses_keys") == 1)
            {
              var sql = "SELECT aor.alg_gebouw_key"
                      + "     , aor.alg_verdieping_key"
                      + "     , aor.alg_ruimte_key"
                      + "     , aor.alg_type"
                      + "     , alg_gebouw_beginuur"
                      + "     , alg_gebouw_einduur"
                      + "  FROM alg_v_allonroerendgoed aor"
                      + "     , alg_gebouw g"
                      + " WHERE aor.alg_gebouw_key = g.alg_gebouw_key"
                      + "   AND aor.alg_onroerendgoed_keys = " + result.alg_onrg_key
                      + "   AND aor.alg_locatie_key = " + result.locatie_key;

              var oRs = Oracle.Execute(sql);

              if (!oRs.eof)
              {
                result.gebouw_key = oRs("alg_gebouw_key").Value;
                result.verdieping_key = oRs("alg_verdieping_key").Value;
                result.ruimte_key = oRs("alg_ruimte_key").Value;
                result.onrg_type = oRs("alg_type").Value;
                result.gebouw_beginuur = oRs("alg_gebouw_beginuur").Value || -1;
                result.gebouw_einduur = oRs("alg_gebouw_einduur").Value || -1;
              }
              else
              {
                result.gebouw_key = -1;
                result.verdieping_key = -1;
                result.ruimte_key = -1;
                result.onrg_type = "L";
                result.gebouw_beginuur = -1;
                result.gebouw_einduur = -1;
              }
              oRs.Close();
            }

            // Moeten de velden telefoon, email en kenteken getoond worden en zijn ze afhankelijk van parkeerplaats.
            function toon_optimistisch(fld)
            {
                var r = "CASE WHEN MAX(" + fld + ") > 0"
                      + "     THEN CASE WHEN MIN(" + fld + ") = 3"
                      + "               THEN 3"
                      + "               ELSE CASE WHEN MIN(" + fld + ") = 2"
                      + "                         THEN 2"
                      + "                         ELSE 1"
                      + "                    END"
                      + "          END"
                      + "     ELSE 0"
                      + "END";
                return r;
            }
            var sql = "SELECT " + toon_optimistisch("a.alg_gebouw_toon_telefoon") + " toon_telefoon"
                    + "     , " + toon_optimistisch("a.alg_gebouw_toon_email")    + " toon_email"
                    + "     , " + toon_optimistisch("a.alg_gebouw_toon_kenteken") + " toon_kenteken"
                    + "  FROM alg_v_allonrgoed_gegevens a"
                    + " WHERE (1=1)"
                    + ( S("vis_afspraak_onrgoed_uses_keys") != 1 || result.onrg_type == 'L'
                      ? " AND a.alg_type = 'G'"
                      + " AND a.alg_locatie_key = " + result.locatie_key
                      : " AND a.alg_type = " + safe.quoted_sql(result.onrg_type)
                      + " AND a.alg_onroerendgoed_keys = " + result.alg_onrg_key
                      );
            var oRs = Oracle.Execute(sql);
            result.toon_telefoon = oRs("toon_telefoon").Value;
            result.toon_email    = oRs("toon_email").Value;
            result.toon_kenteken = oRs("toon_kenteken").Value;
            oRs.Close();

            return result;
        },

    func_enabled_afspraak: // Wat mag ik zoal op deze specifieke afspraak?
        function _func_enabled_afspraak(afspr_key)
        {   // initialisatie voor als afspr_key = -1
            var host_key = user_key;
            var contact_key = user_key;
            var alg_key = -1;
            var rsv_ruimte_key = -1;
            var aantaldone = 0;
            var aantalnotout = 0;
            var tVan, tExpire = 0;
            if (afspr_key > 0)
            {
                var sql = "SELECT a.bez_afspraak_host_key"
                        + "     , a.bez_afspraak_contact_key"
                        + "     , a.alg_onrgoed_keys"
                        + "     , a.prs_perslid_key"
                        + "     , a.res_rsv_ruimte_key"
                        + "     , a.bez_afspraak_datum AS tVan"
                        + "     , fac.DatumTijdPlusUitvoerTijd (SYSDATE, " + S("vis_expire") + ", 'DAGEN') AS tExpire"
                        + "     , COUNT (b.bez_bezoekers_done) AS aantaldone"
                        + "     , SUM (CASE WHEN b.bez_bezoekers_out IS NULL THEN 1 ELSE 0 END) aantalnotout"
                        + "  FROM bez_afspraak a"
                        + "     , bez_bezoekers b"
                        + " WHERE a.bez_afspraak_key = b.bez_afspraak_key(+)" // vanuit PDA hebben we eventjes een afspraak
                        + "   AND a.bez_afspraak_key = " + afspr_key          // zonder bezoekers-->outer join
                        + " GROUP BY a.bez_afspraak_host_key"
                        + "        , a.bez_afspraak_contact_key"
                        + "        , a.alg_onrgoed_keys"
                        + "        , a.prs_perslid_key"
                        + "        , a.res_rsv_ruimte_key"
                        + "        , a.bez_afspraak_datum";
                var oRs = Oracle.Execute(sql);
                if (oRs.eof)
                    shared.record_not_found("<!--" + afspr_key + "-->");

                host_key = oRs("bez_afspraak_host_key").Value;
                contact_key = oRs("bez_afspraak_contact_key").Value;
                alg_key = oRs("alg_onrgoed_keys").Value;
                rsv_ruimte_key = oRs("res_rsv_ruimte_key").Value;
                tVan = oRs("tVan").Value;
                tExpire = oRs("tExpire").Value;
                aantaldone = oRs("aantaldone").Value;
                aantalnotout = oRs("aantalnotout").Value;
                oRs.Close();
            }
            var bresult = user.func_enabled("BEZ",
                                            -1, // discipline key
                                            alg_key,
                                            contact_key,
                                            false, // pessimist
                                            false); // isOptional

            // Kan ik afspraken zien en maken
            bresult.canWritePrk = bresult.canWrite("WEB_BEZPRK");
            bresult.canWritePaf = bresult.canWrite("WEB_BEZPAF");
            // Als alle bezoekers zijn uitgecheckt, dan mag de afspraak niet meer gewijzigd worden.
            bresult.canChange   = (bresult.canWrite("WEB_BEZFOF") || bresult.canWrite("WEB_BEZBOF") || bresult.canWrite("WEB_BEZUSE")) && aantalnotout > 0;
            // Als er bezoekers zijn binnen geboekt, dan mag de afspraak niet meer verwijderd worden.
            bresult.canDelete   = (bresult.canWrite("WEB_BEZFOF") || bresult.canWrite("WEB_BEZBOF") || bresult.canWrite("WEB_BEZUSE"))
                                  && (bresult.canWrite("WEB_BEZFOF") || (tVan > tExpire)) && aantaldone == 0;

            // Als er parkeerplaatsen aanzitten die PAF nodig hebben gelden soms andere regels
            sql = "SELECT count(*) aantal"
                + "  FROM bez_bezoekers b"
                + "     , res_rsv_deel rrd"
                + "     , res_deel rd"
                + "     , ins_deel id"
                + "     , alg_v_aanwezigterreinsector t"
                + " WHERE b.bez_bezoekers_key = rrd.bez_bezoekers_key"
                + "   AND rrd.res_deel_key = rd.res_deel_key"
                + "   AND rd.res_ins_deel_key = id.ins_deel_key"
                + "   AND id.ins_alg_ruimte_key = t.alg_terreinsector_key"
                + "   AND id.ins_alg_ruimte_type = 'T'"
                + "   AND t.prs_afdeling_key IS NOT NULL"
                + "   AND bez_afspraak_key = " + afspr_key
            var oRs = Oracle.Execute(sql);
            bresult.nrPAF = oRs("aantal").Value;
            oRs.Close();
            // Beetje grof: als de FO voor jou PAF parkeerplaatsen heeft geregeld terwijl
            //              je zelf geen PAF rechten hebt laten we je meer niet wijzigen.
            //              Ander zou je indirect de parkeerplaats langer kunnen claimen.
            if (!bresult.canWritePaf && bresult.nrPAF > 0)
              bresult.canChange = false;

            bresult.canWriteAny  = bresult.canWrite("WEB_BEZFOF")  || bresult.canWrite("WEB_BEZBOF")  || bresult.canWrite("WEB_BEZUSE");

            bresult.canResWriteAny = false;
            // Bij extern ingevoerde reserveringen mogen we de bezoekers niet veranderen.
            if (rsv_ruimte_key > 0)
            {
             var res_ruimte_extern_id = null;
             sql = "SELECT rr.res_ruimte_extern_id"
                 + "  FROM res_rsv_ruimte rrr"
                 + "     , res_ruimte_opstelling ro"
                 + "     , res_ruimte rr"
                 + " WHERE rrr.res_ruimte_opstel_key = ro.res_ruimte_opstel_key"
                 + "   AND ro.res_ruimte_key = rr.res_ruimte_key"
                 + "   AND rrr.res_rsv_ruimte_key = " + rsv_ruimte_key;
              var oRs = Oracle.Execute(sql);
              var res_ruimte_extern_id = !oRs.Eof && oRs("res_ruimte_extern_id").Value;
              oRs.Close();

              var authparamsRES = user.checkAutorisation(["WEB_RESFOF", "WEB_RESBOF", "WEB_BEZBOF"], true);
              bresult.canResWriteAny = authparamsRES && authparamsRES.ALGwritelevel < 9 ||
                                       user.isCollega(contact_key) || user.isCollega(host_key);

              // Als je bezoekers bij een reservering wilt aanpassen heb je ook enige RES rechten nodig.
              bresult.canWriteAny  = bresult.canWriteAny && bresult.canResWriteAny;
            }

            bresult.canWriteFOF = bresult.canWrite("WEB_BEZFOF");
            bresult.canWriteBOF = bresult.canWrite("WEB_BEZBOF");

            bresult.canReadAny  = bresult.canRead("WEB_BEZFOF")  || bresult.canRead("WEB_BEZBOF")  || bresult.canRead("WEB_BEZUSE");
            bresult.canReadFOF  = bresult.canRead("WEB_BEZFOF");
            bresult.canReadBOF  = bresult.canRead("WEB_BEZBOF");

            bresult.canBadge = bresult.canRead("WEB_BEZBOF");
            bresult.canCheckInOut = bresult.canWrite("WEB_BEZBOF");
            bresult.canContact = bresult.canWrite("WEB_BEZBOF") || bresult.canWrite("WEB_BEZUSE");

            bresult.canReadFEOnly = false;
            if (    bresult.canReadAny
                && !bresult.canRead("WEB_BEZFOF")
                && !bresult.canRead("WEB_BEZBOF")
               )
            {
              bresult.canReadFEOnly = true;
              if (   !user.isCollega(contact_key)
                  && !user.isCollega(host_key)
                 )
              {
                bresult.canReadAny = false;
              }
            }
            bresult.canChange &= bresult.canReadAny; // Dat is toch wel het minste

            bresult.canWriteFlags = bresult.canWrite("WEB_BEZBOF") || bresult.canWrite("WEB_BEZFOF"); // Kan ik flags aanpassen

            // Als er bezoekers zijn binnen geboekt, dan mogen de datums niet meer worden aangepast.
            bresult.canChangeDate = bresult.canChange && aantaldone == 0;

            return bresult;
        },
    default_actie: function (actie_groep_key)
    {
      var actie_key = -1;
      // Is er een default actie.
      var sql = "SELECT bez_actie_key"
              + "  FROM bez_actie"
              + " WHERE bez_actie_verwijder IS NULL"
              + "   AND bez_actie_default = 1"
              + (actie_groep_key > 0 ? " AND bez_actie_groep_key = " + actie_groep_key : "")
      var oRs = Oracle.Execute(sql);
      if (!oRs.eof)
        actie_key = oRs("bez_actie_key").Value;
      oRs.Close()
      return actie_key;
    },

    // Bepaal eventueel het ene gebouw/terrein wat we mogen kiezen. bez.claim_park is nog niet slim genoeg
    only_prkgebter: -2,
    onlyGebouw: function _onlyGebouw(afspraak_key)
    {
        if (this.only_prkgebter > -2)
            return this.only_prkgebter;

      var sql = "SELECT bez_afspraak_datum, bez_afspraak_eind, alg_locatie_key"
              + "  FROM bez_afspraak"
              + " WHERE bez_afspraak_key = " + afspraak_key;
      var oRs = Oracle.Execute(sql);
      var gebtersql = bez.getgebouwterrein_sql(new Date(oRs("bez_afspraak_datum").value), new Date(oRs("bez_afspraak_eind").value), oRs("alg_locatie_key").value);
      oRs.Close();
      var oRs = Oracle.Execute(gebtersql);
      var aantal_gebter = 0;
      this.only_prkgebter = -1;
      while (!oRs.eof)
      {
        var alg_type = oRs("alg_type").value;
        this.only_prkgebter = (alg_type == "R"? oRs("alg_gebouw_key").value : oRs("alg_terreinsector_key").value);
        aantal_gebter++;
        oRs.MoveNext();
      }
      oRs.Close();
      if (aantal_gebter != 1)
        this.only_prkgebter = -1; // Gebruiker heeft gekozen via Suggest en getFParamInt("gebouwkey" + bznum, "") wordt gebruikt.
      return this.only_prkgebter;
    },

    faq_info: function _faq_info(loc_key, alg_key_arr, changed, is_popup, showall)
    {
      var has = { loc:  loc_key && loc_key != -1
                , alg:  alg_key_arr && alg_key_arr.length && alg_key_arr.length > 0
                };
      var result = { fixed_faq: []
                   , popup_faq: false
                   };
      var canFAQUSEread = user.checkAutorisation("WEB_FAQUSE", true);
      var canFAQFOFread = user.checkAutorisation("WEB_FAQFOF", true);

      if (has.loc || has.alg)
      {
        var sql_select = "     , 1 rank"
                       + "     , DECODE (og.alg_onroerendgoed_keys,"
                       + "               NULL, DECODE (af.alg_locatie_key,"
                       + "                             NULL, 'X', 'L'),"
                       + "               og.alg_type) alg_type "
                       + "     , fac_faq_displaymode displaymode";
        var sql_from = "   , alg_algfaq af"
                     + "   , alg_v_onroerendgoed og";
        var plaats_filter_arr = ["af.alg_algfaq_key IS NULL"]; // Voor plaats-scope-loze items: altijd.
        if (has.loc)
          plaats_filter_arr.push(" (af.alg_locatie_key = " + loc_key + " AND af.alg_onroerendgoed_keys IS NULL)");
        if (has.alg)
          plaats_filter_arr.push(" (af.alg_onroerendgoed_keys IN (" + alg_key_arr + "))");
        var sql_where = ( is_popup
                        ? " AND BITAND(ff.fac_faq_displaymode, 32) <> 0" // Minstens 32 (pop-up BEZ)
                        : " AND ff.fac_faq_displaymode <> 0" // Minstens iets;
                        )
                      + " AND ff.fac_faq_key = af.fac_faq_key(+)"
                      + " AND af.alg_onroerendgoed_keys = og.alg_onroerendgoed_keys(+)"
                      + " AND (  (" + plaats_filter_arr.join(" OR ") + ")"
                      + "     )";
      }
      else
      {
        var sql_select = "     , 1 rank"
                       + "     , 'X' alg_type"
                       + "     , fac_faq_displaymode displaymode";
        var sql_from = "";
        var sql_where = ( is_popup
                        ? " AND BITAND(ff.fac_faq_displaymode, 32) <> 0" // Minstens 32 (pop-up BEZ)
                        : " AND ff.fac_faq_displaymode <> 0" // Minstens iets;
                        );
      }

      if ((has.loc || has.alg) && (!is_popup || showall || changed >= 2))
      {
        var sql_bez = faq.getkennisbank_sql(sql_select, sql_from, sql_where);
        var sql = sql_bez
                + " ORDER BY fac_faq_rank DESC NULLS LAST"
                + "        , fac_faq_datum DESC"
                + "        , fac_faq_question";
        var oRs = Oracle.Execute(sql);
        while (!oRs.eof)
        {
          var displaymode = oRs("displaymode").Value;

          // Displaymode +16=Altijd tonen afspraak, +32=Pop-up afspraak.
          if ((displaymode & 32) == 32) // Pop-up
          {
            if (  ((S("faq_kennisbank_popup") & 1) && canFAQUSEread) // Voor FE
               || ((S("faq_kennisbank_popup") & 2) && canFAQFOFread) // Voor FO
               )
            {
              result.popup_faq = true;
            }
          }

          if ((displaymode & (is_popup? 32 : 16)) == (is_popup? 32 : 16))
          {
            var data = { faq_key: oRs("fac_faq_key").Value
                       , has_kenm: oRs("aantal_kenm").Value > 0
                       , question: oRs("fac_faq_question").Value
                       , answer: oRs("fac_faq_answer").Value
                       , answer2: oRs("fac_faq_answer2").Value
                       , displaymode: oRs("displaymode").Value
                       , faq_type: "faq_X" + oRs("alg_type").Value
                       };
            var fac_url = oRs("fac_faq_url").value;
            if (fac_url)
            {
              var arr = fac_url.split("|");
              var hurl = arr[0];
              data.hlnk = arr.length>1?arr[1]:hurl;

              if (hurl.slice(0,4) == "http") // extern
                data.hurl = hurl;
              else // in cust subdir
                data.hurl = custpath + "/" + hurl;
            }
            result.fixed_faq.push(data);
          }
          oRs.MoveNext();
        }
        oRs.Close();
      }
      return result;
    }

}
%>