<%@ LANGUAGE = JavaScript %>
<%  Server.ScriptTimeout=6000; %>
<% /*
     $Revision$
     $Id$

     File:               mjb_incl_scen_save.asp
     Description:        Opnemen van periodieke taken in een scenario
     Parameters:
         ins_keys        Array van object keys.
         srtcont_keys    Array van soort controlesopdracht keys
         scen_key        Scenario key waarin de periodieke taken in opgenomen dienen te worden.
     Context:
     Note:

*/ %>

<%
var JSON_Result = true;
%>

<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../ins/ins.inc" -->

<%
protectRequest.validateToken();
var scen_key =  getFParamInt("scen_key");

var scen_key_arr = [];
var deelsrtcontrstatus_arr = [];
var isfreezeyear_arr = [];
var ctrdisc_key_arr = [];
var totalcopy = getFParamInt("totalcopy", 0) == 1;
if (totalcopy)
{ // 1 Willekeurig object en controle ophalen om straks 1 maal de rechten te checken en in 1 keer een copie te maken van alle controles.
  // Alleen kijken naar 1) MJOB objecten.
  //                    2) de taakcategorieën die CTRUSE schrijf rechten hebben.
  //                       Level of 3D authorization is 3: 3 = Read and Write separately authorizable (Ja/Nee).
  var sql = "SELECT ins_deel_key"
          + "     , ins_srtcontrole_key"
          + "  FROM ins_v_defined_inspect di"
          + " WHERE di.ctr_ismjob = 1"
          + "   AND EXISTS (SELECT 1"
          + "                 FROM fac_v_webgebruiker w"
          + "                    , fac_functie f"
          + "                WHERE w.prs_perslid_key = " + user_key
          + "                  AND w.fac_functie_key = f.fac_functie_key"
          + "                  AND ins_discipline_key = di.ctr_discipline_key"
          + "                   AND fac_gebruiker_alg_level_write = -1"
          + "                  AND fac_functie_code = 'WEB_CTRUSE')"
          + " ORDER BY ins_deel_key DESC"
  var oRs = Oracle.Execute(sql);
  var ins_key_arr = [oRs("ins_deel_key").Value];
  var srtcont_key_arr = [oRs("ins_srtcontrole_key").Value];
  oRs.Close();

  var sql = "SELECT isc.ctr_discipline_key"
          + "  FROM ins_srtcontrole isc"
          + " WHERE isc.ins_srtcontrole_key = " + srtcont_key_arr[0];
  var oRs = Oracle.Execute(sql);
  ctrdisc_key_arr = [oRs("ctr_discipline_key").Value];
  oRs.Close();
}
else
{
  var ins_key_arr = getFParamIntArray("ins_keys");
  var srtcont_key_arr = getFParamIntArray("srtcont_keys");
  var scen_key_arr = getFParamIntArray("scen_key_arr", []);
  var deelsrtcontrstatus_arr = getFParamIntArray("deelsrtcontrstatus_arr", []);
  var isfreezeyear_arr = getFParamIntArray("isfreezeyear_arr", []);
  var ctrdisc_key_arr = getFParamIntArray("ctrdisc_keys", []);
  var aantaltaken = getFParamInt("aantaltaken", 0);
}

lcl.set_dialect(ctrdisc_key_arr[0], "INS_TAB_DISCIPLINE_KEY");

