<%@language = "javascript" %>
<% /*
     $Revision$
     $Id$

    File:           ins_edit_inspect.asp
    Description:    Wijzigen, inplannen, afmelden of afronden van een inpectie.
    Parameters:     ins_key (geen verschil).

    Context:        Inline actie ins_list.inc of actie ins_inspect_list
    Note:           Parameter mobile doet niets met navigatie, sluiten enzo, die submit gewoon.
                    Resultaat van een submit is een json object

*/
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/iface.inc" -->
<!-- #include file="../Shared/kenmerk_common.inc" -->
<!-- #include file="../Shared/calendar.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../Shared/selector.inc" -->
<!-- #include file="ins_flexkenmerksrtcontrole.inc" -->
<!-- #include file="../Shared/discxalg3d.inc" -->
<!-- #include file="ins.inc" -->

<%
FCLTHeader.Requires({ plugins: ["jQuery", "suggest", "kenmerk"],
                           js: ["date.js"] });

var ins_key_arr = getQParamKeyArray("ins_keys", []);
var srtcont_key_arr = getQParamKeyArray("srtcont_keys", []);
var deelsrtcont_arr = getQParamKeyArray("deelsrtcont_keys", []); // Bestaande inspectie indien meegegeven.
var multi = ins_key_arr.length > 1; // Er zijn meerdere object keys meegegeven.

var insPlan = getQParamInt("plan", 0) == 1;      // Inplannen inspectie.
var insClose = getQParamInt("close", 0) == 1;    // Afmelden of afronden inspectie.
var insFinish = getQParamInt("finish", 0) == 1; // Voltooien (!multi).
var insEdit = !insPlan && !insClose && !insFinish; // Wijzigen inspectie.
var fromfinish = getQParamInt("fromfinish", 0) == 1; // Alleen Voltooien bij bulkactie (multi).
var finishmjob = getQParamInt("finishmjob", 0) == 1;
var groupby = getQParamInt("groupby", 9);
var catclose = (finishmjob && groupby < 9); // Bulk closen per categorie.

if ((insEdit || insFinish) && multi)
  abort_with_warning(L("lcl_ins_allow_multi_edit"));

var tobehandled = 0;
var ingesloten = [];
var ingeslotensc = [];
var ingeslotendsc = [];
var ingeslotenscen = [];
var canMsuEdit = false; // Alleen voor het wijzigen van inspectie (insEdit of insFinish). Er geldt dan altijd !multi.
// Bepaal de objecten/delen in de selectie die
// ook echt ingepland kunnen of mogen worden.
var ctrdisc_key = -1;
// Alle objecten moeten Gereed gemeld(5) of Afgerond(6) kunnen worden voordat de button zichtbaar mag worden.
var canClose = true;
var canFinish = true;
var nrCanFinishAfterClose = 0;

var inflatiepct = S("mjb_inflation");
var inflatiefactor = 1 + (inflatiepct / 100);
var mjb_start_year = S("mjb_start_year");
var mjb_freeze_year = Math.max(S("mjb_freeze_year"), new Date().getFullYear());

