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

<%
//
//  Include file (ASP) used for adding a 3D ALG (place) and PRS (organisation) authorization clause
//  to an SQL statement 'psql' that is being build
//  It requires some column names that represent the columns of discipline, place and organisation
//  levels in this SQL statement, and return the modified psql variable
//  Since it creates several UNIONs based upon the current sql statement,
//  it must be called at the end of the sql creation, i.e. sql must be complete (apart from order by)
//  Variabele pdisc is used (if present) to restrict the condition to only the disciplines in this (array) list
//
//  Every builded ALG union is given to the funcion algxprs(), which is copying the union in
//  different unions extended with the different PRS extentions.
//  Another possibility was to build de PRS unions first, and than copying it and extend it with
//  the different ALG extention.
//  Parameter palgprs is used to tell which 3D authorisation should be used:
//    Only ALG = 0
//    Only PRS = 1
//    Both ALG and PRS = 2
//

function buildprsscope()
{
  var prsscope = {};
  var sql = "SELECT prs_bedrijf_key"
          + "     , prs_afdeling_key1"
          + "     , prs_afdeling_key2"
          + "     , prs_afdeling_key3"
          + "     , prs_afdeling_key4"
          + "     , prs_afdeling_key5"
          + "  FROM prs_v_afdeling_boom b, prs_perslid p"
          + " WHERE b.prs_afdeling_key = p.prs_afdeling_key"
          + "   AND p.prs_perslid_key = " + user_key;
  var oRs = Oracle.Execute (sql);
  prsscope.bedr = oRs("prs_bedrijf_key").Value   || -1;
  prsscope.afd1 = oRs("prs_afdeling_key1").Value || -1;
  prsscope.afd2 = oRs("prs_afdeling_key2").Value || -1;
  prsscope.afd3 = oRs("prs_afdeling_key3").Value || -1;
  prsscope.afd4 = oRs("prs_afdeling_key4").Value || -1;
  prsscope.afd5 = oRs("prs_afdeling_key5").Value || -1;
  oRs.close();
  return prsscope;

}

var prsscope = null;
function algxprs(psql, oRsPArr,
                 pdiscipline_column_3d,
                 pbedrijf_column_3d,
                 pafdeling_column_3d,
                 pautfunction,
                 psql_group_by)
{
   var logPautfunction = (typeof pautfunction == "object" && pautfunction instanceof Array ? pautfunction.join(" || ") : pautfunction);
   __Log({ "discipline_column_3d" : pdiscipline_column_3d,
           "bedrijf_column_3d"    : pbedrijf_column_3d,
           "afdeling_column_3d"   : pafdeling_column_3d,
           "autfunction"          : logPautfunction,
           "oRsPArr.length"       : oRsPArr.length});

  //__Log('InputSQL: <small>' + psql + '</small>');

  // ==============================
  // === BUILD PRS_AUTORISATION ===
  // ==============================

  // Iterate through all disciplines

  var fullSQL = "" // Build a UNION for each INS_DISCIPLINE

  var y = 0;
  while (y < oRsPArr.length)
  {
    var discsOfThisLevel = [];
    var thisLevel = oRsPArr[y].level;
    while (y < oRsPArr.length && oRsPArr[y].level == thisLevel)
    {
      discsOfThisLevel.push(oRsPArr[y].disc);
      y++;
    }
    var multiCol = false;
    var disc_3d_sql = "";
    if (typeof pdiscipline_column_3d != "string")
    {
      if (pdiscipline_column_3d.length == 1)
          pdiscipline_column_3d = pdiscipline_column_3d[0];
      else if (pdiscipline_column_3d.length > 1)
          multiCol = true;
    }
    if (multiCol)
    {
      var disc_column_arr = [];
      for (var z = 0; z < pdiscipline_column_3d.length; z++)
      {
        disc_column_arr.push(pdiscipline_column_3d[z] + " IN (" + discsOfThisLevel.join(", ") + ")");
      }
      disc_3d_sql = "(" + disc_column_arr.join(" OR ") + ")";
    }
    else
      disc_3d_sql = pdiscipline_column_3d + " IN (" + discsOfThisLevel.join(", ") + ")";

    fullSQL += (fullSQL == ""
               ? ""
               : (psql_group_by? psql_group_by : "") + " \nUNION ALL\n ")
             + psql + " AND " + disc_3d_sql;
    __Log(logPautfunction+' for disciplines ' + discsOfThisLevel.join(", ") + ' authorized at PRS level ' + thisLevel);

    var ignoreLevel = !pdiscipline_column_3d && !pbedrijf_column_3d && !pafdeling_column_3d;
    if (thisLevel == -1 || ignoreLevel)
    { // Done
    }
    else
        {
            if (prsscope == null)
              prsscope = buildprsscope(); // alleen ophalen als nodig

                 if (thisLevel== 0) { fullSQL += " AND " + pbedrijf_column_3d  + "  =  " + prsscope.bedr }
            else if (thisLevel== 1) { fullSQL += " AND " + pafdeling_column_3d + "1 =  " + prsscope.afd1 }
            else if (thisLevel== 2) { fullSQL += " AND " + pafdeling_column_3d + "2 =  " + prsscope.afd2 }
            else if (thisLevel== 3) { fullSQL += " AND " + pafdeling_column_3d + "3 =  " + prsscope.afd3 }
            else if (thisLevel== 4) { fullSQL += " AND " + pafdeling_column_3d + "4 =  " + prsscope.afd4 }
            else if (thisLevel== 5) { fullSQL += " AND " + pafdeling_column_3d + "5 =  " + prsscope.afd5 }
            else __Log("Waarschuwing: niveau nog niet ondersteund: " + thisLevel)
        }
  }
  __Log("end algxprs()");
  // we return the extended version of psql, or, if NO discipline was read authorized we prohibit the selection

  return (fullSQL != "" ? fullSQL : psql + " AND 1 = 2");
}