var tobeincluded = 0;
var ingesloten = [];
// Bepaal de objecten in de selectie die
// ook echt opgenomen kunnen of mogen worden in het scenario.
for (var i = 0; i < ins_key_arr.length; i++)
{
  var notexist = true;
  if (scen_key > 0)
  { // Er is een bestaand scenario opgegeven?
    sql = "SELECT ins_srtcontroledl_xcp_key"
        + "  FROM ins_srtcontroledl_xcp"
        + " WHERE ins_deel_key = " + ins_key_arr[i]
        + "   AND ins_srtcontrole_key = " + srtcont_key_arr[i]
        + "   AND ins_scenario_key = " + scen_key;
    oRs = Oracle.Execute(sql);
    notexist = oRs.eof;
    oRs.Close();
  }

  // Elke taak wordt gecontroleerd of deze toegevoegd mag worden. Dit gebeurt door de functie "func_enabled_deel" aan te roepen die het in de "canAddToScen" parameter stopt.
  // De query in die functie om de benodigde gegevens (isScenario, deelsrtcontrole_status, isfreezeyear) op te halen kost veel tijd. Daarom krijgt men vaak een script timeout.
  // De benodigde gegevens kunnen ook al met de query van de functie ins.getmjblist_sql bepaald worden. De rechten kunnen we hier ook zelf bepalen.
  // Dus vanwege zeer veel tijdwinst gaan we zelf canAddToScen bepalen.

    // Bij totalcopy wordt alleen de eerste gecontroleerd. Dan kunnen we de functie func_enabled_deel wel gebruiken.
  if (totalcopy)
  {
    var this_ins = ins.func_enabled_deel(ins_key_arr[i], {srtcont_key: srtcont_key_arr[i]});
   var canAddToScen = this_ins.canAddToScen;
  }
  else
  {
    // Voor CTR alleen discipline autorisatie met 3D ja/nee en read/write autorisatie (fac_functie_min_level = 3)
    var ctrresult = user.func_enabled("CTR",
                                      ctrdisc_key_arr[i],
                                      null, // alg_key is nvt
                                      null, // prs_key in nvt
                                      false, // pessimist (checkOptimistic)
                                      true); // nog even optional (isOptional)
    var hasWrite = false;
    if (ctrresult.canWrite("WEB_CTRSEN")) // Heb ik schrijf rechten om periodieke taken uit te voeren in de actuele situatie (WEB_CTRUSE) of bij scenario's (WEB_CTRSEN)?
      var hasWrite = true;
    else
    { // Dan kijken we of de objectbeheerder het object mag wijzigen en de user de objectbeheerder is.
      if (S("ins_can_edit_own_objects"))
      {
        var sql_b = "SELECT d.prs_perslid_key_beh"
                 + "  FROM ins_deel d"
                 + " WHERE d.ins_deel_key = " + ins_key_arr[i];
        var oRs_b = Oracle.Execute(sql_b);
        var beheerder_key = oRs_b("prs_perslid_key_beh").value;
        var objectbeheerder = (beheerder_key == user_key);
        oRs_b.Close();
        hasWrite = objectbeheerder;
      }
    }
    var isScenario = scen_key_arr[i] > 1;

    var canAddToScen = (hasWrite && !isScenario) &&
                       ((deelsrtcontrstatus_arr[i] != 2 && deelsrtcontrstatus_arr[i] != 5) || !isfreezeyear_arr[i]);
  }

  if (notexist && canAddToScen) // Mag ik de taak aan het scenario toevoegen?
  {
    ingesloten.push({ins_key: ins_key_arr[i], srtcont_key: srtcont_key_arr[i]});
    tobeincluded++;
  }
}
// Hier geen "user.anything_todo_or_abort(tobeincluded > 0);". We geven altijd een melding terug hoeveel taken er aan scenario zijn toegevoegd.

var result = {success: true, message: "", ins_keys: ins_key_arr.join(","), srtcont_keys: srtcont_key_arr.join(",")};