var transitParam = "";
if (catclose)
{
  // Bulk closen per categorie.
  transitParam = buildTransitParam(["close", "ins_keys", "srtcont_keys", "deelsrtcont_keys", "fromfinish", "finishmjob",
                                    "dist_key_arr", "loc_key_arr", "bld_key_arr", "disc_key_arr", "srtgroep_key_arr", "srtdeel_key_arr", "moredetail", "srtgebouw_key_arr",
                                    "groep_str_arr", "categorie_key_arr", "srtcontrole_key_arr", "frequentie_arr", "kp_key_arr", "incbtw", "showunfin", "groupby",
                                    "deel", "mjbMoved", "mjbFreezed", "mjbXcped"]);

  var dist_key_arr = getQParamKeyArray("dist_key_arr", []); // District
  var loc_key_arr = getQParamKeyArray("loc_key_arr", []); // Locatie
  var bld_key_arr = getQParamKeyArray("bld_key_arr", []); // Gebouw
  var disc_key_arr = getQParamKeyArray("disc_key_arr", []);
  var srtgroep_key_arr = getQParamKeyArray("srtgroep_key_arr", []);
  var srtdeel_key_arr = getQParamKeyArray("srtdeel_key_arr", []);
  var moredetail = getQParamInt("moredetail", 0);
  var srtgebouw_key_arr = getQParamKeyArray("srtgebouw_key_arr", []);
  var groep_str_arr = getQParamArray("groep_str_arr", []); // Groep
  var categorie_key_arr = getQParamKeyArray("categorie_key_arr", []); // Categorie
  var srtcontrole_key_arr = getQParamKeyArray("srtcontrole_key_arr", []); // Taak
  var frequentie_arr = getQParamIntArray("frequentie_arr", []); // Array met frequenties.
  var kp_key_arr = getQParamInt("kp_key_arr", -1); // Kostenplaats.
  var incbtw = getQParamInt("incbtw", 0) == 1; // Lijst inclusief BTW weergeven.
  var showunfin = getQParamInt("showunfin", 0) == 1; // Alleen onvoltooide regels.
  var deel = getQParam("deel", ""); // Identieficatie

  // FORM score velden.
  var fitness_score1_from = getQParamInt("fitness_score1_from", -1);               // Conditie score van.
  var fitness_score1_through = getQParamInt("fitness_score1_through", -1);         // Conditie score t/m.
  var fitness_score1_from_neg = getQParamInt("fitness_score1_from_neg", -1);       // Negatieve afwijking conditie score van.
  var fitness_score1_through_neg = getQParamInt("fitness_score1_through_neg", -1); // Negatieve afwijking conditie score t/m.
  var fitness_score1_from_pos = getQParamInt("fitness_score1_from_pos", -1);       // Positieve afwijking conditie score van.
  var fitness_score1_through_pos = getQParamInt("fitness_score1_through_pos", -1); // Positieve afwijking conditie score t/m.
  var priority_score2_from = getQParamInt("priority_score2_from", -1);             // Prioriteitsscore van.
  var priority_score2_through = getQParamInt("priority_score2_through", -1);       // Prioriteitsscore t/m.

  // FORM status checkboxes.
  var mjbMoved  = getQParamInt("mjbMoved", 0) == 1; // Verschoven.
  var mjbFreezed = getQParamInt("mjbFreezed", 0) == 1; // In behandeling.
  var mjbXcped = getQParamInt("mjbXcped", 0) == 1; // Aangepast.

  // Start building the query to fetch all objects satisfying
  var mjbparams = { scenario: 1,
                    fulldetails: true,
                    toyear: mjb_freeze_year,
                    jaren: [mjb_freeze_year],
                    //actsit: actsit,
                    keys: ins_key_arr,
                    niveau: groupby,   // Het niveau (betekenis) van de keys (district(1), gebouw(2), discipline(3), groep(4), objectsoort(5), object(6))
                    dist_key_arr: dist_key_arr,
                    loc_key_arr: loc_key_arr,
                    bld_key_arr: bld_key_arr,
                    disc_key_arr: disc_key_arr,
                    srtgroep_key_arr: srtgroep_key_arr,
                    srtdeel_key_arr: srtdeel_key_arr,
                    moredetail: moredetail,
                    srtgebouw_key_arr: srtgebouw_key_arr,
                    groep_str_arr: groep_str_arr,
                    categorie_key_arr: categorie_key_arr,
                    srtcontrole_key_arr: srtcontrole_key_arr,
                    frequentie_arr: frequentie_arr,
                    kp_key_arr: kp_key_arr,
                    incbtw: incbtw,
                    showunfin: showunfin,
                    deel: deel,
                    fitness_score1_from : fitness_score1_from,
                    fitness_score1_through : fitness_score1_through,
                    fitness_score1_from_neg : fitness_score1_from_neg,
                    fitness_score1_through_neg : fitness_score1_through_neg,
                    fitness_score1_from_pos : fitness_score1_from_pos,
                    fitness_score1_through_pos : fitness_score1_through_pos,
                    priority_score2_from : priority_score2_from,
                    priority_score2_through : priority_score2_through,
                    mjbMoved: mjbMoved,
                    mjbFreezed: mjbFreezed,
                    mjbXcped: mjbXcped,
                    groupby: 9, // Ik wil alle objecten opvragen.
                    finish: true,
                    getsumtypes: true
                  };

  var mjblist_sql = ins.getmjblist_sql(mjbparams);
  // De mjblist_sql bevat nu alle objecten (ins_deel_key) van de aangevinkte regels uit het mjb overzicht en levert voor elk object de waarden voor de insert op.

  var oRs = Oracle.Execute(mjblist_sql);
  user.anything_todo_or_abort(!oRs.eof); // We klagen niet over enkele wel en enkele niet

  var sumtype1 = oRs("sumtype1").Value || 0;
  var sumtype2 = oRs("sumtype2").Value || 0;
  var sumtype3 = oRs("sumtype3").Value || 0;
  tobehandled = sumtype1 + sumtype2 + sumtype3;

  var sumtyp = [];
  sumtyp[0] = tobehandled;
  sumtyp[1] = oRs("sumtype1").Value;
  sumtyp[2] = oRs("sumtype2").Value;
  sumtyp[3] = oRs("sumtype3").Value;
  oRs.Close();

  ingesloten = ins_key_arr;
}
else
{
  for (var i = 0; i < ins_key_arr.length; i++)
  {
    var this_ins = ins.func_enabled_deel(ins_key_arr[i],
                                         {srtcont_key: srtcont_key_arr[i],
                                          deelsrtcont_key: (deelsrtcont_arr[i] > 0? deelsrtcont_arr[i] : -1)
                                         });
    canMsuEdit = (insEdit || insFinish) && this_ins.canMsuEdit;

    var sql = "SELECT idsc.ins_deelsrtcontrole_key"
            + "     , idsc.ins_deelsrtcontrole_status"
            + "     , xcp.ins_srtcontroledl_xcp_eind vervaldatum"
            + "     , isc.ctr_discipline_key"
            + "     , isc.ins_srtcontrole_options options"
            + "  FROM ins_srtcontrole isc"
            + "     , ins_deelsrtcontrole idsc"
            + "     , ins_srtcontroledl_xcp xcp"
            + " WHERE isc.ins_srtcontrole_key = idsc.ins_srtcontrole_key(+)" // Er kan nog voor de eerste keer geinspecteerd moeten worden.
            + "   AND isc.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
            + "   AND xcp.ins_deel_key(+) = " + ins_key_arr[i]
            + "   AND idsc.ins_deel_key(+) = " + ins_key_arr[i]
            + "   AND isc.ins_srtcontrole_key = " + srtcont_key_arr[i]
            + (deelsrtcont_arr[i] > 0
              ? " AND idsc.ins_deelsrtcontrole_key = " + deelsrtcont_arr[i]
              : " AND idsc.ins_deelsrtcontrole_status(+) != 6")
            + "   AND idsc.ins_scenario_key(+) = 1"
            + "   AND xcp.ins_scenario_key(+) = 1"
            + " ORDER BY ins_deelsrtcontrole_datum DESC";
    var oRs = Oracle.Execute(sql);
    ctrdisc_key = oRs("ctr_discipline_key").Value;

    // Waarden moeten aanwezig zijn. Mocht dat niet zo zijn dan is er iets fout.
    // Als de laatste inspectie is afgerond is, wordt er null opgeleverd voor de ins_deelsrtcontrole_key en ins_deelsrtcontrole_status.
    // Er moet dan een nieuwe inspectie worden ingeland/gestart/afgemeld of afgerond.
    var ins_deelsrtcontrole_key = oRs("ins_deelsrtcontrole_key").Value != null? oRs("ins_deelsrtcontrole_key").Value : -1;
    var ins_deelsrtcontrole_status = oRs("ins_deelsrtcontrole_status").Value != null? oRs("ins_deelsrtcontrole_status").Value : -1;
    var vervaldatum = oRs("vervaldatum").Value != null? new Date(oRs("vervaldatum").Value) : null;
    var vervallen = vervaldatum != null && vervaldatum < new Date();
    var isc_options = oRs("options").Value;
    oRs.Close();

    // Zonder inplan rechten de inspectie niet inplannen.
    if (insPlan && !(this_ins.canInspPlan || this_ins.canInspPlanMulti)) // Inplannen. Inplan scherm n.v.t. voor MJOB.
    { // Het is niet de eerste inspectie of de laatste inspectie is niet verwerkt. Overslaan.
      continue;
    }

    // Kan de inspectie gereed gemeld/afgemeld of afgerond worden?
    if (insClose)
    { // Bij bulkacties (multi) alleen kijken naar de bulkactie die uitgevoerd moet worden.
      if ((!fromfinish && !this_ins.canInspClose) ||
          (multi && fromfinish && !(this_ins.canInspFinish || this_ins.canInspFinishMjb)) ||
          (!multi && !this_ins.canInspClose && !(this_ins.canInspFinish || this_ins.canInspFinishMjb))
         )
        // De inspectie kan niet afgemeld/afgerond worden. Overslaan.
        continue;
    }

    if (insFinish && (multi || !this_ins.canInspFinish))
    { // De inspectie kan niet afgerond/voltooid worden. Overslaan.
      continue;
    }


    // Het mag niet de eerste inspectie zijn en de laatste inspectie mag niet verwerkt zijn.
    if (insEdit && !this_ins.canInspEdit)
    { // Eerste inspectie of verwerkte inspectie kan niet gewijzigd worden. Overslaan.
      continue;
    }

    // Ik mag inplannen, gereed melden of wijzigen.
    // De vervallen LOPENDE inspecties zitten hier ook nog tussen.
    // De rest van de vervallen inspecties zijn er door canInspPlan, canInspClose en canInspEdit uitgefilterd.
    // Vervallen LOPENDE inspecties kunnen nu behandeld worden als gewone inspecties.
    // Alle Arrays zijn even groot.
    ingesloten.push(ins_key_arr[i]);
    ingeslotensc.push(srtcont_key_arr[i]);
    ingeslotendsc.push(ins_deelsrtcontrole_key);
    // Als 1 van de srtcontroles niet gereed te melden is, dan kan er niet gereed gemeld worden en moet de button niet getoond worden.
    canClose = canClose && this_ins.canInspClose;
    // Als 1 van de srtcontroles niet af te ronden is, dan kan er niet afgerond worden en moet de button niet getoond worden.
    canFinish = canFinish && (this_ins.canInspFinish || this_ins.canInspFinishMjb);
    // Kan 1 van de srtcontroles na het gereed melden worden afgerond? Dan kan ook de afrond button getoond worden. N.v.t. voor mjob.
    if (this_ins.canInspClose && this_ins.canInspFinish)
      nrCanFinishAfterClose++;
    tobehandled++;
  }
}

if (insClose && !canClose && !canFinish)
  // Als de buttons niet zichtbaar zijn heb ik niets te doen.
  tobehandled = 0;
lcl.set_dialect(ctrdisc_key, "CTR_DISCIPLINE_KEY");
user.anything_todo_or_abort(tobehandled > 0); // We klagen niet over enkele wel en enkele niet

var desc = "";
if (!catclose && ins_key_arr.length == 1)
{
    sql = "SELECT d.ins_deel_omschrijving"      // identificatie
        + "     , s.ins_srtdeel_code"
        + "     , " + lcl.xsqla('s.ins_srtdeel_omschrijving', 's.ins_srtdeel_key')
        + "     , " + lcl.xsqla('g.ins_srtgroep_omschrijving', 'g.ins_srtgroep_key')
        + "     , " + lcl.xsqla('dis.ins_discipline_omschrijving', 'dis.ins_discipline_key')
        + "  FROM ins_deel d"
        + "     , ins_srtdeel s"
        + "     , ins_srtgroep g"
        + "     , ins_tab_discipline dis"
        + " WHERE ins_deel_key = " + ins_key_arr[0]
        + "   AND d.ins_srtdeel_key = s.ins_srtdeel_key"
        + "   AND s.ins_srtgroep_key = g.ins_srtgroep_key"
        + "   AND g.ins_discipline_key = dis.ins_discipline_key";
    oRs = Oracle.Execute(sql);
    var desc    = oRs("ins_deel_omschrijving").Value;
    var sort    = oRs("ins_srtdeel_omschrijving").Value;
    var group   = oRs("ins_srtgroep_omschrijving").Value;
    oRs.Close();
}
%>

<html>
  <head>
<%  FCLTHeader.Generate(); %>