function prshasrestrict(pautfunction)
{
  var sql = "SELECT COUNT(ins_discipline_key)"
          + " FROM fac_v_webgebruiker wg, fac_functie f"
          + " WHERE wg.prs_perslid_key = " + user_key
          + "   AND f.fac_functie_key = wg.fac_functie_key"
          + (typeof pautfunction == "object" && pautfunction instanceof Array
            ? " AND f.fac_functie_code IN (" + safe.quoted_sql_join(pautfunction) + ")"
            : " AND f.fac_functie_code = " + safe.quoted_sql(pautfunction))
          + "   AND wg.fac_gebruiker_prs_level_read > -1";

  var oRs = Oracle.Execute(sql);

  if (!oRs.eof)
  {
    var count = oRs(0).Value;
    if (count > 0) return true;
  }
  oRs.Close();
  return false;
}

function buildalgscope ()
{
    var algscope = { rekeys: "-1",
                     dkeys: "-1",
                     lkeys: "-1",
                     gkeys: "-1",
                     fkeys: "-1",
                     rkeys: "-1"
                   };
    var oRs;
    oRs = Oracle.Execute ("SELECT alg_regio_key FROM alg_v_my_region" +
                          " WHERE prs_perslid_key = " + user_key) // Level 0
    var rekeys = [] // List of my region keys
    while (!oRs.eof)
    {
        rekeys.push(oRs(0).Value);
        oRs.MoveNext();
    }
    oRs.Close();
    if (rekeys.length) algscope.rekeys = rekeys.join(", ");
    oRs = Oracle.Execute ("SELECT alg_district_key FROM alg_v_my_district" +
                          " WHERE prs_perslid_key = " + user_key) // Level 1
    var dkeys = [] // List of my district keys
    while (!oRs.eof)
    {
      dkeys.push(oRs(0).Value);
      oRs.MoveNext()
    }
    oRs.Close();
    if (dkeys.length) algscope.dkeys = dkeys.join(", ");
    oRs = Oracle.Execute ("SELECT alg_locatie_key FROM alg_v_my_location" +
                          " WHERE prs_perslid_key = " + user_key) // Level 2
    var lkeys = []; // List of my location keys
    while (!oRs.eof)
    {
      lkeys.push(oRs(0).Value);
      oRs.MoveNext()
    }
    oRs.Close();
    if (lkeys.length) algscope.lkeys = lkeys.join(", ");
    oRs = Oracle.Execute ("SELECT alg_gebouw_key FROM alg_v_my_building" +
                          " WHERE prs_perslid_key = " + user_key) // Level 3
    var gkeys = []; // List of my building keys
    while (!oRs.eof)
    {
      gkeys.push(oRs(0).Value);
      oRs.MoveNext()
    }
    oRs.Close();
    if (gkeys.length) algscope.gkeys = gkeys.join(", ");
    oRs = Oracle.Execute ("SELECT alg_verdieping_key FROM alg_v_my_floor" +
                          " WHERE prs_perslid_key = " + user_key) // Level 4
    var fkeys = []; // List of my floor keys
    while (!oRs.eof)
    {
      fkeys.push(oRs(0).Value);
      oRs.MoveNext()
    }
    oRs.Close();
    if (fkeys.length) algscope.fkeys = fkeys.join(", ");
    oRs = Oracle.Execute ("SELECT alg_ruimte_key FROM alg_v_my_room" +
                          " WHERE prs_perslid_key = " + user_key) // Level 4
    var rkeys = []; // List of my room keys
    while (!oRs.eof)
    {
      rkeys.push(oRs(0).Value);
      oRs.MoveNext()
    }
    oRs.Close();
    if (rkeys.length) algscope.rkeys = rkeys.join(", ");
    return algscope;
}

