<% /*
     $Revision$
     $Id$

    File:               res_list_ppi.inc
    Description:        Geef een overzicht van de performance prestatie indicator van reserveringen,
                        die voldoen aan de gegeven requirements
    Parameters:
        urole           user role (fe, fo, bo, mi)
        outputmode      behave in an output mode, print to 0 = screen, 1 = printer, 2 = excel, etc.
        showall         show all orders which meets with the given requirements
        datefrom        search for reservations at the selected date-month-year
        dateto          search for reservations at the selected date-month-year
        dist_key_arr        search for reservations for the selected district
        loc_key_arr         search for reservations for the selected location
        bld_key_arr         search for reservations for the selected building
        flr_key_arr         search for reservations for the selected floor
        room_key_arr        search for reservations for the selected room
        roomcat_key_arr    search for reservations with the selected room categories/types
        dayschedule     give an overview at day schedule level
        groupres        groupres the reservations by
    Context:            Search action from res_search_ppi.asp form
    Note:
    TODO:

*/
%>

<!-- #include file="../Shared/discxalg3d.inc" -->
<!-- #include file="../Shared/resultset_table_v2.inc" -->
<!-- #include file="./res.inc" -->
<!-- #include file="../Shared/getkenmerksql.inc" -->

<%
FCLTHeader.Requires({ plugins:["jQuery"],
                      js: ["../res/res_list.js"]
                    });