<%
    var eenheid = -1;
    var scmode = 1; // 0 = Momentmode, 1 = Intervalmode.
    var sctype = -1;
    var aanmaakdatum;
    var startdatum;
    var eersteinspectie;
    var info = "";
    if (!catclose)
    {
      sql = "SELECT *"
          + "  FROM (SELECT DISTINCT xcp.ins_srtcontrole_eenheid eenheid"
          + "             , xcp.ins_srtcontrole_info info"
          + "             , xcp.ins_srtcontrole_mode scmode"
          + "             , xcp.ctr_controle_type sctype"
          + "             , xcp.ins_deel_aanmaak"
          + "             , xcp.ins_srtcontroledl_xcp_startdat startdatum"
          + "             , xcp.ctr_ismjob ismjob"
          + "             , xcp.ins_controlemode_key"
          + "             , (SELECT COUNT (idsc1.ins_deelsrtcontrole_key)"
          + "                  FROM ins_deelsrtcontrole idsc1"
          + "                 WHERE idsc1.ins_deel_key = xcp.ins_deel_key"
          + "                   AND idsc1.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
          + "                   AND idsc1.ins_deelsrtcontrole_key NOT IN (" + ingeslotendsc.join(",") + ")" // Deze inspectie(s) zelf niet meetellen.
          + "                   AND idsc1.ins_scenario_key = 1) aantal"
          + "          FROM ins_v_defined_inspect_xcp xcp"
          + "             , ins_deelsrtcontrole idsc"
          + "         WHERE xcp.ins_srtcontrole_key = idsc.ins_srtcontrole_key(+)" // Er kan nog voor de eerste keer geinspecteerd moeten worden.
          + "           AND idsc.ins_scenario_key(+) = 1"
          + "           AND xcp.ins_scenario_key = 1"
          + "           AND xcp.ins_deel_key IN (" + ingesloten.join(",") + ")"
          + "           AND idsc.ins_deel_key(+) IN (" + ingesloten.join(",") + ")"
          + "           AND xcp.ins_srtcontrole_periode > 0"
          + "           AND xcp.ins_srtcontrole_key IN (" + ingeslotensc.join(",") + ")"
          + "       )";
      var oRs = Oracle.Execute(sql);
      eenheid = oRs("eenheid").Value;
      info = oRs("info").Value;
      scmode = oRs("scmode").Value;
      sctype = oRs("sctype").Value;
      aanmaakdatum = new Date(oRs("ins_deel_aanmaak").Value);
      startdatum = oRs("startdatum").Value != null? new Date(oRs("startdatum").Value) : null;
      mjob = oRs("ismjob").Value == 1;
      default_controlemode_key = oRs("ins_controlemode_key").Value || -1;
      eersteinspectie = ingesloten.length == 1 && oRs("aantal").Value == 0;
      oRs.MoveNext();
      while (!oRs.eof)
      {
        if (eenheid != oRs("eenheid").Value)
          eenheid = -1;
        if (scmode != oRs("scmode").Value)
          scmode = -1;
        if (sctype != oRs("sctype").Value)
        {
          info = "";
          sctype = -1; // Er zijn inspecties met verschillende soort ocntroles. Dan maar -1.
        }
        if (aanmaakdatum.getTime() < new Date(oRs("ins_deel_aanmaak").Value).getTime())
          aanmaakdatum = new Date(oRs("ins_deel_aanmaak").Value);
        if (oRs("startdatum").Value != null && (startdatum == null || startdatum.getTime() < new Date(oRs("startdatum").Value).getTime()))
          startdatum = new Date(oRs("startdatum").Value);
        oRs.MoveNext();
      }
      oRs.Close();
      // Als er meerdere inspecties zijn dan hebben bovenstaande variablen alleen een geldige waarde als het voor alle inspecties hetzelfde is.
    }

%>
    <script type="text/javascript">
      var eenheid = -1;

<%    if ((!catclose && insClose) || (!catclose && !eersteinspectie))
      { %>
        var inspected_srtcontroles = new Array();
<%
        if (sctype < 0)
          abort_with_warning(L("lcl_ins_no_same_srtcontrole"));

        if (ingesloten.length == 1)
        {
          // Is er op de inspectiedatum of op het inspectieuur al geinspecteerd voor deze objecten?
          sql = "SELECT idsc.ins_srtcontrole_key"
              + "     , idsc.ins_deelsrtcontrole_datum"
              + "     , COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, isc.ins_srtcontrole_eenheid) eenheid"
              + "     , isc.ins_srtcontrole_mode"
              + "  FROM ins_deelsrtcontrole idsc"
              + "     , ins_srtcontrole isc"
              + "     , ins_srtcontroledl_xcp xcp"
              + " WHERE idsc.ins_srtcontrole_key = isc.ins_srtcontrole_key"
              + "   AND idsc.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
              + "   AND idsc.ins_deel_key = xcp.ins_deel_key(+)"
              + "   AND idsc.ins_deel_key IN (" + ingesloten[0] + ")"
              + "   AND COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode) > 0"
              + "   AND idsc.ins_srtcontrole_key = " + ingeslotensc[0]
              + "   AND idsc.ins_scenario_key = 1"
              + "   AND xcp.ins_scenario_key(+) = 1";
          var oRs = Oracle.Execute(sql);
          while (!oRs.eof)
          { %>
            inspected_srtcontroles[inspected_srtcontroles.length] = { srtcontrole_key: <%=oRs("ins_srtcontrole_key").Value%>,
                                                                      datum: <%=new Date(oRs("ins_deelsrtcontrole_datum").Value).getTime()%>,
                                                                      eenheid: <%=oRs("eenheid").Value%>,
                                                                      mode: <%=oRs("ins_srtcontrole_mode").Value%>};
<%          oRs.MoveNext();
          }
          oRs.Close();
        }
      }

      if (!catclose)
      {
        var insstatus = -1;
        var status_str = "";
        if ((insPlan || insEdit || insFinish) && ingeslotendsc.join(",").search("-1") < 0)
        { // Bestaande inspectie.
          var sql = "SELECT ins_deelsrtcontrole_status"
                  + "  FROM ins_deelsrtcontrole"
                  + " WHERE ins_deelsrtcontrole_key = " + ingeslotendsc[0];
          var oRs = Oracle.Execute(sql);
          insstatus = oRs("ins_deelsrtcontrole_status").Value;
          status_str = ins.getinspectstatustext(oRs("ins_deelsrtcontrole_status").Value);
          oRs.Close();
        }
        else if (insClose && ingeslotendsc.join(",").search("-1") < 0)
        { // Allemaal bestaande inspecties met de status Gepland(0) of In Behandeling(2).
          // Is de status voor elke inspectie hetzelfde.
          var sql = "SELECT MIN(ins_deelsrtcontrole_status) minstatus"
                  + "     , MAX(ins_deelsrtcontrole_status) maxstatus"
                  + "  FROM ins_deelsrtcontrole"
                  + " WHERE ins_deelsrtcontrole_key IN (" + ingeslotendsc.join(",") + ")"
                  + "   AND ins_scenario_key = 1";
          var oRs = Oracle.Execute(sql);
          if (oRs("minstatus").Value == oRs("maxstatus").Value)
          { // De statussen van alle inspecties zijn hetzelfde. Dan kan ik deze tonen.
            insstatus = oRs("minstatus").Value;
            status_str = ins.getinspectstatustext(oRs("minstatus").Value);
          }
          oRs.Close();
        }
      }