if (tobeincluded > 0)
{ // Er zijn taken die aan het scenario kunnen worden toegevoegd.
  // Is er een nieuw scenario opgegeven?
  if (scen_key < 0)
  { // Er is een nieuw scenario opgegeven.
    var fields = [{ dbs: "ins_scenario_omschrijving", typ: "varchar",  frm: "scenoms" },
                  { dbs: "ins_scenario_opmerking",    typ: "varchar",  frm: "scenopm" },
                  { dbs: "ins_scenario_status",       typ: "number",   val: 0 },
                  { dbs: "prs_perslid_key",           typ: "key",      val: user_key },
                  { dbs: "ins_scenario_key",          typ: "key",      seq: "ins_s_ins_scenario_key" }
                 ];

    var scenIns = buildInsert("ins_scenario", fields);
    scen_key = scenIns.sequences["ins_scenario_key"];

    var err = Oracle.Execute(scenIns.sql, true);
    if (err.friendlyMsg)
    {
      result.warning = err.friendlyMsg;
      result.success = false;
    }
  }
  result.scen_key = scen_key;

  Oracle.Transaction();

  for (var i = 0; i < ingesloten.length; i++)
  { // Toevoegen van de taak voor het object aan het (nieuwe) scenario.
    // Alleen MJOB objecten.
    // Als totalcopy:
    // - dan wordt de for lus 1 maal doorlopen en worden alle controles in 1 keer aangemaakt.
    // - dan alleen kijken naar de taakcategorieën die WEB_CTRUSE of WEB_CTRSEN schrijf rechten hebben.
    //   Level of 3D authorization is 3: 3 = Read and Write separately authorizable (Ja/Nee).
    sql = "INSERT INTO ins_srtcontroledl_xcp (ins_srtcontroledl_xcp_key"
        + "                                 , ins_deel_key"
        + "                                 , ins_srtcontrole_key"
        + "                                 , ins_srtcontroledl_xcp_periode"
        + "                                 , ins_srtcontroledl_xcp_eenheid"
        + "                                 , ins_srtcontroledl_xcp_bits"
        + "                                 , ins_srtcontroledl_xcp_uren"
        + "                                 , ins_srtcontroledl_xcp_materia"
        + "                                 , ins_srtcontroledl_xcp_kosten"
        + "                                 , ins_srtcontroledl_xcp_kosten2"
        + "                                 , ins_srtcontroledl_xcp_kosten3"
        + "                                 , ins_srtcontroledl_xcp_perc"
        + "                                 , ins_srtcontroledl_xcp_groep"
        + "                                 , ins_srtcontroledl_xcp_eind"
        + "                                 , ins_srtcontroledl_xcp_opmerk"
        + "                                 , ins_srtcontroledl_xcp_startdat"
        + "                                 , ins_srtcontroledl_xcp_aantal"
        + "                                 , ins_srtcontroledl_xcp_aanteh"
        + "                                 , ins_scenario_key)"
        + "            SELECT ins_s_srtcontroledl_xcp_key.nextval"
        + (!totalcopy
          ? "               , " + ingesloten[i].ins_key
          : "               , xcp.ins_deel_key")
        + "                 , isc.ins_srtcontrole_key"
        + "                 , xcp.ins_srtcontroledl_xcp_periode"
        + "                 , xcp.ins_srtcontroledl_xcp_eenheid"
        + "                 , xcp.ins_srtcontroledl_xcp_bits"
        + "                 , xcp.ins_srtcontroledl_xcp_uren"
        + "                 , xcp.ins_srtcontroledl_xcp_materia"
        + "                 , xcp.ins_srtcontroledl_xcp_kosten"
        + "                 , xcp.ins_srtcontroledl_xcp_kosten2"
        + "                 , xcp.ins_srtcontroledl_xcp_kosten3"
        + "                 , xcp.ins_srtcontroledl_xcp_perc"
        + "                 , xcp.ins_srtcontroledl_xcp_groep"
        + "                 , xcp.ins_srtcontroledl_xcp_eind"
        + "                 , xcp.ins_srtcontroledl_xcp_opmerk"
        + "                 , xcp.ins_srtcontroledl_xcp_startdat"
        + "                 , xcp.ins_srtcontroledl_xcp_aantal"
        + "                 , xcp.ins_srtcontroledl_xcp_aanteh"
        + "                 , " + scen_key
        + "                FROM ins_srtcontroledl_xcp xcp"                      // De view ins_v_defined_inspect_xcp is vervangen door alleen de tabellen en de kolommen erbij te halen die nodig zijn.
        + "                   , ins_srtcontrole isc"                            // Dit scheelt zeer veel in de uitvoertijd van de query. Er kunnen nu veel meer INSERTS worden uitgevoerd voordat een timout optreed.
        + "                   , ctr_disc_params cdp"
        + "               WHERE xcp.ins_srtcontrole_key(+) = isc.ins_srtcontrole_key"
        + "                 AND isc.ctr_discipline_key = cdp.ctr_ins_discipline_key"
        + "                 AND COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode) > 0"
        + (!totalcopy
          ? "             AND xcp.ins_deel_key(+) = " + ingesloten[i].ins_key
            + "           AND isc.ins_srtcontrole_key = " + ingesloten[i].srtcont_key
            + "           AND xcp.ins_scenario_key(+) = 1"
          : "             AND EXISTS (SELECT 1"
            + "                         FROM fac_v_webgebruiker w"
            + "                            , fac_functie f"
            + "                        WHERE w.prs_perslid_key = " + user_key
            + "                          AND w.fac_functie_key = f.fac_functie_key"
            + "                          AND ins_discipline_key = ctr_discipline_key"
            + "                           AND fac_gebruiker_alg_level_write = -1"
            + "                          AND fac_functie_code IN ('WEB_CTRUSE', 'WEB_CTRSEN'))"
            + "           AND xcp.ins_scenario_key = 1")
        + "               AND cdp.ctr_disc_params_ismjob = 1";

    var err = Oracle.Execute(sql, true);
    if (err.friendlyMsg)
    {
      result.warning = err.friendlyMsg;
      result.success = false;
    }

    ins.testInspectInsert(ingesloten[i].ins_key, ingesloten[i].srtcont_key, scen_key);
    sql = "INSERT INTO ins_deelsrtcontrole(ins_deelsrtcontrole_key"
        + "                              , ins_deel_key"
        + "                              , ins_srtcontrole_key"
        + "                              , ins_deelsrtcontrole_plandatum"
        + "                              , ins_deelsrtcontrole_status"
        + "                              , prs_perslid_key"
        + "                              , ins_scenario_key)"
        + (totalcopy
          ? "            SELECT ins_s_ins_deelsrtcontrole_key.NEXTVAL"
            + "               , xcp.ins_deel_key"
            + "               , xcp.ins_srtcontrole_key"
            + "               , (SELECT MAX(dsc.ins_deelsrtcontrole_plandatum)" // Er kunnen twee lopende records zijn. Plandatum nemen die het verst in de toekomst ligt.
            + "                    FROM ins_deelsrtcontrole dsc"
            + "                   WHERE dsc.ins_deel_key = xcp.ins_deel_key"
            + "                     AND dsc.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
            + "                     AND dsc.ins_scenario_key = 1"
            + "                     AND dsc.ins_deelsrtcontrole_status < 5) plandatum"
            + "               , 0"
            + "               , " + user_key
            + "               , " + scen_key
            + "            FROM ins_v_defined_inspect_xcp xcp"
            + "           WHERE xcp.ins_srtcontrole_periode > 0"
            + "             AND xcp.ins_scenario_key = 1"
            + "             AND xcp.ctr_ismjob = 1"
          : "            SELECT ins_s_ins_deelsrtcontrole_key.NEXTVAL"
            + "               , " + ingesloten[i].ins_key
            + "               , isc.ins_srtcontrole_key"
            + "               , (SELECT MAX(dsc.ins_deelsrtcontrole_plandatum)" // Er kunnen twee lopende records zijn. Plandatum nemen die het verst in de toekomst ligt.
            + "                    FROM ins_deelsrtcontrole dsc"
            + "                   WHERE dsc.ins_deel_key = " + ingesloten[i].ins_key
            + "                     AND dsc.ins_srtcontrole_key = isc.ins_srtcontrole_key"
            + "                     AND dsc.ins_scenario_key = 1"
            + "                     AND dsc.ins_deelsrtcontrole_status < 5) plandatum"
            + "               , 0"
            + "               , " + user_key
            + "               , " + scen_key
            + "            FROM ins_srtcontroledl_xcp xcp"                      // Voor het stuk voor stuk INSERTEN (!totalcopy) van de taken is de view ins_v_defined_inspect_xcp niet gebruikt.
            + "               , ins_srtcontrole isc"                            // De view ins_v_defined_inspect_xcp is vervangen door alleen de tabellen en de kolommen erbij te halen die nodig zijn.
            + "               , ctr_disc_params cdp"                            // Dit scheelt zeer veel in de uitvoertijd van de query. Er kunnen nu veel meer INSERTS worden uitgevoerd voordat een timout optreed.
            + "           WHERE xcp.ins_srtcontrole_key(+) = isc.ins_srtcontrole_key"
            + "             AND isc.ctr_discipline_key = cdp.ctr_ins_discipline_key"
            + "             AND COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode) > 0"
            + "             AND xcp.ins_deel_key(+) = " + ingesloten[i].ins_key
            + "             AND isc.ins_srtcontrole_key = " + ingesloten[i].srtcont_key
            + "             AND xcp.ins_scenario_key(+) = 1"
            + "             AND cdp.ctr_disc_params_ismjob = 1");

    var err = Oracle.Execute(sql, true);
    if (err.friendlyMsg)
    {
      result.warning = err.friendlyMsg;
      result.success = false;
    }
    if ((i % 1000) == 999) // Modulus. Bij elke 100 committen.
    {
      Oracle.Commit();
      Oracle.Transaction();
    }
  }

  Oracle.Commit();
}

if (ingesloten.length < aantaltaken)
{ // Niet alle taken zijn toegevoegd aan scenario.
  result.message = ingesloten.length == 1? L("lcl_mjb_inclscen_mes_1").format(aantaltaken) : L("lcl_mjb_inclscen_mes_n").format(ingesloten.length, aantaltaken);
}
else
{ // Alle taken zijn toegevoegd aan scenario.
  result.toaster = L("lcl_mjb_inclscen_completed");
}

Response.Write(JSON.stringify(result));
%>
<% ASPPAGE_END(); %>