function res_list_ppi(pautfunction, params)
{ // VALIDATE AND PREPARE
  // Als een parameter niet gedefinieerd of null is, dan doet-ie niks
  // anders wordt die verondersteld een zinvolle waarde te hebben
  // NB: -1 is vaak geen zinvolle waarde; null had het dan moeten zijn!

  // Valid and supported parameters are:
  // params.urole           : the usuals two-letter lowercase string
  // params.outputmode      : print to 0 = screen, 1 = printer, 2 = excel, etc.
  // params.showall         : boolean (true | false)
  // params.datefrom        : date
  // params.dateto          : date
  // params.dist_key_arr    : key
  // params.loc_key_arr     : key
  // params.bld_key_arr     : key
  // params.flr_key_arr     : key
  // params.room_key_arr    : key
  // params.roomcat_key_arr : array met keys
  // params.dayschedule     : boolean (true | false)
  // params.groupres        : key

  // De functie checkAutorisation(autfunction) geeft een Response.End indien er geen autorisatie voor autfunction wordt gevonden
  var authparams = user.checkAutorisation(pautfunction);

  var urole = params.urole;
  var fronto = (urole == "fo");
  var backo = (urole == "bo");
  var minfo = (urole == "mi"); // NOT APPLICABLE?
  var frontend = (urole == "fe" || (!fronto && !backo && !minfo));

  settings.overrule_setting("res_t1", Math.floor(S("res_t1")));
  settings.overrule_setting("res_t2", Math.floor(S("res_t2") + 0.6));

  // Voor resulttable de globalen zetten; zou nog anders moeten.
  var outputmode = params.outputmode; // print to 0 = screen, 1 = printer, 2 = excel, etc.
  var print = (outputmode == 1 || outputmode == 5);
  var excel = (outputmode == 2 || outputmode == 6);
  var formString = params.formString;
  var showall = params.showall;

  var datefrom = params.datefrom; // Periode van
  var dateto = params.dateto; // Periode tot
  if (params.timefrom)
  {
    var hh = params.timefrom.split(":")[0];
    var mm = params.timefrom.split(":")[1] / 60;
    var timefrom = parseInt(hh,10) + mm;
  }
  else
  {
    var timefrom = S("res_rap_t1") == -1 ? S("res_t1") : S("res_rap_t1"); // Tijd van
  }
  if (params.timeto)
  {
    var hh = params.timeto.split(":")[0];
    var mm = params.timeto.split(":")[1] / 60;
    var timeto = parseInt(hh,10) + mm;
  }
  else
  {
    var timeto = S("res_rap_t2") == -1 ? S("res_t2") : S("res_rap_t2"); // Tijd tot
  }
  var dist_key_arr = params.dist_key_arr; // District
  var loc_key_arr = params.loc_key_arr; // Locatie
  var bld_key_arr = params.bld_key_arr; // Gebouw
  var flr_key_arr = params.flr_key_arr; // Verdieping
  var room_key_arr = params.room_key_arr; // Ruimte
  var roomcat_key_arr = params.roomcat_key_arr; // Ruimte categorie array
  var dayschedule = params.dayschedule; // Dagverdeling
  var groupres = params.groupres; // Groepering

%>

  <html>
    <head>
<%
      FCLTHeader.Generate({ outputmode: outputmode });
%>
      <script type="text/javascript">
        var urole = "<%=urole%>";
        var print = (<%=print? 1 : 0%> == 1);
        var excel = (<%=excel? 1 : 0%> == 1);
      </script>

    </head>
    <body id="listbody">

<%
      /***** Build sql *****/
      //var date_sql = "";
      var sql_dis = "";
      var sql_loc = "";
      var sql_bld = "";
      var sql_floor = "";
      var sql_rooms = "";
      var sql_dept = "";
      var sql_account = "";
      var sql_roomcat_key = "";

      // If from and to are given both are used
      // If only one of from and to are give, this is used as a (1) day, not an half open interval
      // 20-10-2009 9:46:28/PF
      datefrom = datefrom || dateto;
      dateto = dateto || datefrom;

      // if both are not given take last month als period
      if (!(datefrom && dateto))
      {
        datefrom = new Date();
        dateto = new Date();
      }
      var ora_date1 = datefrom.beginToSQL();
      var ora_date2 = dateto.beginToSQL();
      var ora_date3 = datefrom.beginToSQL();
      var ora_date4 = dateto.endToSQL();
      var ora_date5 = convertToLocalTime(datefrom).toSQL(true);
      var ora_date6 = convertToLocalTime(dateto).toSQL(true);

      //date_sql = " AND beschik.res_reservering_van BETWEEN " + ora_date1 + " AND " + ora_date2;

      if (room_key_arr.length)
        sql_rooms = " AND ruimte_geg.alg_ruimte_key IN (" + room_key_arr.join(",") + ")";
      else if (flr_key_arr.length)
        sql_floor = " AND ruimte_geg.alg_verdieping_key IN (" + flr_key_arr.join(",") + ")";
      else if (bld_key_arr.length)
        sql_bld = " AND ruimte_geg.alg_gebouw_key IN (" + bld_key_arr.join(",") + ")";
      else if (loc_key_arr.length)
        sql_loc = " AND ruimte_geg.alg_locatie_key IN (" + loc_key_arr.join(",") + ")";
      else if (dist_key_arr.length)
        sql_dis = " AND ruimte_geg.alg_district_key IN (" + dist_key_arr.join(",") + ")";

      if (roomcat_key_arr.length)
        sql_roomcat_key = " AND beschik.res_discipline_key IN (" + roomcat_key_arr.join(",") + ")";

function forhours(fn)
{
    var i;
    var res = []
    // Wel met hele uren rekenen, anders geeft dat hier problemen.
    for (i = timefrom; i < timeto; i++)
    {
        var h = getServerHour(i)
        res.push(fn.call(null, h, Math.floor(i)));
    }
    return res;
}
//__Log(forhours(function (h) { return String(h); }));

var tot_ruimtes = 0;
var tot_beschik = 0;
function calcTotals(sql)
{
  var totalSql = "SELECT " + (dayschedule ? "COUNT(COUNT(1))" : "COUNT(1), SUM(MAX(beschikbaar_uren))") + " FROM (" + sql + ") GROUP BY " + (groupres == 14 ? "res_keycolumn" : "alg_ruimte_key");
  var totaloRs = Oracle.Execute(totalSql);
  tot_ruimtes = totaloRs(0).Value;
  if (!dayschedule)
      tot_beschik = totaloRs(1).Value;
  totaloRs.Close();
}

      var sql = " SELECT beschik.alg_ruimte_key"
              + (groupres == 14 // ruimte
                ? ", ruimte_geg.alg_ruimte_aanduiding || ' - (' ||"
                + " beschik.res_ruimte_upper ||"
                + " (SELECT CASE COUNT(rar.res_ruimte_key)"
                  + " WHEN 1"
                  + " THEN ')'"
                  + " ELSE '...)'"
                  + " END"
                  + " FROM res_v_aanwezigalg_ruimte rar"
                  + " WHERE rar.alg_ruimte_key = beschik.alg_ruimte_key) ruimte"
                : "")
              + "      , beschik.res_discipline_key"
              + "      , beschik.res_ruimte_upper"
              + (dayschedule
                ? "    ," + forhours(function (h) { return "b" + String(h); })
                : "    , ROUND(NVL(bezetting, 0), 2) bezetting")
              + "      , ROUND(NVL(beschikbaar, 0), 2) beschikbaar"
              + "      , di.alg_regio_key"
              + "      , l.alg_district_key"
              + "      , l.alg_locatie_key"
              + "      , alg_gebouw_key"
              + "      , alg_verdieping_key"
              + " FROM (SELECT alg_ruimte_key"
              + "            , rarg.res_discipline_key"
              + (dayschedule
                ? ("         ," + forhours(function (h) { return " SUM(n" + String(h) + ") b" + String(h); }))
                : "          , SUM(GREATEST(0, GREATEST(LEAST(to_number(TO_CHAR(res_rsv_ruimte_tot_tz, 'SSSSS')) / 3600"
                  + "                           , COALESCE(res_ruimte_eindtijd, " + S("res_t2") + ")"
                  + "                           ," + (timeto)
                  + "                            )"
                  + "                     ," + (timefrom)
                  + "                      )"
                  + "           -  LEAST(GREATEST(to_number(TO_CHAR(res_rsv_ruimte_van_tz, 'SSSSS')) / 3600"
                  + "                           , COALESCE(res_ruimte_begintijd, " + S("res_t1") + ")"
                  + "                           ," + (timefrom)
                  + "                            )"
                  + "                  ," + (timeto)
                  + "                   ))"
                  + "             ) bezetting")
              + "         FROM (SELECT r.res_rsv_ruimte_key"
              + "                    , ra.alg_ruimte_key"
              + "                    , ra.res_alg_ruimte_key"
              + "                    , rr.res_discipline_key"
              + (dayschedule
                ? "                  ," + forhours(function (h) { return "r.n" + String(h); })
                : "")
              + "                    , r.res_rsv_ruimte_van"
              + oRaAsUserTZ('r', 'res_rsv_ruimte_van')
              + "                    , r.res_rsv_ruimte_tot"
              + oRaAsUserTZ('r', 'res_rsv_ruimte_tot')
              + "                    , ra.res_alg_ruimte_aanmaak"
              + "                    , ra.res_alg_ruimte_verwijder"
              + "                    , rr.res_ruimte_begintijd"
              + "                    , rr.res_ruimte_eindtijd"
              + "                 FROM "
              + (dayschedule
                ? "                    res_v_res_dag_bezetting r"
                : "                    res_rsv_ruimte r")
              + "                    , res_ruimte_opstelling ro"
              + "                    , res_ruimte rr"
              + "                    , res_alg_ruimte ra"
              + "                WHERE r.res_rsv_ruimte_verwijder IS NULL"
              + "                  AND r.res_rsv_ruimte_dirtlevel = 0"
              + "                  AND (rr.res_ruimte_startdatum  IS NULL OR rr.res_ruimte_startdatum <= " + ora_date1 + ")"
              + "                  AND (rr.res_ruimte_vervaldatum IS NULL OR rr.res_ruimte_vervaldatum > " + ora_date1 + ")"
              + "                  AND r.res_status_fo_key IN (1, 2)"
              + "                  AND r.res_ruimte_opstel_key = ro.res_ruimte_opstel_key"
              + "                  AND ro.res_ruimte_key = rr.res_ruimte_key"
              + "                  AND rr.res_ruimte_key = ra.res_ruimte_key) rarg"
              + "        WHERE res_rsv_ruimte_van BETWEEN " + ora_date3 + " AND " + ora_date4
              + "          AND TO_CHAR(res_rsv_ruimte_van_tz, 'd') >= 2" // --veronderstelt NLS_TERRITORY='AMERICA', 2 is maandag
              + "          AND TO_CHAR(res_rsv_ruimte_van_tz, 'd') <= 6"
              + "          AND TRUNC(res_rsv_ruimte_van_tz) NOT IN (SELECT mld_vrije_dagen_datum FROM mld_vrije_dagen)"
              + "          AND rarg.res_alg_ruimte_aanmaak <= " + ora_date2
              + "          AND (rarg.res_alg_ruimte_verwijder IS NULL"
              + "               OR rarg.res_alg_ruimte_verwijder >= " + ora_date1 + ")"
              + "       GROUP BY alg_ruimte_key"
              + "               , rarg.res_discipline_key) bez"
              + "  ,    (SELECT DISTINCT rr1.res_discipline_key, "
                + "                      rr1.res_ruimte_upper,"
                + "                      ra.alg_ruimte_key"
                + "                    , ((fac.Count_Work_Days(" + ora_date5 + "-1 , " + ora_date6 + "))"
                  + (dayschedule
                    ? ""
                    : "                  * (GREATEST(0, LEAST(COALESCE(rr1.res_ruimte_eindtijd, " + S("res_t2") + ")"
                      + "                      ," + (timeto)
                      + "                        )"
                      + "                   - GREATEST(COALESCE(rr1.res_ruimte_begintijd, " + S("res_t1") + ")"
                      + "                            ," + (timefrom)
                      + "                             )"
                      + "                   - (COALESCE(rr1.res_ruimte_eindtijdblok, 12)"
                      + "                      - COALESCE(rr1.res_ruimte_begintijdblok, 12)))"
                      + "                  )"
                    )
                  + "                    ) beschikbaar"
              + "          FROM res_ruimte rr1"
              + "             , res_alg_ruimte ra"
              + "         WHERE rr1.res_ruimte_key = ra.res_ruimte_key"
              + "           AND ra.res_alg_ruimte_aanmaak <= " + ora_date2
              + "           AND (rr1.res_ruimte_startdatum  IS NULL OR rr1.res_ruimte_startdatum <= " + ora_date1 + ")"
              + "           AND (rr1.res_ruimte_vervaldatum IS NULL OR rr1.res_ruimte_vervaldatum > " + ora_date1 + ")"
              + "           AND (ra.res_alg_ruimte_verwijder IS NULL"
              + "                OR ra.res_alg_ruimte_verwijder >= " + ora_date1 + ")) beschik"
              + "     , alg_v_ruimte_gegevens_all ruimte_geg"
              + "     , alg_locatie l"
              + "     , alg_district di"
              + " WHERE beschik.alg_ruimte_key = bez.alg_ruimte_key(+)"
              + "   AND beschik.res_discipline_key = bez.res_discipline_key(+)"
              + "   AND beschik.alg_ruimte_key = ruimte_geg.alg_ruimte_key"
              + "   AND ruimte_geg.alg_locatie_key = l.alg_locatie_key"
              + "   AND l.alg_district_key = di.alg_district_key"
              + sql_roomcat_key
              + sql_dis
              + sql_loc
              + sql_bld
              + sql_floor
              + sql_rooms;

      //
      // Alleen gebruikt voor groepering maand of datum of weekdag
      if (groupres >=16)
      {
        var sql_reservering = "SELECT r.res_rsv_ruimte_key"
                            + "     , ra.alg_ruimte_key"
                            + "     , ra.res_alg_ruimte_key"
                            + "     , rr.res_discipline_key"
                            + (dayschedule
                                ? " ," + forhours(function (h) { return "r.n" + String(h); })
                                : "")
                            + "     , r.res_rsv_ruimte_van"
                            + oRaAsUserTZ('r', 'res_rsv_ruimte_van')
                            + "     , r.res_rsv_ruimte_tot"
                            + oRaAsUserTZ('r', 'res_rsv_ruimte_tot')
                            + "     , ra.res_alg_ruimte_aanmaak"
                            + "     , ra.res_alg_ruimte_verwijder"
                            + "     , rr.res_ruimte_begintijd"
                            + "     , rr.res_ruimte_eindtijd"
                            + "  FROM "
                            + (dayschedule
                                ? "   res_v_res_dag_bezetting r"
                                : "   res_rsv_ruimte r")
                            + "     , res_ruimte_opstelling ro"
                            + "     , res_ruimte rr"
                            + "     , res_alg_ruimte ra"
                            + " WHERE r.res_rsv_ruimte_verwijder IS NULL"
                            + "   AND r.res_rsv_ruimte_dirtlevel = 0"
                            + "   AND (rr.res_ruimte_startdatum  IS NULL OR rr.res_ruimte_startdatum <= " + ora_date1 + ")"
                            + "   AND (rr.res_ruimte_vervaldatum IS NULL OR rr.res_ruimte_vervaldatum > " + ora_date1 + ")"
                            + "   AND r.res_status_fo_key IN (1, 2)"
                            + "   AND r.res_ruimte_opstel_key = ro.res_ruimte_opstel_key"
                            + "   AND ro.res_ruimte_key = rr.res_ruimte_key"
                            + "   AND rr.res_ruimte_key = ra.res_ruimte_key";

        var sql_sel_periode = "";
        var sql_grp_periode = "";
        if (groupres == 16)
        { // Gebruik hele maanden in het berekenen van het aantal werkdagen.
          sql_sel_periode = "fac.count_Work_Days"
                          + "( DECODE(periode, TO_CHAR(" + ora_date5 + ",'yyyymm'), " + ora_date5 + ",          fac.safe_to_date(periode || '01','yymmdd')) - 1"
                          + ", DECODE(periode, TO_CHAR(" + ora_date6 + ",'yyyymm'), " + ora_date6 + ", last_day(fac.safe_to_date(periode || '01','yymmdd')))"
                          + ")"
          sql_grp_periode = "TO_CHAR(" + oRaAsUserTZ('', 'res_rsv_ruimte_van', true) + ", 'yyyymm')";
        }
        if (groupres == 18 || groupres == 19)
        { // Alle dagen zijn goed. //Is de huidig geselecteerde dag een werkdag.
          sql_sel_periode = "1";   //"fac.count_Work_Days(to_date(werkbaredagen.periode,'yyyymmdd')-1, to_date(werkbaredagen.periode,'yyyymmdd'))";
          sql_grp_periode = "TO_CHAR(" + oRaAsUserTZ('', 'res_rsv_ruimte_van', true) + ", 'yyyymmdd')";
        }

        var sql_bezetting   = "SELECT rarg.alg_ruimte_key"
                            + "     , rarg.res_discipline_key"
                            + "     , " + sql_grp_periode + " periode"
                            + (dayschedule
                                ? (", " + forhours(function (h) { return " SUM(n" + String(h) + ") b" + String(h); }))
                                // This fails if you execute this querie from one timezone to gather data from multiple or other timezone(s)
                                // because:
                                // 1. Reservations from another timezone may extend over 2 days when converted to the user's timezone, in which case the calculation is wrong
                                // 2. begin and end times from which to calculate is user bound, not location bound.
                                //
                                // Note: reservations outside 'opening' hours now result in 0 hours.
                                : " , SUM ( "
                                + "            GREATEST ( "
                                + "                0, " // Voorkomt negatieve bezetting bij res buiten openingstijden
                                + "                  LEAST ( "
                                + "                      GREATEST ( "
                                + "                            TO_NUMBER ( "
                                + "                                TO_CHAR (rarg.res_rsv_ruimte_tot_tz, 'SSSSS')) "
                                + "                          / 3600, "
                                + "                          COALESCE (rarg.res_ruimte_begintijd, " + S("res_t1") +")), "
                                + "                      COALESCE (rarg.res_ruimte_eindtijd, " + S("res_t2") +"), "
                                + "                      " + (timeto) + ") "
                                + "                - GREATEST ( "
                                + "                     LEAST ( "
                                + "                            TO_NUMBER ( "
                                + "                                TO_CHAR (rarg.res_rsv_ruimte_van_tz, 'SSSSS')) "
                                + "                          / 3600, "
                                + "                          COALESCE (rarg.res_ruimte_eindtijd, " + S("res_t2") +")), "
                                + "                      COALESCE (rarg.res_ruimte_begintijd, " + S("res_t1") +"), "
                                + "                      " + (timefrom) + "))"
                                + "      ) bezetting")
                            + "  FROM ("+ sql_reservering + ") rarg"
                            + " WHERE rarg.res_rsv_ruimte_van BETWEEN " + ora_date3 + " AND " + ora_date4;
        // Alleen werkdagen meetellen voor 16:Maand.
        // Ook zaterdag en zondag meetellen voor 18:Weekdag, 19:Datum.
        if (groupres == 16)
        {
          sql_bezetting    += "   AND TO_CHAR(rarg.res_rsv_ruimte_van_tz, 'd') >= 2" // --veronderstelt NLS_TERRITORY='AMERICA', 2 is maandag
                            + "   AND TO_CHAR(rarg.res_rsv_ruimte_van_tz, 'd') <= 6";
        }
        sql_bezetting      += "   AND TO_CHAR(rarg.res_rsv_ruimte_van_tz, 'yyyymmdd') NOT IN"
                                  + "(SELECT to_char(mld_vrije_dagen_datum, 'yyyymmdd')"
                                  + "   FROM mld_vrije_dagen"
                                  + ")"
                            + "   AND rarg.res_alg_ruimte_aanmaak <= " + ora_date2
                            + "   AND (  rarg.res_alg_ruimte_verwijder IS NULL "
                            + "       OR rarg.res_alg_ruimte_verwijder >= " + ora_date1
                            + "       )"
                            + " GROUP BY alg_ruimte_key"
                            + "        , rarg.res_discipline_key"
                            + "        , " + sql_grp_periode;

        var sql_werkperiode = "SELECT werkbaredagen.periode"
                            + "     , " + sql_sel_periode + " werkdagen"
                            + "  FROM (SELECT " + sql_grp_periode + " periode"
                                    + "  FROM res_rsv_ruimte"
                                    + " WHERE res_rsv_ruimte_van BETWEEN " + ora_date3 + " AND " + ora_date4
                                    + "   AND res_rsv_ruimte_verwijder IS NULL"
                                    + " GROUP BY " + sql_grp_periode
                                    + ") werkbaredagen";

        var sql_beschikbaar = "SELECT DISTINCT"
                            + "       rr1.res_discipline_key"
                            + "     , ra.alg_ruimte_key"
                            + "     , sw.periode"
                            + "     , sw.werkdagen"
                            + (dayschedule
                                ? ""
                                : " * (GREATEST(0, LEAST(COALESCE(rr1.res_ruimte_eindtijd, " + S("res_t2") + ")"
                                + "                      ," + (timeto)
                                + "                  )"
                                + "    - GREATEST(COALESCE(rr1.res_ruimte_begintijd, " + S("res_t1") + ")"
                                + "                           ," + (timefrom)
                                + "                       )"
                                + "    - (COALESCE(rr1.res_ruimte_eindtijdblok, 12) - COALESCE(rr1.res_ruimte_begintijdblok, 12)))"
                                + "   )")
                            + "       beschikbaar"
                            + "  FROM res_ruimte rr1"
                            + "     , res_alg_ruimte ra"
                            + "     , ("+ sql_werkperiode +") sw"
                            + " WHERE rr1.res_ruimte_key = ra.res_ruimte_key"
                            + "   AND ra.res_alg_ruimte_aanmaak <= " + ora_date2
                            + "   AND (rr1.res_ruimte_startdatum  IS NULL OR rr1.res_ruimte_startdatum <= " + ora_date1 + ")"
                            + "   AND (rr1.res_ruimte_vervaldatum IS NULL OR rr1.res_ruimte_vervaldatum > " + ora_date1 + ")"
                            + "   AND (ra.res_alg_ruimte_verwijder IS NULL OR ra.res_alg_ruimte_verwijder >= " + ora_date1 + ")";

        var sqlM = "SELECT beschik.alg_ruimte_key"
                 + "     , beschik.res_discipline_key"
                 + (dayschedule
                    ? "    ," + forhours(function (h) { return "b" + String(h); })
                    : "    , ROUND(NVL(bez.bezetting, 0), 2) bezetting")
                 + "     , ROUND(NVL(beschik.beschikbaar, 0), 2) beschikbaar"
                 + "     , di.alg_regio_key"
                 + "     , l.alg_district_key"
                 + "     , l.alg_locatie_key"
                 + "     , ruimte_geg.alg_gebouw_key"
                 + "     , ruimte_geg.alg_verdieping_key"
                 + "     , beschik.periode"
                 + "  FROM ("+ sql_bezetting   + ") bez"             // calculate the occupation of the reservable rooms
                 + "     , ("+ sql_beschikbaar + ") beschik"         // calculate the availability of the reservable rooms
                 + "     , alg_v_ruimte_gegevens_all ruimte_geg"
                 + "     , alg_locatie l"
                 + "     , alg_district di"
                 + " WHERE beschik.alg_ruimte_key = bez.alg_ruimte_key(+) "
                 + "   AND beschik.res_discipline_key = bez.res_discipline_key(+)"
                 + "   AND beschik.periode = bez.periode(+)"
                 + "   AND beschik.alg_ruimte_key = ruimte_geg.alg_ruimte_key"
                 + "   AND ruimte_geg.alg_locatie_key = l.alg_locatie_key"
                 + "   AND l.alg_district_key = di.alg_district_key"
                 + sql_roomcat_key
                 + sql_dis
                 + sql_loc
                 + sql_bld
                 + sql_floor
                 + sql_rooms;
      }

      sql = discxalg3d(sql,
                       "beschik.res_discipline_key",
                       "di.alg_regio_key",
                       "l.alg_district_key",
                       "ruimte_geg.alg_locatie_key",
                       "ruimte_geg.alg_gebouw_key",
                       "ruimte_geg.alg_verdieping_key",
                       "ruimte_geg.alg_ruimte_key",
                       autfunction,
                       "");

      sqlM = discxalg3d(sqlM,
                        "beschik.res_discipline_key",
                        "di.alg_regio_key",
                        "l.alg_district_key",
                        "ruimte_geg.alg_locatie_key",
                        "ruimte_geg.alg_gebouw_key",
                        "ruimte_geg.alg_verdieping_key",
                        "ruimte_geg.alg_ruimte_key",
                        autfunction,
                        "");

      if (dayschedule)
      {
        res_colums =  [ [L("lcl_location"), "locatie", "string", false],
                        [L("lcl_res_nr_of_rooms"), "aantal_ruimten", "number", true]];

        res_colums = res_colums.concat(forhours(function (i, h) { return [String(h) == "23" ? "23:00 - 00:00" : String(h) + ":00 - " + String(h + 1) + ":00", "t" + String(i), "float", groupres < 16, groupres >= 16];}));

        inner_select_sql =  ", " + forhours(function (h) { return "SUM(b"+String(h)+") g"+String(h); }) + ", MAX(beschikbaar) beschikbaar_uren";
        outer_select_sql =  ", " + forhours(function (h) { return "NVL((CASE WHEN SUM(beschikbaar_uren) = 0 THEN 0 ELSE SUM(g"+String(h)+") / SUM(beschikbaar_uren) * 100 END), 0) t"+String(h)+""; });
        //order_by = "13";
      }
      else
      {
        res_colums = [ [L("lcl_location"), "locatie", "string", false],
                       [L("lcl_res_nr_of_rooms"), "aantal_ruimten", "number", true],
                       [L("lcl_res_load_in_hours"), "gebruik_uren", "float", true],
                       [L("lcl_res_available_in_hours"), "beschikbaar_uren", "float", true],
                       [L("lcl_occupation_perc"), "bezetting", "float", true] ];

        inner_select_sql = ", SUM(bezetting) gebruik_uren, MAX(beschikbaar) beschikbaar_uren";
        outer_select_sql = ", SUM(gebruik_uren) gebruik_uren, SUM(beschikbaar_uren) beschikbaar_uren, (CASE WHEN SUM(beschikbaar_uren) = 0 THEN 100 ELSE ROUND((SUM(gebruik_uren) / SUM(beschikbaar_uren)) * 100, 2) END) bezetting";

        //order_by = "6";
      }

      if (groupres == 5)
      { // District
        res_colums[0][0] = L("lcl_district");
        res_colums[0][1] = "district";

        sql = " SELECT d.alg_district_key res_keycolumn"
            + ", d.alg_district_omschrijving district"
            + ", x.alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sql + ") x"
            + ", alg_district d"
            + " WHERE x.alg_district_key = d.alg_district_key"
            + " GROUP BY d.alg_district_key"
            + ", d.alg_district_omschrijving"
            + ", x.alg_ruimte_key";

        calcTotals(sql);

        sql = " SELECT res_keycolumn, district, COUNT(alg_ruimte_key) aantal_ruimten"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn, district"
            + " ORDER BY district";

      }
      else if (groupres == 6)
      { // Locatie.
        res_colums[0][0] = L("lcl_location");

        sql = " SELECT l.alg_locatie_key res_keycolumn"
            + ", l.alg_locatie_omschrijving locatie"
            + ", x.alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sql + ") x"
            + ", alg_locatie l"
            + " WHERE x.alg_locatie_key = l.alg_locatie_key"
            + " GROUP BY l.alg_locatie_key"
            + ", l.alg_locatie_omschrijving"
            + ", x.alg_ruimte_key";

        calcTotals(sql);

        sql = " SELECT res_keycolumn, locatie, COUNT(DISTINCT alg_ruimte_key) aantal_ruimten"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn, locatie"
            + " ORDER BY locatie";
      }
      else if (groupres == 10)
      { // Gebouw
        res_colums[0][0] = L("lcl_building");
        res_colums[0][1] = "gebouw";

        sql = " SELECT g.alg_gebouw_key res_keycolumn"
            + ", g.alg_gebouw_naam gebouw"
            + ", x.alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sql + ") x"
            + ", alg_gebouw g"
            + " WHERE x.alg_gebouw_key = g.alg_gebouw_key"
            + " GROUP BY g.alg_gebouw_key"
            + ", g.alg_gebouw_naam"
            + ", x.alg_ruimte_key";

        calcTotals(sql);

        sql = " SELECT res_keycolumn, gebouw, COUNT(alg_ruimte_key) aantal_ruimten"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn, gebouw"
            + " ORDER BY gebouw";

      }
      else if (groupres == 14)
      { // Ruimte
        if (dayschedule)
        {
            res_colums =  [ [L("lcl_room"), "ruimte", "string", false] ];
            res_colums = res_colums.concat(forhours(function (i, h) { return [String(h) == "23" ? "23:00 - 00:00" : String(h) + ":00 - " + String(h + 1) + ":00", "t" + String(i), "float", false, true];}));
        }
        else
        {
            res_colums =  [ [L("lcl_room"), "ruimte", "string", false],
                            [L("lcl_res_load_in_hours"), "gebruik_uren", "float", true],
                            [L("lcl_res_available_in_hours"), "beschikbaar_uren", "float", true],
                            [L("lcl_occupation_perc"), "bezetting", "float", true]];
        }

        sql = " SELECT x.alg_ruimte_key res_keycolumn"
            + ", x.ruimte ruimte"
            + ", x.res_ruimte_upper"
            + inner_select_sql
            + " FROM (" + sql + ") x"
            + " GROUP BY x.alg_ruimte_key, x.ruimte, x.res_ruimte_upper";

        calcTotals(sql);

        sql = " SELECT res_keycolumn, ruimte, res_ruimte_upper"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn, ruimte, res_ruimte_upper"
            + " ORDER BY ruimte";
      }
      else if (groupres == 15)
      { // Ruimte catalogus
        res_colums[0][0] = L("lcl_res_roomcat");
        res_colums[0][1] = "ruimte_categorie";

        sql = " SELECT d.ins_discipline_key res_keycolumn"
            + ", ins_discipline_volgnr"
            + ", "+ lcl.xsql('d.ins_discipline_omschrijving','d.ins_discipline_key') +" ruimte_categorie"
            + ", x.alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sql + ") x"
            + ", ins_tab_discipline d"
            + " WHERE x.res_discipline_key = d.ins_discipline_key"
            + " GROUP BY d.ins_discipline_key"
            + ", ins_discipline_volgnr"
            + ", "+ lcl.xsql('d.ins_discipline_omschrijving','d.ins_discipline_key')
            + ", x.alg_ruimte_key";

        calcTotals(sql);

        sql = " SELECT res_keycolumn, ins_discipline_volgnr, ruimte_categorie, COUNT(DISTINCT alg_ruimte_key) aantal_ruimten"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn, ins_discipline_volgnr, ruimte_categorie"
            + " ORDER BY ins_discipline_volgnr, ruimte_categorie";
      }
      else if (groupres == 16)
      { // Maand
        if (dayschedule)
        {
            res_colums =  [ [L("lcl_month"), fnrowMaand, "string", false] ];
            res_colums = res_colums.concat(forhours(function (i, h) { return [String(h) == "23" ? "23:00 - 00:00" : String(h) + ":00 - " + String(h + 1) + ":00", "t" + String(i), "float", false, true];}));
        }
        else
        {
            res_colums =  [ [L("lcl_month"), fnrowMaand, "string", false],
                            [L("lcl_res_load_in_hours"), "gebruik_uren", "float", false],
                            [L("lcl_res_available_in_hours"), "beschikbaar_uren", "float", false],
                            [L("lcl_occupation_perc"), "bezetting", "float", false] ];
        }

        sql = " SELECT periode res_keycolumn, alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sqlM + ") x"
            + " GROUP BY periode, x.alg_ruimte_key";

        sql = " SELECT res_keycolumn"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn"
            + " ORDER BY res_keycolumn";

      }
      else if (groupres == 18)
      { // Weekdag
        if (dayschedule)
        {
            res_colums =  [ [L("lcl_weekday"), fnrowMaand, "string", false] ];
            res_colums = res_colums.concat(forhours(function (i, h) { return [String(h) == "23" ? "23:00 - 00:00" : String(h) + ":00 - " + String(h + 1) + ":00", "t" + String(i), "float", false, true];}));
        }
        else
        {
            res_colums =  [ [L("lcl_weekday"), fnrowMaand, "string", false],
                            [L("lcl_res_load_in_hours"), "gebruik_uren", "float", false],
                            [L("lcl_res_available_in_hours"), "beschikbaar_uren", "float", false],
                            [L("lcl_occupation_perc"), "bezetting", "float", false] ];
        }

        sql = " SELECT periode, alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sqlM + ") x"
            + " GROUP BY periode, x.alg_ruimte_key";

        sql = " SELECT TO_CHAR(TO_DATE(periode,'yyyymmdd'),'d') res_keycolumn"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY TO_CHAR(TO_DATE(periode,'yyyymmdd'),'d')"
            + " ORDER BY TO_CHAR(TO_DATE(periode,'yyyymmdd'),'d')";

      }
      else if (groupres == 19)
      { // Datum
        if (dayschedule)
        {
            res_colums =  [ [L("lcl_date"), fnrowMaand, "string", false] ];
            res_colums = res_colums.concat(forhours(function (i, h) { return [String(h) == "23" ? "23:00 - 00:00" : String(h) + ":00 - " + String(h + 1) + ":00", "t" + String(i), "float", false, true];}));
        }
        else
        {
            res_colums =  [ [L("lcl_date"), fnrowMaand, "string", false],
                            [L("lcl_res_load_in_hours"), "gebruik_uren", "float", false],
                            [L("lcl_res_available_in_hours"), "beschikbaar_uren", "float", false],
                            [L("lcl_occupation_perc"), "bezetting", "float", false] ];
        }

        sql = " SELECT periode res_keycolumn, alg_ruimte_key"
            + inner_select_sql
            + " FROM (" + sqlM + ") x"
            + " GROUP BY periode, x.alg_ruimte_key";

        sql = " SELECT res_keycolumn"
            + outer_select_sql
            + " FROM (" + sql + ") data"
            + " GROUP BY res_keycolumn"
            + " ORDER BY res_keycolumn";

      }
      else
      {
        sql = sql;
      }

      /***** End build sql *****/

      // Performance Oracle12
      if (sql.substr(0, 7) == "SELECT ")
        sql = "SELECT /*+ CURSOR_SHARING_EXACT */ " + sql.substr(7);
      if (sql.substr(0, 8) == " SELECT ")
        sql = "SELECT /*+ CURSOR_SHARING_EXACT */ " + sql.substr(8);

        /*****************************************************
         * Callback functies ResultsetTable for FE and FO only
         ****************************************************/

        function fnrowMaand(oRs)
        {
          var content = oRs("res_keycolumn").value;
          if (groupres == 16 || groupres == 19)
          {
            var jaar_int  = parseInt(content.substr(0,4), 10);
            var maand_int = parseInt(content.substr(4,2), 10);
            var dag_int   = parseInt(content.substr(6,2), 10);

            var maand_str = calendar_names.months[maand_int - 1];
            var dag_str   = "";
            if (groupres == 19)
            {
              dag_str = dag_int + " ";
            }
            return dag_str + maand_str + " " + jaar_int;
          }
          else if (groupres == 18)
          {
            var dagnaam = calendar_names.days[content-1];
            return dagnaam;
          }
        }

        var tot_aantal_ruimten = 0;
        var tot_gebruik_uren = 0;
        var tot_beschikbaar_uren = 0;
        var totaal = [];
        forhours(function (h) { totaal[h] = 0; })

        function fntotalCalc(oRs)
        {
          tot_aantal_ruimten = tot_ruimtes;
          if (dayschedule)
            forhours(function (h) { totaal[h] += (groupres == 14 ? 1 : oRs("aantal_ruimten").Value) * oRs("t" + String(h)).value });
          else
          {
            tot_beschikbaar_uren = tot_beschik;
            tot_gebruik_uren += oRs("gebruik_uren").value;
          }
        }

        function fntotalShow(column, nrlines)
        {
          var result = "";
          switch (column.caption)
          {
              case L("lcl_res_nr_of_rooms"): result = tot_aantal_ruimten; break;
              case L("lcl_res_load_in_hours"): result = safe.displayfloat(tot_gebruik_uren, 2); break;
              case L("lcl_res_available_in_hours"): result = safe.displayfloat(tot_beschikbaar_uren, 2); break;
              case L("lcl_occupation_perc"): result = safe.displayfloat((tot_beschikbaar_uren == 0 ? 100 : (tot_gebruik_uren / tot_beschikbaar_uren) * 100), 2); break;
              default: result = safe.curr(totaal[parseInt(column.caption, 10)]/tot_aantal_ruimten); break; // Dit zijn eigelijk de gemiddelden
          }
          return result;
        }

        /**************************************
         * End callback functies ResultsetTable
         **************************************/
         // Transform decimal limit to friendly times (i18n?)
         var res_rap_t1h = Math.floor(timefrom);
         if (res_rap_t1h < 10) res_rap_t1h = "0" + res_rap_t1h;
         var res_rap_t1m = Math.floor((timefrom - res_rap_t1h)*60);
         if (res_rap_t1m < 10) res_rap_t1m = "0" + res_rap_t1m;
         var res_rap_t1s = res_rap_t1h + ":" + res_rap_t1m

         var res_rap_t2h = Math.floor(timeto);
         if (res_rap_t2h < 10) res_rap_t2h = "0" + res_rap_t2h;
         var res_rap_t2m = Math.floor((timeto - res_rap_t2h)*60);
         if (res_rap_t2m < 10) res_rap_t2m = "0" + res_rap_t2m;
         var res_rap_t2s = res_rap_t2h + ":" + res_rap_t2m
         var doTotals = (groupres != 16 && groupres != 18 && groupres != 19)
         var rst = new ResultsetTable({ keyColumn: "res_keycolumn",
                                        ID: "restable",
                                        sql: sql,
                                        totalCalc: (doTotals ? fntotalCalc : null),
                                        totalShow: (doTotals ? fntotalShow : null),
                                        filterParams: params,
                                        outputmode: outputmode,
                                        title: L("lcl_res_PPI_title") + " " + L("lcl_res_PPI_fromto").format(res_rap_t1s, res_rap_t2s),
                                        showAll: showall
                                      });

        // Kolommen [L("lcl_location"), "locatie", "Text"]
        res_colums.length
        for (var i = 0; i < res_colums.length; i++)
        {
          rst.addColumn(new Column({ caption: res_colums[i][0], content: res_colums[i][1], datatype: res_colums[i][2], total: res_colums[i][3], average: res_colums[i][4] }));
        }

        var count = rst.processResultset();
%>
    </body>
  </html>
<%
}
%>