%>
      function ins_submit_callback(json)
      {
        if (json.success)
            FcltMgr.closeDetail(window, json);
      }

      async function ins_submit(finish)
      {
        // Controle verplichte velden.
<%      if (!catclose)
        { %>
          // Als het veld verplicht is, dan zit de required class op het veld.
          // Als het veld verplicht is afhankelijk van de button waarop geklikt wordt, dan zit de mayberequired class op het veld.
          if (!await validateForm("u2", { checkExtraClass: (finish? "mayberequired" : "") }))
            return false;
<%      } %>

<%      if (!catclose && insPlan)
        { %>
          // Controleren voor uren inspectie of plandatum niet in het verleden ligt.
          // Dit kan alleen voorkomen bij uren omdat de uren voor vandaag de hele dag ingevuld kunnen worden.
          // Bij dagen, maanden en jaren eenheid kan vandaag niet ingevuld worden. Alleen vanaf morgen kan ingevuld worden.
          if (eenheid == 0 && new Date(parseInt($("#plandatum").val())) <= new Date())
          {
            FcltMgr.alert(L("lcl_ins_controle_not_past")); // Plandatum mag niet in het verleden liggen!
            return false;
          }
<%      }
        else if (!catclose && insClose)
        { %>
          // Controleren voor uren inspectie of inspectie uitvoerdatum na de laatste uitvoerdatum ligt.
          // Bij multi geldt de laatste uitvoerdatum van alle objecten.
          if (lastinspectdatum && new Date(parseInt($("#deelsrtcontrole_datum").val())) <= lastinspectdatum)
          {
            FcltMgr.alert(L("lcl_ins_controle_after_lastinspect"));
            return false;
          }

          // Controleren voor uren inspectie of inspectie in toekomst of respijtdatum in verleden ligt.
          // Dit kan voorkomen omdat de uren voor vandaag de hele dag ingevuld kunnen worden.
          // Het zou dus eigenlijk alleen voor uren inspecties voor kunnen komen.
          // Alleen controleren als eenheid is uren. Bij invoer kies je dan ook een bepaald uur.
          if (eenheid == 0 && new Date(parseInt($("#deelsrtcontrole_datum").val())) > new Date())
          { // Invoeren inspecteren.
            FcltMgr.alert(L("lcl_ins_controle_not_future")); // Controledatum mag niet in de toekomst liggen!
            return false;
          }

          for (var i = 0; i < inspected_srtcontroles.length; i++)
          {
            // Voor multi objecten is inspected_srtcontroles leeg.
            // In het save script worden die inspecties er dan wel uitgefilterd/overgeslagen.
            if (inspected_srtcontroles[i].srtcontrole_key == $("#sel_srtcontrole").val())
            {
              // Controle of er op de inspectiedatum of op het inspectieuur al inspecties zijn geweest
              // TODO: Wat te doen met extra inspecties. En per week/maand/jaar enz.
              var controle_datum_midnight = new Date(parseInt($("#deelsrtcontrole_datum").val())).midnight().getTime();
              var controle_datum_uur = new Date(new Date(parseInt($("#deelsrtcontrole_datum").val())).setMinutes(0,0,0)).getTime();
              var controle_datum_min = new Date(new Date(parseInt($("#deelsrtcontrole_datum").val())).setSeconds(0, 0)).getTime();

              if (controle_datum_midnight == new Date(parseInt(inspected_srtcontroles[i].datum)).midnight().getTime() &&
                  inspected_srtcontroles[i].eenheid > 0 &&
                  inspected_srtcontroles[i].mode == 0) // Geldt alleen voor momentmodus.
              { // Op dezelfde dag mag niet.
                FcltMgr.alert(L("lcl_ins_double_inspection_today"));
                return false;
              }
              else if (controle_datum_uur == new Date(new Date(parseInt(inspected_srtcontroles[i].datum)).setMinutes(0,0,0)).getTime() &&
                       inspected_srtcontroles[i].eenheid == 0 &&
                       inspected_srtcontroles[i].mode == 0) // Geldt alleen voor momentmodus.
              { // In hetzelfde uur mag niet.
                FcltMgr.alert(L("lcl_ins_double_inspection_hour"));
                return false;
              }
              else if (controle_datum_min == new Date(parseInt(inspected_srtcontroles[i].datum)).getTime() &&
                       inspected_srtcontroles[i].mode == 1) // Dat respijtdatum hetzelfde is als inspectiedatum is niet mogelijk omdat anders ook de check "respijtdatum < nudatum" geldt (zie hierboven). Er moet gelden: inspectiedatum < nu en respijtdatum > nu.
              { // Een inspectie doen op dezelfde datumtijd (controledatum hetzelfde) mag niet omdat je daarna dan niet meer de volgende inspectie kunt doen.
                // De geplande _org tijd is dan hetzelfde als de laatste inspectie omdat de volgende inspectie dan niet opgeschoven is.
                // Inspecties op dezelfde datumtijd moeten dus afgevangen worden.
                // Dit kan alleen voorkomen in de interval mode.
                FcltMgr.alert(L("lcl_ins_double_inspection"));
                return false;
              }
            }
          }
          $("#finish").val(finish);
<%      }
        else if (!catclose && (insEdit || insFinish))
        { %>
          if (dsc_is_afgemeld)
          {
            if (maxDateEdit == -1)
              // Dan is maxDate de huidige tijd new Date().
              var maxDateUitvoer = new Date();
            else
              var maxDateUitvoer = maxDateEdit;

            // Controleren of de huidige uitvoerdatum van de inspectie tussen die van de voorgaande en volgende inspectie ligt.
            var uitvoerdatum = new Date(parseInt($("#deelsrtcontrole_datum").val()));
            if (uitvoerdatum < minDateEdit || uitvoerdatum >= maxDateUitvoer)
            {
              FcltMgr.alert(L("lcl_ins_controle_between_two"));
              return false;
            }
          }
          $("#finish").val(finish);
<%      } %>

        var autoconfirm = true;
        var nextdatum;
        var uitvoerdatum;
<%      if (insClose && ingesloten.length == 1 && (!catclose && !eersteinspectie))
        { // Het is NIET de eerste inspectie.
          var sqln = "SELECT ins.nextcyclusdate (" + ingesloten[0] + ", " + ingeslotensc[0] + ", 1, 1) nextdate FROM DUAL"
          var oRsn = Oracle.Execute(sqln);
          var nextdate = new Date(oRsn("nextdate").Value);
          oRsn.Close();

          // Is er een plandatum ingevuld in de momentmode. Dan kan die plandatum voor de standaard nextdatum liggen.
          if (scmode == 0 && ingeslotendsc.join(",").search("-1") < 0) // 0 = Momentmode, 1 = Intervalmode.
          {
            var sqlp = "SELECT idsc.ins_deelsrtcontrole_plandatum"
                     + "  FROM ins_deelsrtcontrole idsc"
                     + " WHERE idsc.ins_deelsrtcontrole_key = " + ingeslotendsc[0];
            var sqlp = Oracle.Execute(sqlp);
            var plandatum = sqlp("ins_deelsrtcontrole_plandatum").Value != null? new Date(sqlp("ins_deelsrtcontrole_plandatum").Value): null;
            sqlp.Close();

            if (plandatum && plandatum < nextdate)
              nextdate = plandatum;
          }
%>
          var uitvdatum = new Date(parseInt($("#deelsrtcontrole_datum").val()));
          uitvoerdatum = inspected_srtcontroles[0].eenheid == 0? new Date(uitvdatum) : new Date(uitvdatum.midnight());
          var nextdate = new Date(<%=nextdate.getTime()%>);
          nextdatum = inspected_srtcontroles[0].eenheid == 0? new Date(nextdate) : new Date(nextdate.midnight());
          autoconfirm = uitvoerdatum >= nextdatum;
<%      } %>

        if (autoconfirm)
          var lcl_confirm = "";
        else
          var lcl_confirm = (finish? L("lcl_ins_finish_before_scheduled").format(toDateString(nextdatum), toDateString(uitvoerdatum)) : L("lcl_ins_close_before_scheduled").format(toDateString(nextdatum), toDateString(uitvoerdatum)));
        // Als het de eerste inspectie is dan worden nextdatum en uitvoerdatum niet gevuld, maar dan is autoconfirm true en wordt er geen popup getoond en de lcl dus niet gebruikt.
        FcltMgr.confirm(lcl_confirm,
                       {autoconfirm: autoconfirm || <%=ingesloten.length%> > 1}, // Parameter multi kan true zijn terwijl er maar 1 taak wordt gereedgemeld/voltooid.
                        function() {
                          $.post($("form[name=u2]")[0].action,
                                 $("[name=u2]").serialize() + "<%=transitParam%>",
                                 FcltCallbackAndThenAlways(ins_submit_callback),
                                 "json");
                        });
      }

      function ins_cancel()
      {
          FcltMgr.closeDetail(window, { cancel: true } );
      }

<%    if (!catclose && (insClose || insEdit || insFinish))
      { %>
        function onChangeDeelsrtcdatum(id)
        {
          if (id == 2) return;
          selecteddate = new Date(parseInt($("#deelsrtcontrole_datum").val())).midnight().getTime();
          if (selecteddate < new Date().midnight().getTime() && (eenheid > 0))
          { // Eenheid is geen uren.
            // Tijd op 0:00 uur zetten.
            $("#show_deelsrtcontrole_datum").datepicker("disable").datepicker("setDate", new Date(selecteddate)).datepicker("enable");
            $("#deelsrtcontrole_datum").val(selecteddate);
            $("#time_from_deelsrtcontrole_datum").val(toTimeString(new Date(selecteddate)));
          }
          else if (selecteddate == new Date().midnight().getTime() && (eenheid > 0))
          { // Eenheid is geen uren.
            // Tijd op huidige tijd zetten.
            $("#show_deelsrtcontrole_datum").datepicker("disable").datepicker("setDate", new Date()).datepicker("enable");
            $("#deelsrtcontrole_datum").val(new Date().getTime());
            $("#time_from_deelsrtcontrole_datum").val(toTimeString(new Date()));
          }
        }
<%    } %>

      function ins_melding()
      { // Meldbron Inspection meegeven (mld_meldbron_key = 10). De urole wordt bij mld_melding.asp bepaald.
        FcltMgr.openDetail("appl/mld/mld_melding.asp?meldbronkey=10&ins_key=<%=ingesloten[0]%>&deelsrtcont_key=<%=ingeslotendsc[0]%>", L("lcl_add"));
      }
    </script>
  </head>

  <body class="editmode">
  <% SUBFRAME_START(); %>