var algscope = null;
function discx3d(psql,
                 pdiscipline_column_3d,
                 pregio_column_3d,
                 pdistrict_column_3d,
                 plocatie_column_3d,
                 pgebouw_column_3d,
                 pverdieping_column_3d,
                 pruimte_column_3d,
                 pbedrijf_column_3d,
                 pafdeling_column_3d,
                 pautfunction,
                 pdisc, // Array met disciplines.
                 palgprs,
                 psql_group_by,
                 minlevel_arr)
{
   var logPautfunction = (typeof pautfunction == "object" && pautfunction instanceof Array ? pautfunction.join(" || ") : pautfunction);
   var pdisc = pdisc || [];
  __Log({  "discipline_column_3d" : pdiscipline_column_3d,
           "regio_column_3d" : pregio_column_3d,
           "district_column_3d" : pdistrict_column_3d,
           "locatie_column_3d" : plocatie_column_3d,
           "gebouw_column_3d" : pgebouw_column_3d,
           "verdieping_column_3d" : pverdieping_column_3d,
           "ruimte_column_3d" : pruimte_column_3d,
           "bedrijf_column_3d" : pbedrijf_column_3d,
           "afdeling_column_3d" : pafdeling_column_3d,
           "autfunction" : logPautfunction,
           "disc" : pdisc.join(", "),
           "algprs" : palgprs,
           "psql_group_by" : psql_group_by,
           "minlevel" : minlevel_arr});

  //__Log('InputSQL: <small>' + psql + '</small>');

  var fullSQL = "";
  var oRs;
  if (palgprs == 0 || palgprs == 2)
  { // ==============================
    // === BUILD ALG_AUTORISATION ===
    // ==============================

    // Iterate through all disciplines
    var sqlDA = "SELECT DISTINCT i.ins_discipline_key, fac_gebruiker_alg_level_read, isd.ins_srtdiscipline_alg"
              + "  FROM fac_v_webgebruiker wg, fac_functie f, ins_tab_discipline i, ins_srtdiscipline isd"
              + " WHERE wg.prs_perslid_key = " + user_key
              + "   AND f.fac_functie_key = wg.fac_functie_key"
              + (typeof pautfunction == "object" && pautfunction instanceof Array
                ? " AND f.fac_functie_code IN (" + safe.quoted_sql_join(pautfunction) + ")"
                : " AND f.fac_functie_code = " + safe.quoted_sql(pautfunction))
              + "   AND wg.fac_gebruiker_alg_level_read < 9"
              + "   AND wg.ins_discipline_key = i.ins_discipline_key"
              + "   AND i.ins_srtdiscipline_key = isd.ins_srtdiscipline_key(+)"
              + "   AND i.ins_discipline_verwijder is NULL";
    var sqlDP = "SELECT DISTINCT i.ins_discipline_key, fac_gebruiker_prs_level_read, isd.ins_srtdiscipline_alg"
              + "  FROM fac_v_webgebruiker wg, fac_functie f, ins_tab_discipline i, ins_srtdiscipline isd"
              + " WHERE wg.prs_perslid_key = " + user_key
              + "   AND f.fac_functie_key = wg.fac_functie_key"
              + (typeof pautfunction == "object" && pautfunction instanceof Array
                ? " AND f.fac_functie_code IN (" + safe.quoted_sql_join(pautfunction) + ")"
                : " AND f.fac_functie_code = " + safe.quoted_sql(pautfunction))
              + "   AND wg.fac_gebruiker_prs_level_read < 9"
              + "   AND wg.ins_discipline_key = i.ins_discipline_key"
              + "   AND i.ins_srtdiscipline_key = isd.ins_srtdiscipline_key(+)"
              + "   AND i.ins_discipline_verwijder is NULL";
    if (pdisc.length)
    {
      sqlDA += " AND i.ins_discipline_key IN (" + pdisc.join(",") + ")";
      sqlDP += " AND i.ins_discipline_key IN (" + pdisc.join(",") + ")";
    }
    if (minlevel_arr && minlevel_arr.length) // RES filtert extra hard.
    {                 // Het is alleen voor de performanc om er geen onnodige discplines bij te slepen
      sqlDA += " AND i.ins_discipline_min_level IN ({0})".format(minlevel_arr.join(","));
      sqlDP += " AND i.ins_discipline_min_level IN ({0})".format(minlevel_arr.join(","));
    }
    sqlDA += " ORDER BY 2, 3, 1";  // we need this
    sqlDP += " ORDER BY 2, 3, 1";  // we need this
    var oRsP = Oracle.Execute(sqlDP); // used for PRS function algxprs()
    var oRsPArr = [];
    while (!oRsP.eof)
    {
        oRsPArr.push({ disc: oRsP("ins_discipline_key").Value, level: oRsP("fac_gebruiker_prs_level_read").Value });
        oRsP.MoveNext();
    }
    oRsP.close();

    fullSQL = "" // Build a UNION for each INS_DISCIPLINE

    var oRs = Oracle.Execute(sqlDA);  // used for ALG
    var variationCount = 0;
    while (!oRs.eof)
    {
      var discsOfThisLevel = [];
      var thisLevel = oRs("fac_gebruiker_alg_level_read").Value;
      var srtalg = (oRs("ins_srtdiscipline_alg").Value ? oRs("ins_srtdiscipline_alg").Value & 1 : 1); // andere bitjes is niveau, dat maakt hier niet uit
      if (srtalg == 0) // geen vastgoed
      {
        thisLevel == -1; // dan alsof je alle rechten hebt
      }
      while (!oRs.eof && oRs("fac_gebruiker_alg_level_read").Value == thisLevel)
      {
        discsOfThisLevel.push(oRs("ins_discipline_key").Value);
        oRs.MoveNext()
      }
      var multiCol = false;
      if (typeof pdiscipline_column_3d != "string")
      {
        if (pdiscipline_column_3d.length == 1)
            pdiscipline_column_3d = pdiscipline_column_3d[0];
        else if (pdiscipline_column_3d.length > 1)
            multiCol = true;
      }
      if (multiCol) // MLD vakgroep discipline OR behandelteam discipline
      {
        pfullSQL = psql + " AND (";
        var disc_column_arr = [];
        for (var x = 0; x < pdiscipline_column_3d.length; x++)
        {
          disc_column_arr.push(pdiscipline_column_3d[x] + " IN (" + discsOfThisLevel.join(", ") + ")");
        }
        pfullSQL += disc_column_arr.join(" OR ") + ")";
      }
      else
        pfullSQL = psql + " AND "+ pdiscipline_column_3d + " IN (" + discsOfThisLevel.join(", ") + ")";

      __Log(logPautfunction + ' for disciplines ' + discsOfThisLevel.join(", ") + ' authorized at ALG level ' + thisLevel);
      variationCount ++;
      if (variationCount > 1)
          __Log("Dit is de {0}e variatie in ALG rechten. Dat geeft minder optimale grote queries".format(variationCount), "#F88");

      // if (incidentele bestellingen) then no ALG autorisation (srtdisc==5)
      var ignoreLevel = !pregio_column_3d &&
                        !pdistrict_column_3d &&
                        !plocatie_column_3d &&
                        !pgebouw_column_3d &&
                        !pverdieping_column_3d &&
                        !pruimte_column_3d;
      if (thisLevel == -1 || srtalg == 0 || ignoreLevel)
      { // Done
      }
      else
      {
          if (algscope == null)
            algscope = buildalgscope(); // alleen ophalen als nodig
               if (thisLevel == 0) { pfullSQL += " AND " + pregio_column_3d      + " IN (" + algscope.rekeys + ")" }
          else if (thisLevel == 1) { pfullSQL += " AND " + pdistrict_column_3d   + " IN (" + algscope.dkeys  + ")" }
          else if (thisLevel == 2) { pfullSQL += " AND " + plocatie_column_3d    + " IN (" + algscope.lkeys  + ")" }
          else if (thisLevel == 3) { pfullSQL += " AND " + pgebouw_column_3d     + " IN (" + algscope.gkeys  + ")" }
          else if (thisLevel == 4) { pfullSQL += " AND " + pverdieping_column_3d + " IN (" + algscope.fkeys  + ")" }
          else if (thisLevel == 5) { pfullSQL += " AND " + pruimte_column_3d     + " IN (" + algscope.rkeys  + ")" }
          else __Log("Waarschuwing: niveau nog niet ondersteund: " + thisLevel)
      }
      // Look for every ALG union to the PRS authorisation
      if (oRsPArr.length)
      {
        fullSQL += (fullSQL == ""
                   ? ""
                   : " \nUNION /* {0} */\n ").format("ALGlevel: " + thisLevel) // Meldingen met 3D op vakgroep en behandelteam maar 1 keer opleveren (geen UNION ALL).
                 + ((palgprs == 2)
                   ? algxprs(pfullSQL, oRsPArr, pdiscipline_column_3d,
                             pbedrijf_column_3d, pafdeling_column_3d,
                             pautfunction, psql_group_by)
                   : pfullSQL)
                 + (psql_group_by
                   ? psql_group_by
                   : "");
      }
    }
    oRs.close();
  }
  else if (palgprs == 1)
  {
    // Iterate through all disciplines
    var sqlD = "SELECT i.ins_discipline_key, fac_gebruiker_prs_level_read, i.ins_srtdiscipline_key"
             + "  FROM fac_v_webgebruiker wg, fac_functie f, ins_tab_discipline i"
             + " WHERE wg.prs_perslid_key = "+user_key
             + "   AND f.fac_functie_key = wg.fac_functie_key"
             + (typeof pautfunction == "object" && pautfunction instanceof Array
               ? " AND f.fac_functie_code IN (" + safe.quoted_sql_join(pautfunction) + ")"
               : " AND f.fac_functie_code = " + safe.quoted_sql(pautfunction))
             + "   AND wg.fac_gebruiker_prs_level_read < 9"
             + "   AND wg.ins_discipline_key = i.ins_discipline_key(+)"
             + "   AND i.ins_discipline_verwijder is NULL";
    if (pdisc.length)
    {
      sqlD += " AND i.ins_discipline_key IN (" + pdisc.join(",") + ")";
    }
    sqlD += " ORDER BY 2, 1";  // we need this
    var oRsP = Oracle.Execute(sqlD); // used for PRS function algxprs()
    var oRsPArr = [];
    while (!oRsP.eof)
    {
        oRsPArr.push({ disc: oRsP("ins_discipline_key").Value, level: oRsP("fac_gebruiker_prs_level_read").Value });
        oRsP.MoveNext();
    }
    oRsP.close();

    if (oRsPArr.length)
    {
      fullSQL = algxprs(psql, oRsPArr, pdiscipline_column_3d, pbedrijf_column_3d, pafdeling_column_3d,
                        pautfunction, psql_group_by);
    }
  }
  else
  {
    __Log("Error: Unknown 3D authorisation");
  }
  // we return the extended version of psql, or, if NO discipline was read authorized we prohibit the selection
  return (fullSQL != "" ? fullSQL : psql + " AND 1 = 3");
}
%>