<%  // Melding aanmaakbaar? Alleen meldingen die enigzins beperkt zijn tot onze object(soort/groep)
    var canMelding = false;
    if (!catclose && !multi && ingesloten[0] > 0 && ingeslotendsc[0] > 0)
    {
        var sql = "SELECT COUNT(*) aantal"
                + "  FROM mld_stdmelding msm"
                + "     , mld_v_mld_stdmelding_srtinst mss"
                + "     , ins_tab_discipline itd"
                + "     , ins_srtdiscipline isd"
                + " WHERE msm.mld_stdmelding_key = mss.mld_stdmelding_key"
                + "   AND msm.mld_ins_discipline_key = itd.ins_discipline_key"
                + "   AND msm.mld_stdmelding_verwijder IS NULL"
                + "   AND (  (msm.mld_stdmelding_vervaldatum IS NULL)"
                + "       OR (msm.mld_stdmelding_vervaldatum > SYSDATE)"
                + "       )"
                + "   AND EXISTS"
                        + " (SELECT fw.ins_discipline_key"
                        + "    FROM fac_v_webgebruiker fw"
                        + "       , fac_functie ff"
                        + "   WHERE msm.mld_ins_discipline_key = fw.ins_discipline_key"
                        + "     AND fw.prs_perslid_key = " + user_key
                        + "     AND fw.fac_functie_key = ff.fac_functie_key"
                        + "     AND ff.fac_functie_code IN ('WEB_MLDUSE', 'WEB_MLDFOF')"// Backo mag geen meldingen aanmaken
                        + "     AND fw.fac_gebruiker_alg_level_write < 9"// In theorie zouden we ook nog kunnen ALG-scopen...
                        + " )"
                + "   AND itd.ins_srtdiscipline_key = isd.ins_srtdiscipline_key"
                + "   AND isd.ins_srtdiscipline_ins = 1"
                + "   AND mss.ins_deel_key = " + ingesloten[0];
      var oRs = Oracle.Execute(sql);
      canMelding = (oRs("aantal").Value > 0);
      oRs.Close();
    }

    // De array ingesloten bevat die delen die gepland, gewijzigd, afgemeld of afgerond mogen worden.
    // Één van de waarden insPlan, insEdit, insClose of insFinish is true.
    var buttons = [];
    var submit = false;
    var close = false;
    var finish = false;
    if (insPlan || insEdit)
    {
      buttons.push({title: (insPlan? L("lcl_ins_schedule") : L("lcl_submit")), icon: "fa-fclt-save", action:"ins_submit(0)"});
      submit = true; // Opslaan button aanwezig.
    }

    if (insClose || insFinish)
    { // Bij bulkacties (multi) alleen kijken naar de bulkactie die uitgevoerd moet worden.
      if (!catclose && canClose && !(multi && fromfinish))
      {
        buttons.push({title: L("lcl_ins_close"), icon: "fa-flag", action:"ins_submit(0)"});
        close = true; // Gereedmelden button aanwezig.
      }
      var finishAfterClose = (nrCanFinishAfterClose > 0 && multi && !fromfinish); // Na het gereed melden kan voor minstens 1 periodieke taak worden afgerond.
      if ((canFinish && (!multi || fromfinish)) || finishAfterClose)
      { // De afrond button wordt nu ook getoond bij het afmelden als er tenminste 1 periodiek taak na het gereed melden ook kan worden afgerond.
        // Als niet alle periodiek taken kunnen worden afgerond in deze situatie, dan wordt ook het aantal in de button getoond die wel kunnen worden afgerond.
        buttons.push({title: L("lcl_ins_finish") + (finishAfterClose && nrCanFinishAfterClose < tobehandled? " (" + L("lcl_count") + ":" + nrCanFinishAfterClose + ")" : ""), icon: "fa-flag-checkered",  action: "ins_submit(1)"});
        finish = true; // Voltooien button is aanwezig.
      }
    }

    if (canMelding)
      buttons.push({title: L("lcl_do_amelding"), tooltip: L("lcl_do_amelding_hint"), action: "ins_melding()", icon: "fa-wand-magic-sparkles" });
    buttons.push({title: L("lcl_cancel"),       icon: "fa-fclt-cancel",   action: "ins_cancel()"});

    var titletext;
    switch(sctype)
    {
      case 1:  titletext = L("lcl_ins_srtcontrole_insp"); break;
      case 2:  titletext = L("lcl_ins_srtcontrole_repl"); break;
      case 3:  titletext = L("lcl_ins_srtcontrole_cert"); break;
      default: titletext = L("lcl_menu_ins_controle"); break;
    }
    IFRAMER_HEADER(titletext + " " + desc, buttons);
%>
    <form name="u2" action="ins_inspect_save.asp" method="post">
      <input type="hidden" name="savemode" id="savemode" value="<%=insPlan? "P" : (insClose? "C" : "E")%>">
      <input type="hidden" name="ins_keys" id="ins_keys" value="<%=ingesloten.join(",")%>">
      <input type="hidden" name="srtcont_key_arr" id="srtcont_key_arr" value="<%=ingeslotensc.join(",")%>">
<%    if (!catclose && (insEdit || insFinish))
      { %>
        <input type="hidden" name="deelsrtcont_key" id="deelsrtcont_key" value="<%=ingeslotendsc[0]%>">
<%    } %>
      <input type="hidden" name="finish" id="finish" value="0">
<%    var blocktext = (insPlan? L("lcl_ins_schedule") : (insClose? L("lcl_ins_stop") : L("lcl_ins_controle_srt") ))
                    + (multi || catclose
                      ? " (" + L("lcl_count") + ":" + tobehandled + ")"
                      : "");
      BLOCK_START("insMultiEdit", blocktext , {icon: "fa-calendar-check"});
        if (!catclose && ins_key_arr.length == 1)
        {
          ROFIELDTR("fld", L("lcl_obj_group"), group);
          ROFIELDTR("fld", L("lcl_obj_sort"), sort);
        }
        if (!catclose && !multi)
        { // Inspecteren van één object met één of meerdere soortcontroles
          var sql = "SELECT " + lcl.xsqla("d.ins_discipline_omschrijving", "d.ins_discipline_key")
                  + "  FROM ctr_v_aanwezigdiscipline d"
                  + " WHERE d.ins_discipline_key = " + ctrdisc_key;
          var oRs = Oracle.Execute(sql);
          var ctrdisc_omschr = oRs("ins_discipline_omschrijving").Value;
          oRs.Close();
          ROFIELDTR("fld", L("ctr_discipline"), ctrdisc_omschr);

          var sql = "SELECT xcp.ins_srtcontrole_key"
                  + "     , " + lcl.xsqla('xcp.ins_srtcontrole_omschrijving', 'xcp.ins_srtcontrole_key')
                  + "     , xcp.ins_srtcontrole_info info"
                  + "     , COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, xcp.ins_srtcontrole_eenheid) eenheid"
                  + "  FROM ins_v_defined_inspect_xcp xcp"
                  + " WHERE xcp.ins_deel_key IN (" + ingesloten[0] + ")"
                  + "   AND xcp.ins_srtcontrole_periode > 0"
                  + "   AND xcp.ins_srtcontrole_key = " + ingeslotensc[0]
                  + "   AND xcp.ins_scenario_key(+) = 1"
                  + " GROUP BY xcp.ins_srtcontrole_key"
                  + "        , xcp.ins_srtcontrole_omschrijving"
                  + "        , xcp.ins_srtcontrole_info"
                  + "        , xcp.ins_srtcontrole_eenheid"
                  + "        , xcp.ins_srtcontrole_periode"
                  + "        , xcp.ins_deel_key"
                  + "        , xcp.ins_srtcontroledl_xcp_eenheid";
                  //+ "      HAVING COUNT(*) = " + 1 // Als multi dan alleen de inspecties die voor *alle* objecten gelden

          FCLTselector("sel_srtcontrole_show",
                       sql,
                       { label: L("lcl_ins_controle"),
                         initKey: ingeslotensc[0],
                         emptyOption: L("lcl_select_srtcontrole"),
                         readonly: true, // dan wordtie niet gesubmit
                         //required: true, // Als readonly dan heeft deze geen effect meer.
                         extraParamValue: "eenheid, info",
                         extraParamValueInit: "-1, "
                        });
%>
          <input type="hidden" name="sel_srtcontrole" id="sel_srtcontrole" value="<%=ingeslotensc[0]%>">
<%

          ROTEXTAREATR("fldtxt", L("lcl_ins_info"), info, {html: "rows='3'", trclass: "invoerinsp", id: "srtcontrole_info", suppressEmpty: true });
        }

        ROFIELDTR("fld", L("lcl_ins_status"), status_str, {suppressEmpty: true });


        var inspect_data;
        if (!catclose)
        {
          // Men mag alleen een inspectie-uitvoerdatum invoeren die later is dan de laatste inspectie-uitvoerdatum.
          // Bij multi ook de laatste uitvoerdatum bepalen.
          sql = "SELECT MAX(idsc.ins_deelsrtcontrole_datum) lastinspectdatum"
              + "     , MAX(idsc.ins_deelsrtcontrole_datum + 1) dag_na_lastinspectdatum"
              // De ins_deelsrtcontrole_datum_org van de laatste voltooide inspectie.
              // Bij het inplannen is dat van het laatste record. Bij het gereedmelden en wijzigen is dit het voorlaatste record.
              + (insPlan
                ? "     , MAX(idsc.ins_deelsrtcontrole_datum_org + 1)"
                : "     , (SELECT MAX(idsc2.ins_deelsrtcontrole_datum_org) + 1"
                  + "        FROM ins_deelsrtcontrole idsc2"
                  + "       WHERE idsc2.ins_deel_key = idsc.ins_deel_key"
                  + "         AND idsc2.ins_srtcontrole_key = idsc.ins_srtcontrole_key"
                  + "         AND idsc2.ins_scenario_key = idsc.ins_scenario_key"
                  + "         AND idsc2.ins_deelsrtcontrole_key NOT IN (SELECT MAX(idsc3.ins_deelsrtcontrole_key)"
                  + "                                                     FROM ins_deelsrtcontrole idsc3"
                  + "                                                    WHERE idsc3.ins_deel_key = idsc2.ins_deel_key"
                  + "                                                      AND idsc3.ins_srtcontrole_key = idsc2.ins_srtcontrole_key"
                  + "                                                      AND idsc3.ins_scenario_key = idsc2.ins_scenario_key))")
                + " dag_na_orgdatum"
              + "     , SUM (CASE"
              + "            WHEN COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, isc.ins_srtcontrole_eenheid) != 0" // Geen tijd eenheid maar dag, maand of jaar.
              + "            THEN 1" // Dag, maand of jaar.
              + "            ELSE 0" // Tijd.
              + "            END) aantal_dmj_eenheid"
              + "     , isc.ins_srtcontrole_mode"
              + "  FROM ins_deelsrtcontrole idsc"
              + "     , ins_srtcontrole isc"
              + "     , ins_srtcontroledl_xcp xcp"
              + " WHERE idsc.ins_srtcontrole_key = isc.ins_srtcontrole_key"
              + "   AND idsc.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
              + "   AND idsc.ins_deel_key = xcp.ins_deel_key(+)"
              + "   AND COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode) > 0"
              + "   AND idsc.ins_deel_key IN (" + ingesloten.join(",") + ")"
              + "   AND idsc.ins_srtcontrole_key IN (" + ingeslotensc.join(",") + ")"
              + "   AND idsc.ins_scenario_key = 1"
              + "   AND xcp.ins_scenario_key(+) = 1"
              + " GROUP BY isc.ins_srtcontrole_mode"
              + (!insPlan
                ? "      , idsc.ins_deel_key"
                  + "    , idsc.ins_srtcontrole_key"
                  + "    , idsc.ins_scenario_key"
                : "");
          var oRs = Oracle.Execute(sql);
          var lastinspectdatum;
          var dag_na_lastinspectdatum;
          var dag_na_orgdatum;
          var aantal_dmj_eenheid;
          var mode;
          var minDate = startdatum != null? startdatum : aanmaakdatum; // Als er nog geen inspecties zijn geweest dan is de startdatum of aanmaakdatum de minimale datum.
          if (!oRs.eof && oRs("lastinspectdatum").Value != null)
          {
            lastinspectdatum = new Date(oRs("lastinspectdatum").Value); // Kan uiterlijk vandaag zijn.
            dag_na_lastinspectdatum = new Date(oRs("dag_na_lastinspectdatum").Value); // Kan uiterlijk morgen zijn.
            dag_na_orgdatum = new Date(oRs("dag_na_orgdatum").Value);
            aantal_dmj_eenheid = oRs("aantal_dmj_eenheid").Value;
            mode = oRs("ins_srtcontrole_mode").Value;
            if (mode == 0)
            { // Momentmode.
              if (ingesloten.length == 1)
              {
                if (insPlan || insClose || insEdit || insFinish)
                { // De datum moet (een dag) na de uitvoerdatum en orgdatum (ins_deelsrtcontrole_datum_org) van de laatste inspectie zijn.
                  minDate = (dag_na_lastinspectdatum > dag_na_orgdatum)? dag_na_lastinspectdatum : dag_na_orgdatum;
                }
                //else // MGE: Volgens mij kun je hier niet meer komen want insPlan, insClose, insEdit of insFinish is true.
                //{ // De datum moet zeker nextdate zijn om uitgevoerd te kunnen worden.
                //  // Bereken de volgende inspectiedatum.
                //  // De functie ins.nextcyclusdate levert de volgende inspectie datum met tijd op onafhankelijk van de eenheid.
                //  var sqln = "SELECT ins.nextcyclusdate (" + ingesloten[0] + ", " + ingeslotensc[0] + ", 1, 1) nextdate FROM DUAL"
                //  var oRsn = Oracle.Execute(sqln);
                //  var nextdate = new Date(oRsn("nextdate").Value);
                //  oRsn.Close();
                //  minDate = nextdate;
                //}
              }
              else
                // Multi
                minDate = aantal_dmj_eenheid > 0? dag_na_lastinspectdatum : lastinspectdatum;
            }
            else
              // Intervalmode.
              minDate = lastinspectdatum;
%>
            <script type="text/javascript">
              var lastinspectdatum = new Date(<%=lastinspectdatum.getTime()%>);
            </script>
<%
          }
          else
          {
%>
            <script type="text/javascript">
              var lastinspectdatum = null;
            </script>
<%
          }
          oRs.Close();

          var dsc_is_afgemeld = false;
          var multidsc_has_afgemeld = false;
          if (!multi && ingeslotendsc[0] > 0)
          { // Bestaande inspectie.
            var sql = "SELECT dsc.ins_deelsrtcontrole_datum"
                    + "     , dsc.ins_controlemode_key"
                    + "     , dsc.ins_deelsrtcontrole_opmerking"
                    + "     , dsc.ins_deelsrtcontrole_plandatum"
                    + "     , dsc.ins_deelsrtcontrole_status"
                    + "  FROM ins_deelsrtcontrole dsc"
                    + "     , ins_srtcontrole isc"
                    + " WHERE dsc.ins_srtcontrole_key = isc.ins_srtcontrole_key"
                    + "   AND dsc.ins_deelsrtcontrole_key = " + ingeslotendsc[0];
            var oRs = Oracle.Execute(sql);
            inspect_data = {deelsrtcontrole_datum: oRs("ins_deelsrtcontrole_datum").Value != null? new Date(oRs("ins_deelsrtcontrole_datum").Value): null,
                            controlemode_key: oRs("ins_deelsrtcontrole_status").Value >= 5? oRs("ins_controlemode_key").Value : default_controlemode_key,
                            deelsrtcontrole_opmerking: oRs("ins_deelsrtcontrole_opmerking").Value,
                            deelsrtcontrole_plandatum: oRs("ins_deelsrtcontrole_plandatum").Value != null? new Date(oRs("ins_deelsrtcontrole_plandatum").Value) : null,
                            deelsrtcontrole_status: oRs("ins_deelsrtcontrole_status").Value,
                            deelsrtcontrole_status_str: ins.getinspectstatustext(oRs("ins_deelsrtcontrole_status").Value)
                           }
            // Als de tijd van de datum NIET middennacht (00:00) is dan mag je de datum niet wijzigen. Daarom tijd bepalen voor FCLTcalendar.
            // Wijzigen zet datum op middennacht wat problemen met een constraint kan geven.
            var hours   = inspect_data.deelsrtcontrole_datum != null? inspect_data.deelsrtcontrole_datum.getHours()   : new Date().getHours();
            var minutes = inspect_data.deelsrtcontrole_datum != null? inspect_data.deelsrtcontrole_datum.getMinutes() : new Date().getMinutes();
            dsc_is_afgemeld = inspect_data.deelsrtcontrole_status >= 5;
            oRs.Close();
          }
          else
          { // Nieuwe inspectie of multi.
            // Inplannen: Als niet multi en het is de eerste inspectie en de startdatum heeft een waarde dan deze waarde invullen als PLANDATUM.
            //            De minimum datum is dan gelijk de startdatum.
            // Gereed melden/Afronden: Als niet multi en het is de eerste inspectie en de startdatum heeft een waarde dan deze waarde invullen als CONTROLEDATUM.
            inspect_data = {deelsrtcontrole_datum: insClose && !multi && startdatum != null && eersteinspectie? startdatum : null,
                            controlemode_key: default_controlemode_key,
                            deelsrtcontrole_plandatum: insPlan? (!multi && startdatum != null && eersteinspectie? startdatum : new Date()): null,
                            deelsrtcontrole_opmerking: "",
                            deelsrtcontrole_status: insstatus,
                            deelsrtcontrole_status_str: status_str
                           };
            if (insPlan && !multi && startdatum != null && eersteinspectie)
            {
              if (mjob)
                minDate = new Date(startdatum.getFullYear() + 1, 0, 1);
              else
                minDate = startdatum;
            }
          }

          var opmerking_verplicht = 0;
          if (ingeslotensc.length > 0)
          {
            var sql = "SELECT MAX(ins_srtcontrole_opmerking_text) opm_verplicht"
                    + "  FROM ins_srtcontrole"
                    + " WHERE ins_srtcontrole_key IN (" + ingeslotensc.join(",") + ")";
            var oRs = Oracle.Execute(sql);
            opmerking_verplicht = oRs("opm_verplicht").Value;
            oRs.Close();
          }
        }

        if (!catclose && (insPlan || (insEdit && (insstatus == 0 || insstatus == 2 || insstatus == 3) && inspect_data.deelsrtcontrole_plandatum)))
          FCLTcalendar("plandatum",
                       { label: L("lcl_ins_controle_plandate"),
                         datum: minDate > inspect_data.deelsrtcontrole_plandatum? minDate : inspect_data.deelsrtcontrole_plandatum,
                         trclass: "invoerinsp",
                         minDate: minDate,
                         required : true, // Initeel hidden. Dan niet verplicht.
                         timeField: true,
                         timeStep: 60,
                         startTime: 0,
                         endTime: 23.75,
                         readonly: mjob || (insEdit && (insstatus == 2 || insstatus == 3)), // In status "Ingepland(0)" is de plandatum altijd nog aan te passen.
                         suppressEmpty: true
                       });

        if (!catclose && (insClose || ((insEdit || insFinish) && insstatus >= 5)))
        {
          FCLTcalendar("deelsrtcontrole_plandatum",
                       { label: L("lcl_ins_controle_plandate"),
                         datum: inspect_data.deelsrtcontrole_plandatum,
                         trclass: "invoerinsp",
                         timeField: true,
                         timeStep: 60,
                         startTime: 0,
                         endTime: 23.75,
                         readonly: true,
                         suppressEmpty: true
                       });
          var maxDate = new Date();
          if (insClose || ((insEdit || insFinish) && typeof inspect_data.deelsrtcontrole_datum != null))
          {
            var dmj_eenheid;
            // Voor gereed te gemelden(5) en af te ronden(6) inspecties gelden een ander minDate en maxDate.
            if (dsc_is_afgemeld)  // Er geldt dan (insEdit of insFinish) en !insClose. Als insClose dan is de status < 5.
            { // Inspectie is Gereed gemeld(5) of Afgerond(6). Datum mag ik nog aanpassen.
              // Wijzigen in status Afgerond(6) mag alleen als je INSMSU rechten (canMsuEdit) hebt.
              // Niet multi en ins_deelsrtcontrole_key is bekend.

              // Vooralsnog kan inspectiedatum niet aangepast worden als de eenheid uren(0) is (readonly).
              sql = "SELECT MAX(idsc.ins_deelsrtcontrole_datum) lastinspectdatum"
                  + "     , MAX(idsc.ins_deelsrtcontrole_datum + 1) dag_na_lastinspectdatum"
                  + "     , CASE"
                  + "       WHEN COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, isc.ins_srtcontrole_eenheid) != 0" // Geen tijd eenheid maar dag, maand of jaar.
                  + "       THEN 1" // Dag, maand of jaar.
                  + "       ELSE 0" // Tijd.
                  + "       END dmj_eenheid"
                  + "     , isc.ins_srtcontrole_mode"
                  + "  FROM ins_deelsrtcontrole idsc"
                  + "     , ins_srtcontrole isc"
                  + "     , ins_srtcontroledl_xcp xcp"
                  + " WHERE idsc.ins_srtcontrole_key = isc.ins_srtcontrole_key"
                  + "   AND idsc.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
                  + "   AND idsc.ins_deel_key = xcp.ins_deel_key(+)"
                  + "   AND COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode) > 0"
                  + "   AND idsc.ins_deel_key IN (" + ingesloten[0] + ")"
                  + "   AND idsc.ins_srtcontrole_key IN (" + ingeslotensc[0] + ")"
                  + "   AND ins_deelsrtcontrole_key < " + ingeslotendsc[0]
                  + "   AND idsc.ins_scenario_key = 1"
                  + "   AND xcp.ins_scenario_key(+) = 1"
                  + " GROUP BY isc.ins_srtcontrole_mode"
                  + "        , xcp.ins_srtcontroledl_xcp_eenheid"
                  + "        , isc.ins_srtcontrole_eenheid";
              var oRs = Oracle.Execute(sql);
              if (!oRs.eof && oRs("lastinspectdatum").Value != null)
              {
                lastinspectdatum = new Date(oRs("lastinspectdatum").Value); // Kan uiterlijk vandaag zijn.
                dag_na_lastinspectdatum = new Date(oRs("dag_na_lastinspectdatum").Value); // Kan uiterlijk morgen zijn.
                dmj_eenheid = oRs("dmj_eenheid").Value;
                mode = oRs("ins_srtcontrole_mode").Value;
                if (mode == 0)
                { // Momentmode.
                  sql = "SELECT COUNT(*) aantal"
                      + "  FROM ins_deelsrtcontrole idsc"
                      + " WHERE ins_deel_key = " + ingesloten[0]
                      + "   AND ins_srtcontrole_key = " + ingeslotensc[0]
                      + "   AND ins_scenario_key = 1"
                      + "   AND TRUNC(ins_deelsrtcontrole_datum) = TRUNC((SELECT ins_deelsrtcontrole_datum"
                      + "                                                   FROM ins_deelsrtcontrole idsc1"
                      + "                                                  WHERE idsc1.ins_deelsrtcontrole_key = " + ingeslotendsc[0] + "))";
                  oRs2 = Oracle.Execute(sql);
                  var same_execution_date = oRs2("aantal").Value;
                  oRs2.Close();
                  minDate = dmj_eenheid == 1 && same_execution_date == 1? new Date(dag_na_lastinspectdatum.midnight()) : lastinspectdatum;
                }
                else
                  // Intervalmode.
                  minDate = lastinspectdatum;
              }
              else
                minDate = aanmaakdatum;
              oRs.Close();

              var take_sysdate = false;
              // Vooralsnog kan inspectiedatum niet aangepast worden als de eenheid uren(0) is (readonly).
              sql = "SELECT MIN(COALESCE(idsc.ins_deelsrtcontrole_datum, ins_deelsrtcontrole_plandatum)) firstinspectdatum"
                  + "     , MIN(COALESCE(idsc.ins_deelsrtcontrole_datum, ins_deelsrtcontrole_plandatum) - 1) dag_voor_firstinspectdatum"
                  + "     , CASE"
                  + "       WHEN COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, isc.ins_srtcontrole_eenheid) != 0" // Geen tijd eenheid maar dag, maand of jaar.
                  + "       THEN 1" // Dag, maand of jaar.
                  + "       ELSE 0" // Tijd.
                  + "       END dmj_eenheid"
                  + "     , isc.ins_srtcontrole_mode"
                  + "  FROM ins_deelsrtcontrole idsc"
                  + "     , ins_srtcontrole isc"
                  + "     , ins_srtcontroledl_xcp xcp"
                  + " WHERE idsc.ins_srtcontrole_key = isc.ins_srtcontrole_key"
                  + "   AND idsc.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
                  + "   AND idsc.ins_deel_key = xcp.ins_deel_key(+)"
                  + "   AND COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode) > 0"
                  + "   AND idsc.ins_deel_key IN (" + ingesloten[0] + ")"
                  + "   AND idsc.ins_srtcontrole_key IN (" + ingeslotensc[0] + ")"
                  + "   AND ins_deelsrtcontrole_key > " + ingeslotendsc[0]
                  + "   AND idsc.ins_scenario_key = 1"
                  + "   AND xcp.ins_scenario_key(+) = 1"
                  + "   AND idsc.ins_deelsrtcontrole_status >= 5"
                  + " GROUP BY isc.ins_srtcontrole_mode"
                  + "        , xcp.ins_srtcontroledl_xcp_eenheid"
                  + "        , isc.ins_srtcontrole_eenheid";
              oRs = Oracle.Execute(sql);
              if (!oRs.eof)
              {
                firstinspectdatum = new Date(oRs("firstinspectdatum").Value); // Kan uiterlijk vandaag zijn.
                dag_voor_firstinspectdatum = new Date(oRs("dag_voor_firstinspectdatum").Value); // Kan uiterlijk morgen zijn.
                dmj_eenheid = oRs("dmj_eenheid").Value;
                mode = oRs("ins_srtcontrole_mode").Value;
                maxDate = dmj_eenheid? dag_voor_firstinspectdatum : firstinspectdatum;
                if (mode == 0)
                  // Momentmode.
                  maxDate = dmj_eenheid == 1? new Date(dag_voor_firstinspectdatum.setHours(23,59,59,99)) : firstinspectdatum;
                else
                  // Intervalmode.
                  maxDate = firstinspectdatum;
              }
              else take_sysdate = true; // Voor de maxDate de huidige datum nemen.
              oRs.Close();

%>
              <script type="text/javascript">
                var minDateEdit = new Date(<%=minDate.getTime()%>);
<%              if (take_sysdate)
                { %>
                  var maxDateEdit = -1; // Dan is maxDate de huidige datum new Date().
<%              }
                else
                { %>
                  var maxDateEdit = new Date(<%=maxDate.getTime()%>);
<%              } %>
              </script>
<%
            }

            if (mjob)
            { // Bij MJOB mag de maxDate niet na het freeze jaar liggen. Dit checken.
              var maxFreezeDate = new Date(mjb_freeze_year, 11, 31, 23, 59, 59, 999);
              if (maxDate.getTime() > maxFreezeDate.getTime())
                maxDate = maxFreezeDate;
            }

            FCLTcalendar("deelsrtcontrole_datum",
                         { label: L("lcl_ins_controle_datum"),
                           datum: inspect_data.deelsrtcontrole_datum? inspect_data.deelsrtcontrole_datum : (maxDate < new Date()? maxDate : new Date()),
                           minDate: minDate,
                           maxDate: maxDate,
                           required: true,
                           trclass: "invoerinsp",
                           timeField: true,
                           timeStep: 60,
                           startTime: 0,
                           endTime: 23.75,
                           onChangeDate: "onChangeDeelsrtcdatum(1)",
                           onChangeTime: "onChangeDeelsrtcdatum(2)",
                           readonly: ((dsc_is_afgemeld && dmj_eenheid == 0) ||  // Als eenheid in uren(0) is, dan mag de uitvoerdatum/inspectiedatum niet aangepast worden als inspectie is gereed gemeld(5) of afgerond(6).
                                      ((insEdit || insFinish) && ins_deelsrtcontrole_status == 6 && !canMsuEdit) ||
                                      (inspect_data.deelsrtcontrole_datum != null && inspect_data.deelsrtcontrole_datum < aanmaakdatum)
                                     )
                         });
          }
          sql = "SELECT ins_controlemode_key"
              + "     , " + lcl.xsqla('ins_controlemode_oms', 'ins_controlemode_key')
              + "  FROM ins_controlemode"
              + "  WHERE ins_srtcontrole_type = " + sctype
              + "  ORDER BY 2";

          // Methode is voor de status Afgemeld(5) en Historie/Verwerkt(6) altijd ingevuld.
          FCLTselector("sel_controlemode",
                       sql,
                       { label: L("lcl_ins_controle_mode"),
                         initKey: inspect_data.controlemode_key, // Als de controle mode bij multi verschillend is, dan is deze waarde -1.
                         emptyOption: L("lcl_select_controlemode"),
                         required: true,
                         readonly: ((insEdit || insFinish) && !canMsuEdit) || insstatus >= 5 // Na het afronden/voltooien mag de taakafhandeling niet meer aangepast worden (FCLT#79491).
                       });
        }
        else if (catclose)
        {
          FCLTcalendar("deelsrtcontrole_datum",
                       { label: L("lcl_ins_controle_datum"),
                         datum: new Date(),
                         minDate: new Date(),
                         maxDate: maxDate,
                         required: true,
                         trclass: "invoerinsp",
                         timeField: true,
                         timeStep: 60,
                         startTime: 0,
                         endTime: 23.75,
                         //onChangeDate: "onChangeDeelsrtcdatum(1)",
                         //onChangeTime: "onChangeDeelsrtcdatum(2)",
                         readonly: true
                       });
%>        <input type="hidden" id="deelsrtcontrole_datum" name="deelsrtcontrole_datum" value="<%=new Date().getTime()%>">
          <tr><td><%=L("lcl_ins_controle_mode")%>:</td></tr>
<%
          for (var i = 1; i <= 3; i++)
          {
            if (sumtyp[i] > 0)
            {
              var typeoms = "";
              switch (i)
              {
                case 1: {
                          typeoms = L("lcl_ins_srtcontrole_insp");
                          break;
                        }
                case 2: {
                          typeoms = L("lcl_ins_srtcontrole_repl");
                          break;
                        }
                case 3: {
                          typeoms = L("lcl_ins_srtcontrole_cert");
                          break;
                        }
              }

              sql = "SELECT ins_controlemode_key"
                  + "     , " + lcl.xsqla('ins_controlemode_oms', 'ins_controlemode_key')
                  + "  FROM ins_controlemode"
                  + "  WHERE ins_srtcontrole_type = " + i
                  + "  ORDER BY 2";

              // Methode is voor de status Afgemeld(5) en Historie/Verwerkt(6) altijd ingevuld.
              FCLTselector("sel_controlemode" + i,
                           sql,
                           { label: "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" + typeoms + " (" + L("lcl_count") + ":" + sumtyp[i] + ")",
                             initKey: -1,
                             emptyOption: L("lcl_select_controlemode"),
                             required: true
                           });
            }
          }
        }

%>
        <script type="text/javascript">
          var dsc_is_afgemeld = <%=dsc_is_afgemeld? 1 : 0%> == 1;
        </script>
<%

        insReq = (insClose ? 1 : 0) + (insFinish ? 2 : 0); // Welke opmerking_verplicht-bit is gezet: 0=geen, 1=gereedmelden, 2=voltooien.
        RWTEXTAREATR("opmerk",
                     "fldtxt" + ((opmerking_verplicht & insReq) > 0 ? " required": ""),
                     L("lcl_remark"),
                     (!catclose? inspect_data.deelsrtcontrole_opmerking : ""),
                     { html: "rows='8'",
                       trclass: "invoerinsp",
                       maxlength: 4000
                     }
                    );
      if (!catclose)
      { %>
        <script type="text/javascript">
          var insstatus = <%=insstatus%>;
          //var nextinspectdatum = new Date(< %=nextinspectdatum.getTime()% >);

          // In de interval mode moet de tijd bij de respijtdatum altijd invulbaar zijn.
          // In de moment mode moet de tijd bij de plandatum alleen invulbaar zijn als de eenheid in uren(0) is.
          eenheid = <%=eenheid%>;
          var scmode = <%=scmode%>;
          if (scmode == 0 && eenheid != 0)
            $("#time_from_plandatum").hide().next().hide();
        </script>
<%    }
      BLOCK_END();
      if (!catclose)
      {
          generateFlexKenmerkBlock({deelsrtcontrole_key: (!multi && ingeslotendsc[0] > 0? ingeslotendsc[0] : -1),
                                    srtcontrole_key: ingeslotensc[0],
                                    submit: submit,
                                    close: close,
                                    finish: finish,
                                    ins_status: insstatus
                                  });
      }

      IFACE.FORM_END();
%>
    </form>
    <% SUBFRAME_END(); %>
  </body>
</html>
<% ASPPAGE_END(); %>
