<% /*
     $Revision$
     $Id$

    File:               INS/ins_list.inc
    Description:        Show an overview of objects in list-form.
                        which meets with the given requirements
                        User can select on or more lines and edit/delete them
                        FE ->verbruiksregistratie
                        BO ->object registratie
                        FO ->uitleenmodule

    Parameters:
        urole               user role (fe, fo, bo, mi)
        outputmode          behave in an output mode, print to 0 = screen, 1 = printer, 2 = excel, etc.
        showall             show all objects which meets with the given requirements
        inspect             Toon ook inspectie kolommen (implies actief=1)
        inspClosed          search for objects inspections wich are verwerkt
        inspDone            search for objects inspections wich are done
        inspBusy            search for objects inspections wich are in progress
        inspSoon            search for objects inspections wich are soon
        inspClosed, inspDone, inspBusy, inspSoon: de vinkjes
        inspsoonfrom        search for objects with inspections between inspsoonfrom and inspsoonto
        inspsoonto          search for objects with inspections between inspsoonfrom and inspsoonto
        donedatefrom        search for objects with inspections between donedatefrom and donedateto
        donedateto          search for objects with inspections between donedatefrom and donedateto
        reg_key_arr         search for objects with the given regio keys
        dist_key_ar         search for objects with the given district keys
        loc_key_arr         search for objects with the given location keys
        bld_key_arr         search for objects with the given building keys
        flr_key_arr         search for objects with the given floor keys
        room_key_arr        search for objects with the given room keys
        wpl_key             search for objects with the given workplace key
        deel                search for objects with the given identification
        disc_key_arr        search for objects with the given discipline keys
        insgroup_key_arr    search for objects with the given groep keys (srtgroup key)
        objsrt_key_arr      search for objects with the given objectsoort (srtdeel key) as intArray
        objsrt_oms          search for srtobjects with the given code or description
        ctrdisc_key_arr     search for ctrdiscipliines with the given srtdisc_keys
        srtcontrole_key_arr search for tasks with the given task keys,
        groep               search for group with the given code or description
        dep_key             search for objects with the given department key
        persoon_key         search for objects with the given persoon key
        verantw_key         search for objects with the given responsible building person key
        beh_key             search for objects manaed by the given beh (persoon) key
        cpersoon_key        search for objects with the given contactpersoon key
        cnt_bedrijf_key     search for objects waar het desbetreffende bedrijf contractueel onderhoud kan doen
        ins_key_arr         search for objects with the given ins key array
        parent_key          search for subobjects of the given ins parent_key
        koppel_key          search for related objects of the given koppel_key
        terr_key            search for objects with the given terrein key
        comp_key            search for objects with the given companie key
        checkout            Call during check-out of visitor
        insObjIncl          search also for objects wich is a part from another object
        insPhotoIncl        show picture of object when available
        insLentOut          search for objects wich are lent out
        insAvail            search for objects wich are available
        lentoutAction       search for last lent in/out
        lentoutDateFrom     search for objects lent in/out period
        lentoutDateTo       search for objects lent in/out period
        insSuccessY         search for inspections which are a success
        insSuccessN         search for inspections which are not active
        fgraph              search for objects for a Graphics search, flr_key is given
        withflex            display a flex column if there are any
    Context:                - INS/ins_search.asp (Search action from bes_search.asp form)
                            - FGraph (<cust>_Report.asp)
                            - Self (when printing)
    Note:                   For FGraph-selectable objects 'owner' selection is never applicable
                            as the objects will be place-bound. Place info may be restricted to room/wp details.
                            Als parent_key of koppel_key, dan worden geen bulkacties getoond (tiny)

*/ %>

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

<%
FCLTHeader.Requires({ plugins:["jQuery", "suggest"],
                      js: ["jquery-ui.js", "../ins/ins_list.js"]
                    });
function ins_list (pautfunction, params)
{
  var buttons = [];
  // De functie checkAutorisation(autfunction) geeft een Response.End indien er geen autorisatie voor autfunction wordt gevonden
  var authparams = user.checkAutorisation(pautfunction, false, params.disc_key_arr.length == 1? params.disc_key_arr[0] : null);
  var authparamsINSMAN = user.checkAutorisation("WEB_INSMAN", true);
  var hasWriteINSMAN = (authparamsINSMAN && authparamsINSMAN.ALGwritelevel < 9 && authparamsINSMAN.PRSwritelevel < 9)

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

  var canAdd = (authparams.PRSwritelevel < 9 && urole != "fo");
  var canImport = (user.checkAutorisation("WEB_IMPORT", true) != null);

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

  var reg_key_arr         = params.reg_key_arr || [];
  var dist_key_arr        = params.dist_key_arr || [];
  var loc_key_arr         = params.loc_key_arr || [];
  var room_key_arr        = params.room_key_arr || [];
  var disc_key_arr        = params.disc_key_arr || [];
  var insgroup_key_arr    = params.insgroup_key_arr || [];
  var objsrt_key_arr      = params.objsrt_key_arr || [];
  var ctrdisc_key_arr     = params.ctrdisc_key_arr;
  var srtcontrole_key_arr = params.srtcontrole_key_arr;
  var dep_key             = params.dep_key;
  var persoon_key         = params.persoon_key;
  var cpersoon_key        = params.cpersoon_key;
  var fgraph              = params.fgraph;
  var parent_key          = params.parent_key;
  var koppel_key          = params.koppel_key;
  var embedded            = params.embedded;
  var tiny                = params.tiny || parent_key || koppel_key;
  var groepering          = params.groepering || -1;
  var inspect             = params.inspect;
  var checkout            = params.checkout;
  var insObjIncl          = params.insObjIncl;
  var inacObjIncl         = params.inacObjIncl;
  var insPhotoIncl        = params.insPhotoIncl;
  var insSensOnly         = params.insSensOnly;
  var inspDone            = params.inspDone;
  var withflex            = params.withflex;
  var lentoutAction       = params.lentoutAction;

  var fitness_score1_from      = params.fitness_score1_from;
  var fitness_score1_through   = params.fitness_score1_through;
  var gwfitness_score1_from    = params.gwfitness_score1_from;
  var gwfitness_score1_through = params.gwfitness_score1_through;
  var priority_score2_from     = params.priority_score2_from;
  var priority_score2_through  = params.priority_score2_through;

  //var filterParams = params;
  var filterParams = JSON.parse(JSON.stringify(params)); // Clone het parameter object.
  filterParams.disc_key = disc_key_arr;
  filterParams.disc_key_arr = null;
  filterParams.insgroup_key = insgroup_key_arr;
  filterParams.insgroup_key_arr = null;
%>

  <html>
    <head>
<%
      FCLTHeader.Generate({ outputmode: outputmode });

      var ins_name = "";
      var ins_srtname = "";
      var srtdeel_binding = 0;
      if (parent_key)
      {
        var sql = "SELECT ins_deel_omschrijving"
                + "     , ins_discipline_key"
                + "     , " + lcl.xsqla('sd.ins_srtdeel_omschrijving', 'sd.ins_srtdeel_key')
                + "     , ins_srtdeel_binding"
                + "  FROM ins_deel d"
                + "     , ins_srtdeel sd "
                + " WHERE sd.ins_srtdeel_key = d.ins_srtdeel_key"
                + "   AND ins_deel_key = " + parent_key;
        var oRs = Oracle.Execute(sql);
        ins_name = oRs("ins_deel_omschrijving").value;
        ins_srtname = oRs("ins_srtdeel_omschrijving").value;
        srtdeel_binding= oRs("ins_srtdeel_binding").Value;
      }
%>
    <script type="text/javascript">
<%    if (insPhotoIncl) { %>
        $(function() {
          $(".toggle-objphoto").toggle($("td img.objphoto:visible").length > 0);
        });
<%    } %>
      var urole = "<%=urole%>";
      var eigen = "<%=params.eigen||0%>";
      function ins_deelkoppeling()
      {
        FcltMgr.openModalDetail("../ins/ins_deelkoppeling.asp?urole=<%=urole%>&ins_keys=<%=koppel_key%>",
                                L("lcl_ins_koppelobjects"),
                                { callback: FcltMgr.reload });
      }

      function ins_deelkoppeling_diagram()
      {
        FcltMgr.openDetail("appl/ins/ins_deelkoppelingen.asp?urole=<%=urole%>&ins_key=<%=koppel_key%>", L("lcl_ins_koppelobjects"));
      }

      function ins_onderdelen()
      {
        FcltMgr.openModalDetail("../ins/ins_onderdelen.asp?urole=<%=urole%>&ins_key=<%=parent_key%>",
                                "<%=safe.jsstring(L("lcl_ins_parentobjects") + " " + ins_srtname + " " + ins_name)%>",
                                { callback: FcltMgr.reload });
      }
     </script>
    </head>
    <body id="listbody">

<%
      if (frontend)
      { %>
        <form action="ins_search_list.asp" method="get" id="inslist" name="inslist">
          <input type="hidden" name="urole" value="<%=urole%>">
          <% /* filter velden voor frontend. Nodig voor reload na oplaan nieuw waarden. */ %>
          <input type="hidden" name="locatiekey" value="<%=loc_key_arr.length? loc_key_arr.join(",") : ""%>">
          <input type="hidden" name="srtdeel" value="<%=objsrt_key_arr.length? objsrt_key_arr.join(",") : ""%>">
<%
          var sql_loc = "";
          var sql_obj_sort = "";

          if (loc_key_arr.length)
          {
            sql_loc = " AND l.alg_locatie_key IN (" + loc_key_arr.join(",") + ")";
          }
          else if (dist_key_arr.length)
          {
            sql_loc = " AND l.alg_district_key IN (" + dist_key_arr.join(",") + ")";
          }
          else if (reg_key_arr.length)
          {
            sql_loc = " AND di.alg_regio_key IN (" + reg_key_arr.join(",") + ")";
          }
          else
          {
            // Note: we do not support alg-scope  per discipline (yet)
            sql_loc = (authparams.ALGreadlevel >= 0
                      ? " AND d.ins_alg_locatie_key IN"
                        + " (SELECT alg_locatie_key FROM fac_v_my_locations"
                        + " WHERE prs_perslid_key = " + user_key
                        + " AND niveau = " + authparams.ALGreadlevel + ")"
                      : "");
          }

          if (objsrt_key_arr.length)
          {
            sql_obj_sort = " AND sk.INS_SRTDEEL_KEY IN (" + objsrt_key_arr.join(",") + ")";
          }
          else
          {
            sql_obj_sort = " AND sk.ins_discipline_key IN (SELECT gb.ins_discipline_key"
                         + "   FROM fac_v_webgebruiker gb, fac_functie f"
                         + "  WHERE prs_perslid_key = " + user_key
                         + "    AND fac_functie_code = " + safe.quoted_sql(pautfunction)
                         + "    AND f.fac_functie_key = gb.fac_functie_key"
                         + "    and gb.fac_gebruiker_alg_level_read < 9)";
          }

          sql = " SELECT "+lcl.xsqla('sd.ins_srtdeel_omschrijving', 'sd.ins_srtdeel_key')
              + ", d.ins_deel_omschrijving || ' (' || d.ins_deel_key || ')' object_omschrijving" // object omschrijving
              + ", d.ins_deel_opmerking"
              + ", d.ins_deel_flag"
              + ", (SELECT akd.ins_kenmerkdeel_aanmaak"
                + " FROM ins_v_aanwezigkenmerkdeel akd"
                + " WHERE akd.ins_deel_key = d.ins_deel_key"
                + " AND akd.ins_kenmerk_key = sk.ins_kenmerk_key) last_change_date" // vorige invoerdatum
              + ", (SELECT akd.ins_kenmerkdeel_waarde"
                + " FROM ins_v_aanwezigkenmerkdeel akd"
                + " WHERE akd.ins_deel_key = d.ins_deel_key"
                + " AND akd.ins_kenmerk_key = sk.ins_kenmerk_key) last_value"       // huidige (laatste) waarde
              + ", sk.ins_srtdeel_key"                                              // objectsoort deel key
              + ", d.ins_deel_key"                                                  // onderdeel key
              + ", sk.ins_kenmerk_key"                                              // objectkenmerk key
              + ", d.ins_alg_ruimte_key"                                            // alg ruimte key
              + ", sk.ins_srtkenmerk_key"                                           // bibliotheek kenmerk key
              + ", sk.ins_srtkenmerk_kenmerktype"                                   // bibliotheek type
              + ", sk.ins_srtkenmerk_lengte"                                        // bibliotheek lengte
              + ", sk.ins_srtkenmerk_nmin"                                          // bibliotheek maximum waarde
              + ", sk.ins_srtkenmerk_nmax"                                          // bibliotheek minimum waarde
              + ", l.alg_locatie_omschrijving"                                      // locatie omschrijving
              + ", "+lcl.xsqla('sd.ins_srtdeel_eenheid', 'sd.ins_srtdeel_key')      // eenheid van het verbruik
              + ", sk.ins_kenmerk_volgnummer"                                       // kenmerk volgnummer
              + ", COALESCE("
                + " (SELECT akd.ins_kenmerkdeel_key"
                + " FROM ins_v_aanwezigkenmerkdeel akd"
                + " WHERE akd.ins_deel_key = d.ins_deel_key"
                + " AND akd.ins_kenmerk_key = sk.ins_kenmerk_key)"
                + ", -1) ins_kenmerkdeel_key"                                       // ins_kenmerkdeel_key
              + ", rd.res_deel_key"
              + ", rd.res_deel_opmerking"
              + ", rd.res_deel_count"
              + " FROM ins_v_srtdeel_kenmerk sk"
              + ", ins_v_aanwezigdeel d"
              + ", ins_srtdeel sd"
              + ", alg_locatie l"
              + (!loc_key_arr.length && !dist_key_arr.length && reg_key_arr.length
                ? ", alg_district di"
                : "")
              + ", " + ins.getresdeel_sql() + " rd"
              + " WHERE sk.ins_srtdeel_key = sd.ins_srtdeel_key"
              + " AND d.ins_srtdeel_key = sd.ins_srtdeel_key"
              + " AND d.ins_alg_locatie_key = l.alg_locatie_key"
              + (!loc_key_arr.length && !dist_key_arr.length && reg_key_arr.length
                ? " AND l.alg_district_key = di.alg_district_key"
                : "")
              + " AND d.ins_deel_key =  rd.res_ins_deel_key(+)"
              + " AND sd.ins_srtgroep_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + ")"
              + sql_loc
              + sql_obj_sort
              + " AND sk.ins_kenmerk_meetwaarde = 1"
              + " AND sk.ins_srtkenmerk_kenmerktype = 'N'"
              + " AND (d.ins_deel_vervaldatum IS NULL OR d.ins_deel_vervaldatum > TRUNC(SYSDATE))"
              + " ORDER BY alg_locatie_omschrijving"            // overweeg uppers?
              + ", "+lcl.xsql('sd.ins_srtdeel_omschrijving', 'sd.ins_srtdeel_key')
              + ", d.ins_deel_omschrijving || ' (' || d.ins_deel_key || ')'"
              + ", "+ lcl.xsql('sd.ins_srtdeel_eenheid','sd.ins_srtdeel_key');

          /******************************************
          * Callback functies ResultsetTable for FE *
          *******************************************/

          function fnrowDataFE(oRs)
          {
            var insDeelKey = oRs("ins_deel_key").value;
            var insDeelDescr = oRs("object_omschrijving").value;
            var insKenmerkDeelKey = oRs("ins_kenmerkdeel_key").value;
            var insKenmerkKey = oRs("ins_kenmerk_key").value;

            var data = {insDeelKey:insDeelKey, insDeelDescr:insDeelDescr, insKenmerkDeelKey:insKenmerkDeelKey, insKenmerkKey:insKenmerkKey};
            return JSON.stringify(data);
          }

          function fnInput(oRs)
          { // input nieuwe waarde d.m.v. input box
            newInput = "<NOBR>"

            var write_ok
            if (authparams.ALGwritelevel >= 0)
            {
              sql2 = "SELECT alg_ruimte_key FROM fac_v_my_rooms"
                   + " WHERE prs_perslid_key = " + user_key
                   + " AND niveau = " + authparams.ALGwritelevel
                   + " AND alg_ruimte_key = " + oRs("ins_alg_ruimte_key").value;
              oRs2 = Oracle.Execute(sql2);
              if (!oRs2.eof)
                write_ok = true;
              else
                write_ok = false;
            }
            else
            {
              write_ok = true;
            }

            newInput += '<input type="text" maxlength="10" style="text-align:right"'
                      + ' onBlur="checkInput(event);" onKeyPress="return checkEnter(event);"'
                      + ' id="cnt' + rst.rowNum + '" name="cnt' + rst.rowNum + '" class="fldshort" value=""'
                      + ' value1="' + oRs("ins_srtkenmerk_kenmerktype").value + '"'
                      + ' value2="' + oRs("ins_srtkenmerk_lengte").value + '"'
                      + ' value3="' + oRs("ins_srtkenmerk_nmin").value + '"'
                      + ' value4="' + oRs("ins_srtkenmerk_nmax").value + '"'
                      + (!write_ok || oRs("ins_srtkenmerk_kenmerktype").value != 'N'
                        ? ' readonly'
                        : '')
                      + '>'
                      + '<input type="hidden" id="last_val' + rst.rowNum + '" name="last_val' + rst.rowNum + '" value="' + (oRs("last_value").value? oRs("last_value").value : 0) + '">'
                      + '<input type="hidden" id="deel_key' + rst.rowNum + '" name="deel_key' + rst.rowNum + '" value="' + oRs("ins_deel_key").value + '">'
                      + '<input type="hidden" id="kenmerk_key' + rst.rowNum + '" name="kenmerk_key' + rst.rowNum + '" value="' + oRs("ins_kenmerk_key").value + '">';

            return newInput;
          }

          /***********************************************
           * End callback functies ResultsetTable for FE *
           ***********************************************/
          var rst = new ResultsetTable({ keyColumn: "ins_deel_key",
                                         sql: sql,
                                         ID: "instable",
                                         tabs_code: "ins_list-" + urole + "-ob",
                                         //rowClass: fnrowClass,
                                         rowData: fnrowDataFE,
                                         filterParams: filterParams,
                                         outputmode: outputmode,
                                         title: L("lcl_ins_objects"),
                                         showAll: showall
                                       });

          rst.addColumn(new Column({caption: L("lcl_location"), content: "alg_locatie_omschrijving"}));
          rst.addColumn(new Column({caption: L("lcl_obj_sort"), content: "ins_srtdeel_omschrijving"}));
          rst.addColumn(new Column({caption: L("lcl_obj_inf_name"), content: "object_omschrijving"}));
          rst.addColumn(new Column({caption: L("lcl_last_date"), content: "last_change_date", datatype: "date"}));
          rst.addColumn(new Column({caption: L("lcl_last_value"), content: "last_value"}));
          rst.addColumn(new Column({caption: L("lcl_obj_cons_value"), content: fnInput, colName: "fnInput"}));
          rst.addColumn(new Column({caption: L("lcl_obj_unit"), content: "ins_srtdeel_eenheid"}));

          // Acties
          if (!embedded) {
              rst.addAction({action: "insHistory", caption: L("lcl_history")});
              rst.addAction({action: "insSave", caption: L("lcl_save_value"), multi: true, multiOnce: true});
          }
          var count = rst.processResultset();
%>
          <input type='hidden' id='count' name='count' value='<%=count%>'>
        </form>
<%
      }
      else
      { // !frontend
        if (!excel)
        {
%>        <script type="text/javascript">

            function openFG(evt, insKey, room, INS_ALG_RUIMTE_TYPE, pxyknown)
            {
              FcltMgr.stopPropagation(evt);
<%            if (S("ins_fg_remote_maps") != "")
              { %>
                if (pxyknown == 1)
                {
                  FcltMgr.windowopen('../cad/ShowGoogleMap.asp?obj_key=' + insKey, 'FGShow',
                                     "width=640, height=480, directories=no, location=no, menubar=no,"
                                   + "resizable=yes, status=no, titlebar=yes, toolbar=no");
                  return;
                }
<%            } %>
              if (INS_ALG_RUIMTE_TYPE == 'T')
              {
                var url = '../cad/ShowTerrain.asp?tKey=' + (room||-1) + '&obj_key=' + insKey;
                FcltMgr.openModalDetail(url);
              }
              else
              {
                var url = '../cad/ShowRoom.asp?rKey=' + (room||-1) + '&ins_key='+insKey;
                FcltMgr.openModalDetail(url);
              }
            }
          </script>
<%
        } // !excel

        if (withflex && !excel && !print)
        {
          var insFlexParams = ins.ins_deel_flex_params(1, {inspect: inspect, ins_deelsrtcontrole: "ispn"}); // 1=Objectbeheer overzicht.
          params.insFlexParams = insFlexParams;
        }
%>
<%      // =======================================================
        // All header information been emitted. Now start building
        // the SQL-queries to do actual data retrieval
        // =======================================================

        var ErisUitleenbaar = false;
        var ErisReserveerbaar = false;

        var hasDrawings = false;
        var hasAantal = false;
        var anyobjman = false

        var sqlu ="SELECT COUNT (*) FROM ins_srtdeel WHERE ins_srtdeel_uitleenbaar = 1 AND ins_srtdeel_verwijder IS NULL";
        var oRsu = Oracle.Execute(sqlu);
        ErisUitleenbaar = oRsu(0).value >0
        oRsu.close();
        sqlu ="SELECT COUNT (*) FROM res_deel WHERE res_deel_verwijder IS NULL";
        oRsu = Oracle.Execute(sqlu);
        ErisReserveerbaar = oRsu(0).value >0
        oRsu.close();

        sqlu = "SELECT 1"
             + "  FROM cad_tekening"
             + " WHERE cad_tekening_verwijder IS NULL AND ROWNUM = 1";
        oRsu = Oracle.Execute(sqlu);
        hasDrawings = !oRsu.eof;
        oRsu.close();

        // als het altijd 1 is wil ik geen aantal-kolom
        sqlu = "SELECT 1"
             + "  FROM ins_deel"
             + " WHERE ins_deel_verwijder IS NULL AND COALESCE(ins_deel_aantal, 1) <> 1 AND ROWNUM = 1";
        oRsu = Oracle.Execute(sqlu);
        hasAantal = !oRsu.eof;
        oRsu.close();

        sqlu ="SELECT COUNT (*) FROM ins_deel WHERE prs_perslid_key_beh IS NOT NULL AND ins_deel_verwijder IS NULL AND ROWNUM = 1";
        oRsu = Oracle.Execute(sqlu);
        anyobjman = oRsu(0).value >0
        oRsu.close();

        // Start building the query to fetch all objects satisfying
        var sql = ins.getobjectinspect_sql(pautfunction, params);
        // ========== now 'sql' holds the main SQL-statement to fetch all object info

        ///////////////////////////////////////////////////////////
        //
        //      Now let's present the results:
        //
        ///////////////////////////////////////////////////////////

        /*************************************************
         * Callback functies ResultsetTable for FO en BO *
         *************************************************/

        function fnInlinePhoto(oRs)
        {
          if (oRs("ins_deel_image").Value === null) {
            return "";
          }
          var this_photoinfo = ins.photoinfo(oRs("ins_deel_key").Value, oRs("ins_deel_image").Value);
          if (outputmode == 3 || !this_photoinfo.photopaththumb) // XML
            return this_photoinfo.photopaththumb;

          var html = (this_photoinfo.isDefault ? "<img/>" : ("<img loading='lazy' class='objphoto' alt='"+L("lcl_image")+"' src='"+safe.htmlattr(this_photoinfo.photopaththumb) +"'>"));
          return html;
        }

        function fnrowData(oRs)
        {
          var insKey = oRs("ins_deel_key").Value;
          var insTypeKey = oRs("ins_srtdeel_key").Value;
          var insAvailable = oRs("ins_alg_ruimte_key_org").Value == null? 1 : 0;
          var insSrtControleKey = inspect? oRs("ins_srtcontrole_key").Value : -2;

          // Als de status Verwerkt(6) is dan kan/moet er weer een nieuw inspectie gestart worden. Dan geen ins_deelsrtcontrole_key meegegeven (-2).
          var istatus = inspect? oRs("ins_deelsrtcontrole_status").Value : -1;
          var insDeelSrtContrKey = inspect && oRs("ins_deelsrtcontrole_key").Value != null && istatus != 6? oRs("ins_deelsrtcontrole_key").Value : -2;

          var data = {insKey: insKey, insTypeKey: insTypeKey, insAvailable: insAvailable,
                      insSrtControleKey: insSrtControleKey, insDeelSrtContrKey: insDeelSrtContrKey,
                      ins_status: istatus};
          return JSON.stringify(data);
        }

        function fnrowActionEnabler(oRs)
        {
          var eLendOut = false;
          var eReceive = false;
          var eAdapt = false;
          if (fronto)
          {
            // Button onafhankelijk van writefof rechten altijd tonen
            // Autorisatiefunctie "func_enabled_deel" aanroepen voor elk object kost te veel tijd bij het tonen van het overzicht.
            // Controle vindt wel plaats bij het uitgeven en innemen van de objecten.
            eLendOut = oRs("ins_alg_ruimte_key_org").value == null;
            eReceive = !eLendOut;
            eAdapt = eReceive && (oRs("bewerkbaar").Value == 1);
          }
          var eDelete = false;
          var eEdit = true; // Indien enigste actie dan wordt de actie niet getoond en is het de default actie op de hele regel
          var eDetails = true; // Ik zie alleen objecten waar ik read rechten (3d) op heb. Dan mag ik ze ook verder inzien.
          var eShowInsp = false;
          var ePlan = false;
          var ePlanMulti = false;
          var eStart = false;
          var eClose = false;
          var eFinish = false;
          if (inspect && !inspDone)
          {
            // Als object is vervallen dan kun je niet meer inspecteren en uitstellen.
            var this_ins = ins.func_enabled_deel(oRs("ins_deel_key").Value,
                                                 {srtcont_key: oRs("ins_srtcontrole_key").Value,
                                                  deelsrtcont_key: oRs("ins_deelsrtcontrole_key").Value
                                                 });
            var istatus = oRs("ins_deelsrtcontrole_status").Value;

            eShowInsp = this_ins.canInspShow && istatus < 6; // Als de inspectie is afgerond dan kun moet je eerst een nieuwe inspectie starten. Alleen lopende inspecties kun je inkijken.
            ePlan = this_ins.canInspPlan;
            ePlanMulti = this_ins.canInspPlanMulti && !tiny;
            eStart = this_ins.canInspStart;
            eClose = this_ins.canInspClose;
            eFinish = !this_ins.canInspClose && this_ins.canInspFinish; // Als er nog niet gereed gemeld/afgemeld is dan wordt die butten wel getoond.
          }

          var data = {eLendOut: eLendOut, eReceive: eReceive, eAdapt: eAdapt, eDelete: eDelete, eEdit: eEdit,
                      eDetails: eDetails, eShowInsp: eShowInsp, ePlan: ePlan, ePlanMulti: ePlanMulti, eStart: eStart, eClose: eClose, eFinish: eFinish};
          return data;
        }

        function fnrowClass(oRs)
        {
          var lclass = "";
          var istatus = oRs("ins_deelsrtcontrole_status").Value != null? oRs("ins_deelsrtcontrole_status").Value : -1;
          var eenheid = oRs("inspectie_eenheid").Value;
          var mode = oRs("ins_srtcontrole_mode").Value;

          if (inspDone) return lclass;
          var ins_deelsrtcontrole_plandatum = oRs("ins_deelsrtcontrole_plandatum").Value; // Ingeplande datum.
          if (ins_deelsrtcontrole_plandatum == null)
            var dt = new Date(oRs("inspectie_next").Value);
          else
            var dt = new Date(ins_deelsrtcontrole_plandatum);
          dt.setHours(0,0,0,0);     // trunc datum
          var dtsoon = new Date;
          dtsoon.setDate(dtsoon.getDate() + S("ins_inspect_soon_days"));
          dtsoon.setHours(0,0,0,0);     // trunc datum
          var dtlate = new Date(new Date().setHours(0,0,0,0));

          var dt1 = new Date(dt);
          var dt2 = new Date(dt);
          if (eenheid == 4 && mode == 0)
          { // Jaarlijks in een bepaalde maand (moment mode). Inspecteren kan dan van de eerste dag van de maand tot de eerste dag van de volgende maand.
            dt1 = new Date(dt1.setDate(1));                   // Eerste van de maand.
            dt2 = new Date(new Date(dt2.setDate(1)).setMonth(dt2.getMonth() + 1)); // Eerste van de volgende maand.
          }

          if (dt1 >= dtsoon)
            return lclass; // Op tijd, meer dan S("ins_inspect_soon_days") dagen in de toekomst.

          if (dt2 >= dtlate)
            return lclass + " expired1"; // Binnenkort.

          return lclass + " expired2"; // Te laat.
        }

        function fnStatus(oRs)
        {
            var stat = oRs("ins_deelsrtcontrole_status").Value;
            if (!(stat>0) || stat == 6) // De status gaat over de vorige/lopende inspectie. Bij afgerond is dat niet boeiend
                return "";
            return ins.getinspectstatustext(oRs("ins_deelsrtcontrole_status").Value);
        }

        function fnPlace(oRs)
        {
          var place = ""
          if (oRs("ins_alg_ruimte_type_org").value != null)
            place = oRs("uitgegeven_vanuit").Value;
          else
            if (oRs("ins_alg_ruimte_type").value == 'P' || oRs("ins_alg_ruimte_type").value == 'A')
              // Object niet uitgeleend. Uitgeleend aan is eigenlijk de plaats.
              place = oRs("uitgeleend_aan").value;
            else
              place = oRs("plaats").value;

          return safe.html(place);
        }

        function fnLentOutTo(oRs)
        {
          var lentOutTo
          if (oRs("ins_alg_ruimte_type_org").value != null)
            lentOutTo = oRs("uitgeleend_aan").value;
          else
            lentOutTo = "";

          return safe.html(lentOutTo);
        }

        function fnLentOutToEmail(oRs)
        {
          var lentOutToEmail
          if (oRs("ins_alg_ruimte_type_org").value != null)
            lentOutToEmail = oRs("uitgeleend_aan_email").value;
          else
            lentOutToEmail = "";

          return safe.html(lentOutToEmail);
        }

        function fnPosition(oRs)
        {
          var rkey = oRs("alg_ruimte_key").value;
          var rtype = oRs("ins_alg_ruimte_type").value;
          if (rtype == "A" || rtype == "P")
          { // Misschien is het uitgeleend en komt het wel uit een ruimte
            rkey = oRs("ins_alg_ruimte_key_org").value;
            rtype = oRs("ins_alg_ruimte_type_org").value;
          }
          if (rtype == null || rtype == "A" || rtype == "P")
            return ""; // Kunnen we niet tonen

          // TODO: beide kan natuurlijk ook nog/
          var xyavailable = (oRs("ins_deel_x").value != null? 1 : 0);
          var dwgxyavailable = (oRs("ins_deel_dwgx").value != null? 1 : 0);

          if (rtype == "W")
          {
            var sql = "SELECT prs_alg_ruimte_key, prs_werkplek_dwgx FROM prs_werkplek WHERE prs_werkplek_key = " + rkey;
            var oRs2 = Oracle.Execute(sql);
            var rkey = oRs2("prs_alg_ruimte_key").Value;
            var xyavailable = false;
            var dwgxyavailable = (oRs2("prs_werkplek_dwgx").value != null? 1 : 0);
            oRs2.Close();
            rtype = "R";
          }

          var position = "";
          if (xyavailable || dwgxyavailable) {
              if (outputmode == 0) {
                  position = '<span style="font-size: 1.3em" onclick="openFG(event, ' + oRs("ins_deel_key").value + ', ' + rkey + ', \'' + rtype + '\', ' + xyavailable + ');">'
                            + (xyavailable? I("fa-globe") : I("fa-map-pin")) + '</span>';
              } else {
                  position = (xyavailable? "M" : "FG");

              }
          } else {
              if (outputmode == 0) {
                  osition = '<span class="fa-2x" style="font-size: 1.3em" onclick="openFG(event, ' + oRs("ins_deel_key").value + ', ' + rkey + ', \'' + rtype + '\');">'
                           + I("fa-map-marker") + '</span>';
              }
          }

          return position;
        }

        function fnKoppelvan(oRs)
        {
            if (oRs("ins_deelkoppeling_naar_key").Value == koppel_key)
                return safe.html(oRs("ins_deel_omschrijving").Value)
                       + (oRs("ins_deel_opmerking").Value? " (" + safe.html(oRs("ins_deel_opmerking").Value) + ")" : "");
            else
                return "";
        }

        function fnKoppelaan(oRs)
        {
            if (oRs("ins_deelkoppeling_van_key").Value == koppel_key)
                return safe.html(oRs("ins_deel_omschrijving").Value)
                       + (oRs("ins_deel_opmerking").Value? " (" + safe.html(oRs("ins_deel_opmerking").Value) + ")" : "");
            else
                return "";
        }

        function fnKoppel(oRs)  // ongeacht de richting, dat toont fnKoppelrichting
        {
            return safe.html(oRs("ins_deel_omschrijving").Value)
                   + (oRs("ins_deel_opmerking").Value? " (" + safe.html(oRs("ins_deel_opmerking").Value) + ")" : "");
        }
        function fnKoppelrichting(oRs)
        {
            if (oRs("ins_deelkoppeling_van_key").Value == koppel_key)
              return (outputmode == 0 ? I("fa-arrow-right-from-bracket") : L("lcl_ins_deelkoppeling_naar"));
            else
              return (outputmode == 0 ? I("fa-arrow-right-to-bracket fa-rotate-180") : L("lcl_ins_deelkoppeling_van"));
        }

        function fnReserveerbaar(oRs)
        {
            var res = "";
            if ( oRs("res_deel_key").value != null )
            {
                if (outputmode == 0 ) {
                    res= "<span";
                    if (oRs("res_deel_opmerking").value != null )
                        res += " title='" + safe.htmlattr(oRs("res_deel_opmerking").value) + "' ";
                    res += ">"+L("lcl_obj_reserveerbaar")
                          + (oRs("res_deel_count").value > 1?" (" + oRs("res_deel_count").value + "x)":"")
                         + "</span>";
                }
                else
                    res = L("lcl_yes");
            } else {
                res = (outputmode == 0 ? "" : L("lcl_no"));
            }
            return res;
        }

        function fnUitleenbaar(oRs)
        {
            var res = "";
            if ( oRs("ins_srtdeel_uitleenbaar").value==1 ) {
                res = (outputmode == 0 ? L("lcl_obj_uitleensrtdeel") : L("lcl_yes"));
            } else {
                res = (outputmode == 0 ? "" : L("lcl_no"));
            }
            return res;
        }

        function fnInspectie(oRs) // TODO: Of via RowClass
        {
            var vervallen = (oRs("inspectie_eind").Value != null && new Date(oRs("inspectie_eind").Value).getTime() < new Date().midnight());
            if (vervallen) return L("lcl_ins_controle_vervallen");

            var ismjob = oRs("ctr_ismjob").Value == 1;
            var inspectie = (inspDone? oRs("inspectie_date").Value : oRs("inspectie_next").Value);

            if (ismjob)
              dttxt = new Date(inspectie).getFullYear(); // Voor MJOB is alleen het jaar van belang.
            else
            {
              var inspectie_eenheid = oRs("inspectie_eenheid").Value;
              if (inspectie_eenheid == 0)
                var dttxt = toDateTimeString(inspectie);
              else
                var dttxt = toDateString(inspectie);
            }

            return "<span style='white-space: nowrap'>" + dttxt + "</span>";
        }

        function fnPlandatum(oRs)
        {
          var vervallen = (oRs("inspectie_eind").Value != null && new Date(oRs("inspectie_eind").Value).getTime() < new Date().midnight());
          if (vervallen) return L("lcl_ins_controle_vervallen");
          var inspectie_eenheid = oRs("inspectie_eenheid").Value;

          if (inspDone)
            var plandatum = oRs("ins_deelsrtcontrole_datum_org").Value; // Plandatum is dan de orginele datum.
          else
            var plandatum = oRs("ins_deelsrtcontrole_plandatum").Value;

          if (inspectie_eenheid == 0)
            var dttxt = toDateTimeString(plandatum);
          else
            var dttxt = toDateString(plandatum);

          return "<span style='white-space: nowrap'>"+dttxt+"</span>";
        }

        function fnCyclus(oRs)
        {
          var res = "";
          var txt = "";
          var aantal = oRs("periode").Value;
          switch (oRs("inspectie_eenheid").Value) //  0=uurlijks, 1=dagelijks, 2=wekelijk, 3=maandelijk, 4=jaarlijks, null=niet
          {
            case 0:   { txt = L("lcl_ins_controle_period_hour"); break; }
            case 1:   { txt = L("lcl_ins_controle_period_day"); break; }
            case 2:   { txt = L("lcl_ins_controle_period_week"); break; }
            case 3:   { txt = L("lcl_ins_controle_period_month"); break; }
            case 4:   { txt = L("lcl_ins_controle_period_year"); break; }
          }
          if (txt) res = aantal + txt;  // evt. separator in de lcl's
          return res;
        }

        function fnCMSuccess(oRs)
        {
          var res = "";
          if (oRs("ins_controlemode_success").Value == 0)
            if (excel) {
              res = L("lcl_yes");
            } else {
              res = I("fa-exclamation-triangle");
            }
          else
            if (excel) {
              res = L("lcl_yes");
            } else {
              res = I("fa-check");
            }
          return res;
        }

        function fnThresholdstate(oRs)
        {
          var statusicon = "";
          if (oRs("thresholdstate").value == null)
            return "";

          // Als het ouder is dan een dag maken we het uncertain
          var certaintyclass = (new Date(oRs("ins_deel_statedate").value) < new Date(new Date().setDate(new Date().getDate() - 1)) ? " sensoruncertain" : "");

          if (oRs("thresholdstate").value > 0)
             statusicon = (outputmode == 0 ? "<span class='sensoralert"+certaintyclass+"'>"+I("fa-exclamation-triangle", {fastyle: "fas"})+"</span>" : oRs("thresholdstate").value);
          else
            statusicon = (outputmode == 0 ? "<span class='sensorok"+certaintyclass+"'>"+I("fa-circle", {fastyle: "fas"})+"</span>" : oRs("thresholdstate").value);
          return  statusicon;
        }

        function fnActief(oRs)
        {
          return (oRs("ins_deel_actief").Value == 1 ? L("lcl_Yes") : L("lcl_No"));
        }

        function fnlastChangeDate(oRs) {
          var formattedDate = "";
          var sql = " SELECT COALESCE ("
                  + "        (SELECT MAX(datum)"
                  + "            FROM (SELECT MAX(t.fac_tracking_datum) AS datum"
                  + "                    FROM fac_tracking t"
                  + "                   WHERE     fac_srtnotificatie_key IN"
                  + "                                 (SELECT fac_srtnotificatie_key"
                  + "                                    FROM fac_srtnotificatie"
                  + "                                   WHERE fac_srtnotificatie_code IN ('INSNEW', 'INSUPD'))" // Only check for new and updated
                  + "                         AND fac_tracking_refkey = " + oRs("ins_deel_key").Value
                  + "                  UNION"
                  + "                  SELECT MAX(i.ins_deel_note_aanmaak) AS datum"
                  + "                    FROM ins_deel_note i"
                  + "                   WHERE ins_deel_key = " + oRs("ins_deel_key").Value + ")),"
                  + "         (SELECT ins_deel_aanmaak"
                  + "            FROM ins_deel"
                  + "           WHERE ins_deel_key = " + oRs("ins_deel_key").Value + ")) AS most_recent_dates"
                  + " FROM DUAL";
          var oRs = Oracle.Execute(sql);
          if (oRs("most_recent_dates").Value !== null)
            formattedDate = toDateTimeString(new Date(oRs("most_recent_dates").Value));
          oRs.Close();
          return formattedDate;
        }

        function fnrowClass2(oRs)
        {
            var lclass = null;
            if (oRs("res_rsv_deel_key").Value)
            {
                var res_tot = new Date(oRs("res_rsv_deel_tot").Value);
                if (res_tot <= new Date())
                {
                    lclass = " expired2"; // Te laat
                }
            }

            if (inspect)  // Class alleen belangrijk voor looplijst inspectie.
            {
                var recent = new Date();
                recent.setMinutes(recent.getMinutes() - S("mld_melding_recent"));
                var oRs2 = Oracle.Execute(
                  "SELECT MAX(t.fac_tracking_datum) recentdatum"
                  + " FROM fac_tracking t"
                  + ", fac_srtnotificatie sn"
                  + " WHERE sn.fac_srtnotificatie_xmlnode = 'melding'"
                  + " AND t.fac_srtnotificatie_key = sn.fac_srtnotificatie_key"
                  + " AND t.fac_tracking_refkey IN "
                  +   "(SELECT mld_melding_key"
                  +   " FROM mld_melding_object"
                  +   " WHERE ins_deel_key = " + oRs("ins_deel_key").Value + ")"
                );
                if (!oRs2.eof)
                {
                  var mld_recent = new Date(oRs2("recentdatum").Value);
                  if (mld_recent > recent)
                  {
                    lclass = (lclass ? lclass += " recentlychangedmld" : " recentlychangedmld");
                  }
                }
                oRs2.Close();
            }

            return lclass;
        }

        var tot_aantal_ins = 0;
        function fntotalCalc(oRs)
        {
          tot_aantal_ins += oRs("aantal").Value;
        }

        function fntotalShow(column, nrlines)
        {
          var result = "";
          switch (column.caption)
          {
            case L("lcl_ins_aantal_objecten")   : result = tot_aantal_ins; break;
          }
          return result;
        }

        function fncolNoteTooltip(oRs)
        {
          if (oRs("notitie").Value != null)
          {
            return (outputmode == 0 ? toDateTimeString(oRs("notitiedatum").Value) : "");
          }
          else return "";
        }

        function fncolFlags(oRs)
        {
            var ins_deel_key = oRs("ins_deel_key").Value;
            var flagkey = oRs("ins_deel_flag").Value || 0;
            var ttl = L("lcl_ins_flag" + flagkey);
            var displ = "";

            if (print || excel)
            {
                if (flagkey != 0) displ = safe.html(ttl);
            }
            else
            {
                if (flagkey > 0)  // zolang we niet inline kunnen togglen hoeven we een lege flag niet te tonen,
                                  // dat verwart maar icm die multi-edit-checkbox.
                {
                  var flagIcon = I("fa-fclt-flag" + (flagkey == 0 ? "0" : ""));
                  // Met hidden flagkey voor sortering. 999 zorgt dat bij 1 keer sorteren de gevlagde direct bovenaan staan
                  displ = "<div "
                    + " title='"+safe.htmlattr(ttl)+"'>"
                    + "<span id='insflagimg"+ins_deel_key+"' flagkey='"+flagkey+"' class='insflag"+flagkey+"'>"+flagIcon+"</span>"
                    + "<span style='display:none'>"+(flagkey||999)+"</span></div>";
                }
            }
            return displ;
        }

        function fncolFlexBijlagen(oRs)
        {
          var flexval = oRs("insflex").Value;
          if (inspect) {
           var ins_deelsrtcontrole_key = oRs("ins_deelsrtcontrole_key").Value;
          }
          else {
            var ins_key = oRs("ins_deel_key").Value;
          }
          var result = ( flexval
                         ? safe.html(flexval.replace(/\r/g, "\n")+ "\n")
                         : ""
                       );
          if (insFlexParams.bijlageflex)
          {
            result += ins.ins_deel_flex_bijlagen((inspect? ins_deelsrtcontrole_key : ins_key), 1, inspect); // 1=Objectebeheer overzicht.
          }
          return result;
        }

        var deleted_room = false;
        if (room_key_arr.length)
        {
          var sqlr = "SELECT alg_ruimte_verwijder"
                  + "  FROM alg_ruimte"
                  + " WHERE alg_ruimte_key IN (" + room_key_arr.join(",") + ")";
          var oRsr = Oracle.Execute(sqlr);
          deleted_room = oRsr("alg_ruimte_verwijder").Value != null;
          oRsr.Close();
        }

        if (!deleted_room)
        {
          if (koppel_key)
          {
            var this_ins = ins.func_enabled_deel(koppel_key);
            if (this_ins.canChange) {
              buttons.push({ icon: "fa-arrow-right-arrow-left", title: L("lcl_ins_manage"), action: "ins_deelkoppeling()" });
            }
            buttons.push({ icon: "fa-diagram-project", title: L("lcl_ins_deelkoppeling_diagram"), action: "ins_deelkoppeling_diagram()" });
          }
          else if (canAdd)
          {
            var addurl = "";
            if (parent_key)
            {
              var addurl = "appl/ins/ins_deel.asp?urole=" + urole + "&parent_key=" + parent_key;
            }
            else
            {
              // Er zijn nogal wat varianten van parameter name bij INS dus moeten wel in
              // het paramsobject wat vertalingen doen.
              var transitParam = buildTransitParam(["disc", "Group", "sort", "dept", "prs_key",
                                                    "locatiekey", "gebouwkey", "verdiepingkey", "ruimtekey", "werkplekkey"],
                                        { disc: disc_key_arr.join(","), Group: insgroup_key_arr.join(","), sort: objsrt_key_arr.join(","), dept: dep_key, prs_key: persoon_key});
              var addurl = "appl/ins/ins_deel.asp?urole=" + urole + transitParam;
            }
            buttons.push({ icon: "fa-plus", title: L("lcl_add"), action: "FcltMgr.openDetail('" + addurl + "', '" + safe.jsstring(L("lcl_add")) + "')" });
            buttons.push({ icon: "fa-fclt-refresh", title: L("lcl_refresh"), action: "FcltMgr.reload()" });
          }

          if (parent_key)
          {
            var this_ins = ins.func_enabled_deel(parent_key);
            if (this_ins.canChange) {
              buttons.push({ icon: "fa-list-tree", title: L("lcl_ins_manage"), action: "ins_onderdelen()" });
            }
          }

          if (embedded && authparams.PRSwritelevel < 9 && fronto && (cpersoon_key > 0 || persoon_key > 0))
          {
            if (cpersoon_key > 0)
            { // Contactpersoon moet eerst binnengemeld zijn/worden alvorens een object toegekend kan worden.
              sql2 = "SELECT COUNT(b.prs_contactpersoon_key) aantal"
                  + "  FROM bez_bezoekers b"
                  + " WHERE b.prs_contactpersoon_key = " + cpersoon_key
                  + "   AND b.bez_bezoekers_done IS NOT NULL"
                  + "   AND b.bez_bezoekers_out IS NULL";
              var oRs2 = Oracle.Execute(sql2);
              var isbinnen = oRs2("aantal").value > 0;
              oRs2.Close();
            }
            else // (persoon_key > 0): Intern persoon kan altijd een object toegekend krijgen.
              isbinnen = true;

            if (isbinnen || (S("ins_attach_obj_cntpers") == 1 && cpersoon_key > 0 && !checkout))  // ja, deze overschrijft het array
            {
              buttons = [{ icon: "fa-fclt-refresh", title: L("lcl_refresh"), action: "FcltMgr.reload()" },
                         { icon: "fa-plus", title: L("lcl_add"), action: "insCheckOutNewItem(" + (cpersoon_key > 0? cpersoon_key + ", 'C'" : persoon_key + ", 'P'") + ")" }
                        ];
            }
          }
          if (inspect) {
              buttons.push({ icon: "fa-list-ul",  title: L("lcl_mld_legenda"), action: "openLegenda()" });
          }
          buttons.push({ icon: "fa-columns",  title: L("lcl_scf_columns"), action: "openColumns()"});
        }

        /*****************************************************
         * End callback functies ResultsetTable for FO en BO *
         *****************************************************/
        // TODO conditionele Add button
        if (groepering == -1)
        {
          var rst = new ResultsetTable({ keyColumn: (groepering == -1? "ins_deel_key" : null),
                                         sql: sql,
                                         ID: "instable",
                                         tabs_code: "ins_list-" + urole + "-" + (parent_key? "pk" : (koppel_key? "kk" : (inspect? "in" : "ob"))),
                                         rowData: fnrowData,
                                         rowActionEnabler: fnrowActionEnabler,
                                         rowClass: inspect? fnrowClass : fnrowClass2,
                                         flexModule: "INS",
                                         flexId: "ins_deel_key",
                                         flexGroupId: "ins_srtdeel_key",
                                         multiple: true,
                                         filterParams: filterParams,
                                         outputmode: outputmode,
                                         title: (parent_key? L("lcl_subobjects") : (koppel_key? L("lcl_ins_koppelobjects") : (inspect? L("lcl_ins_planned_activities"): L("lcl_ins_objects")))),
                                         showAll: showall,
                                         buttons: buttons,
                                         roundtripCode: (canImport && urole != "fo" ? "INS" : "")
                                       });
        }
        else
          var rst = new ResultsetTable({ sql: sql,
                                         ID: "instable",
                                         rowClass: "",
                                         filterParams: params,
                                         outputmode: outputmode,
                                         title: L("lcl_ins_objects"),
                                         showAll: showall,
                                         totalCalc: fntotalCalc,
                                         totalShow: fntotalShow,
                                         buttons: [] // niet toevoegen in PPI
                                        });

        // Kolommen
        if (fronto)
        {
          if (insPhotoIncl) // screen, niet te veel
            rst.addColumn(new Column({caption: L("lcl_obj_photo"), content: fnInlinePhoto, colName: "fnInlinePhoto", classList: "toggle-objphoto" }));
          rst.addColumn(new Column({caption: L("lcl_obj_sort"), content: "soort", hasActions: true}));
          rst.addColumn(new Column({caption: L("lcl_obj_identification"), content: "ins_deel_omschrijving"}));
          rst.addColumn(new Column({caption: L("lcl_ins_opmerking"), content: "ins_deel_opmerking"}));
          rst.addColumn(new Column({caption: L("lcl_obj_position"), content: fnPlace, colName: "fnPlace"}));
          rst.addColumn(new Column({caption: L("lcl_res_starttime"), content: "res_rsv_deel_van", datatype: "datetime", colName: "fnGereserveerdVan"}));
          rst.addColumn(new Column({caption: L("lcl_res_endtime"), content: "res_rsv_deel_tot", datatype: "datetime", colName: "fnGereserveerdTot"}));
          rst.addColumn(new Column({caption: L("lcl_obj_lent_out_to"), content: fnLentOutTo, colName: "fnLentOutTo"}));
          if (lentoutAction >= 0)
          {
            var col_caption = (lentoutAction == 1 ? L("lcl_ins_laatste_uitgifte") : (lentoutAction == 2 ? L("lcl_ins_laatste_inname") : L("lcl_ins_laatste_actie")));
            rst.addColumn(new Column({caption: col_caption, content: "fac_tracking_datum", datatype: "datetime", colName: "fnLentDate"}));
          }
          if (excel)
              rst.addColumn(new Column({caption: L("lcl_prs_email"), content: fnLentOutToEmail, colName: "fnLentOutToEmail"}));
        }
        else if (groepering == -1)
        {
          if (koppel_key && (L("lcl_obj_koppelaan") != L("lcl_obj_koppelvan")))
          {
              rst.addColumn(new Column({caption: I("fa-arrows-left-right"), content: fnKoppelrichting, colName: "fnKoppelrichting"}));
              rst.addColumn(new Column({caption: L("lcl_obj_identification"), content: fnKoppel, colName: "fnKoppel"}));
              rst.addColumn(new Column({caption: L("lcl_obj_koppelaan"), content: fnKoppelaan, colName: "fnKoppelaan", showDefault: false}));
              rst.addColumn(new Column({caption: L("lcl_obj_koppelvan"), content: fnKoppelvan, colName: "fnKoppelvan", showDefault: false}));
          }
          else // Gewoon
          {
              if (S("ins_deel_flags") > 0)
              {
                rst.addColumn(new Column({caption: (outputmode == 0 ?  I("fa-fclt-flag0") : L("lcl_ins_flags")), content: fncolFlags, colName: "fncolFlags", colText: L("lcl_ins_flags"), align: "center"}));
              }
              if (inspect && ctrdisc_key_arr.length != 1)
                rst.addColumn(new Column({caption: L("ctr_discipline"), content: "ctr_disc_oms"}));
              if (insPhotoIncl && !excel) // screen, niet te veel
                rst.addColumn(new Column({caption: L("lcl_obj_photo"), content: fnInlinePhoto, colName: "fnInlinePhoto", classList: "toggle-objphoto" }));
              rst.addColumn(new Column({caption: L("lcl_obj_identification"), content: "ins_deel_omschrijving", nowrap: true }));
              if (insObjIncl)
                rst.addColumn(new Column({caption: L("lcl_ins_parentobject"), content: "parent_omschrijving", nowrap: true, showDefault: false }));
              if (hasAantal)
              {
                rst.addColumn(new Column({caption: L("lcl_count"), content: "ins_deel_aantal", datatype: "number"}));
                rst.addColumn(new Column({caption: L("lcl_obj_unit"), content: "ins_srtdeel_eenheid"}));
              }
              rst.addColumn(new Column({caption: L("lcl_ins_opmerking"), content: "ins_deel_opmerking", combine: inspect}));
          }
          if (koppel_key)
              rst.addColumn(new Column({caption: L("lcl_obj_koppeloms"), content: "ins_deelkoppeling_omschrijving"}));
          if (inspect)
          {
              rst.addColumn(new Column({caption: L("lcl_ins_controle_cyclus"), content: fnCyclus, nowrap: true, colName: "fnCyclus"}));
              rst.addColumn(new Column({caption: L("lcl_ins_status"), content: fnStatus, colName: "fnStatus"}));
              rst.addColumn(new Column({caption: (inspDone? L("lcl_ins_controle_datum") : L("lcl_ins_controle_next")), content: fnInspectie, colName: "fnInspectie"}));
              rst.addColumn(new Column({caption: L("lcl_ins_controle_plandate"), content: fnPlandatum, colName: "fnPlandatum"}));
              if (inspDone)
                rst.addColumn(new Column({caption: L("ins_controlemode_success"), content: fnCMSuccess, colName: "fnCMSuccess"}));
              rst.addColumn(new Column({caption: L("lcl_ins_controle_srt"), content: "ins_srtcontrole_omschrijving"}));
              rst.addColumn(new Column({caption: L("ins_srtcontrole_opmerking"), content: "ins_srtcontrole_opmerking"}));
              rst.addColumn(new Column({caption: L("lcl_ins_srtcontrole_groep"), content: "groepoms"}));
          }

          if (!parent_key) {
              rst.addColumn(new Column({caption: L("lcl_obj_position"), content: "plaats", showDefault: !koppel_key }));
              if (!fgraph) {
                rst.addColumn(new Column({caption: L("lcl_obj_owner"), content: "uitgeleend_aan", combine: true, showDefault: !koppel_key }));
                rst.addColumn(new Column({caption: L("lcl_estate_locatie_man_descr"), content: "alg_locatie_omschrijving", showDefault: !koppel_key }));
                rst.addColumn(new Column({caption: L("lcl_adress"), content: "alg_locatie_adres", showDefault: !koppel_key }));
                rst.addColumn(new Column({caption: L("lcl_prs_address_bezoek_plaats"), content: "alg_locatie_plaats", combine: true, showDefault: !koppel_key }));
              }
          }
          if (inspect)
            rst.addColumn(new Column({caption: L("lcl_company"), content: "prs_bedrijf_naam"}));
          rst.addColumn(new Column({caption: L("lcl_discipline"), content: "ins_disc_oms", showDefault: !koppel_key }));
          rst.addColumn(new Column({caption: L("lcl_obj_group"), content: "ins_groep_oms", showDefault: !koppel_key }));
          rst.addColumn(new Column({caption: L("lcl_obj_sort"), content: "soort", showDefault: !koppel_key }));
          if (ins_score_enabled)
          {
            rst.addColumn(new Column({caption: L("ins_srtdeel_mjb_grensscore1"), content: "ins_srtdeel_mjb_grensscore1", datatype: "number", align: "center"}));
            rst.addColumn(new Column({caption: L("lcl_ins_deel_mjb_score1"), content: "ins_deel_mjb_score1", datatype: "number", align: "center"}));
            rst.addColumn(new Column({caption: L("lcl_ins_deel_mjb_score2"), content: "ins_deel_mjb_score2", datatype: "number", align: "center"}));
          }

          if (inspDone)
          {
            rst.addColumn(new Column({caption: L("lcl_ins_inspecteur"), content: "inspecteur"}));
          }
          if (anyobjman)
          {
            rst.addColumn(new Column({caption: L("lcl_ins_manager"), content: "objectbeheerder"}));
          }
          if (!parent_key && !koppel_key && !inspect) {
              if (!fgraph && !embedded &&hasDrawings)
                rst.addColumn(new Column({caption: L("lcl_fg_gotofgheader"), content: fnPosition, colName: "fnPosition", align:"center"}));
              if (!embedded && ErisReserveerbaar && !inspect)
                  rst.addColumn(new Column({caption: L("lcl_obj_reserveerbaar"), content: fnReserveerbaar, colName: "fnReserveerbaar", align:"center"}));
              if (!embedded && ErisUitleenbaar && !inspect)
                  rst.addColumn(new Column({caption: L("lcl_obj_uitleensrtdeel"), content: fnUitleenbaar, colName: "fnUitleenbaar", align:"center"}));
          }
          // Toon sensorinfo
          if (insSensOnly)
          {
              // alert indien overschrijding
              rst.addColumn(new Column({caption: L("lcl_ins_sensoralertstate"), content: fnThresholdstate, colName: "fnThresholdstate", align: "center"}));
               // de actueelste sensorwaarde
              rst.addColumn(new Column({caption: L("lcl_deel_state"), content: "ins_deel_state", align: "center", tooltip: "ins_deel_statedate" }));
              rst.addColumn(new Column({caption: L("lcl_deel_statedate"), content: "ins_deel_statedate", showDefault: false }));
           }
        }

        if (fronto || groepering == -1)
        {
          if (inacObjIncl) {
            // alleen als er ook inactieven voorkomen is het zinvol deze kolom te tonen
            rst.addColumn(new Column({caption: L("lcl_ins_active"), content: fnActief, colName: "fnActief", showDefault: !koppel_key }));
          }
          if (!inspect && !fronto) {  // kan over gediscussieerd worden
            rst.addColumn(new Column({caption: L("lcl_ins_vervaldatum"), content: "ins_deel_vervaldatum", datatype: "date", prettydate: true, showDefault: !koppel_key }));
          }

          rst.addColumn(new Column({caption: L("lcl_mld_inf_name"), content: fnlastChangeDate, colName: "fnlastChangeDate" }));
          rst.addColumn(new Column({caption: L("lcl_last_action"), content: "ins_deel_aanmaak", datatype: "date", purpose: PRINTING_ONLY}));
          // Printing_only suggereert dat het je dan op het scherm niet in de weg staat maar niemand wil coordinaten op zijn print
          // Wel naar Excel hooguit. Maar we moeten hier sowieso naar kijken irt showDefault
          rst.addColumn(new Column({caption: L("lcl_obj_geoxcoord"), content: "ins_deel_x", purpose: PRINTING_ONLY, showDefault: false}));
          rst.addColumn(new Column({caption: L("lcl_obj_geoycoord"), content: "ins_deel_y", purpose: PRINTING_ONLY, showDefault: false}));
        }

        if (fronto || groepering == -1 || inspect)
        {
          if (withflex && !excel && !print && insFlexParams.anyflex) {
            rst.addColumn(new Column({caption: insFlexParams.flexlabel, content: fncolFlexBijlagen, colName: "fncolFlexBijlagen"}));
          }
          if (!frontend)
            rst.addColumn(new Column({caption: L("lcl_ins_note"), content: "notitie", tooltip: (outputmode == 0 && !frontend ? fncolNoteTooltip : null)}));
        }

        if (groepering > 0)
        {
          var caption = "";
          var content = "";
          switch (groepering)
          {
            case 1  : rst.addColumn(new Column({caption: L("lcl_discipline"), content: "ins_disc_oms"}));
                      break;
            case 2  : rst.addColumn(new Column({caption: L("lcl_discipline"), content: "ins_disc_oms"}));
                      rst.addColumn(new Column({caption: L("lcl_obj_group"), content: "ins_groep_oms"}));
                      break;
            case 3  : rst.addColumn(new Column({caption: L("lcl_discipline"), content: "ins_disc_oms"}));
                      rst.addColumn(new Column({caption: L("lcl_obj_group"), content: "ins_groep_oms"}));
                      rst.addColumn(new Column({caption: L("lcl_obj_sort"), content: "soort"}));
                      break;
            case 5  : rst.addColumn(new Column({caption: L("lcl_mi_location"), content: "alg_locatie_omschrijving"}));
                      break;
            case 6  : rst.addColumn(new Column({caption: L("lcl_mi_location"), content: "alg_locatie_omschrijving"}));
                      rst.addColumn(new Column({caption: L("lcl_bld_terra"), content: "geb_ter_omschrijving"}));
                      break;
            case 11 : rst.addColumn(new Column({caption: L("lcl_prs_organisatie"), content: "prs_afdeling_naam"}));
                      break;
            case 12 : rst.addColumn(new Column({caption: L("lcl_bld_ter_verantw"), content: "verantwoordelijke"}));
                      break;
            case 13 : rst.addColumn(new Column({caption: L("lcl_ins_manager"), content: "objectbeheerder"}));
                      break;
          }
          rst.addColumn(new Column({caption: L("lcl_ins_aantal_objecten"), content: "aantal", datatype: "number", total: true}));
        }

        // Acties
        if (fronto && authparams.PRSwritelevel < 9) // Ik heb write rechten nodig voor deze acties
        {
          // 1 van de 2 mag zichtbaar zijn. Kijken naar query resultaat!!!
          // PF: TODO: multi in/uit werkt niet goed
          rst.addAction({ action: "insEdit", caption: L("lcl_details"), enabler: "eDetails", isDefault: true}); // Actie insEdit gaat toch eerst naar show mode.
          // Inchecken of uitchecken is zichtbaar. Beiden kunnen als default aangeven worden.
          // Nu alle regels aanklikbaar of inchecken of uitchecken
          rst.addAction({ action: "insCheckOut", caption: L("lcl_obj_lend_out"), enabler: "eLendOut", multi: true, multiOnce: true });
          rst.addAction({ action: "insCheckIn", caption: L("lcl_obj_receive"), enabler: "eReceive", multi: true, multiOnce: true });
          rst.addAction({ action: "insAdapt", caption: L("lcl_ins_adapt"), enabler: "eAdapt" });
        }
        if (backo && groepering == -1)
        {
          rst.addAction({ action: "insEdit", caption: L("lcl_change"), isDefault: true}); // isDefault, dus nooit multi, alleen door aanklikken regel. Multi via afgehandeld via functie insMultiEdit()
          if (inspect)
          {
            var sql_opt = "SELECT MAX(BITAND(ins_srtcontrole_options, 1)) insplan"
                    + "     , MAX(BITAND(ins_srtcontrole_options, 2)) insstart"
                    + "     , MAX(BITAND(ins_srtcontrole_options, 4)) insclose"
                    + "     , MAX(BITAND(ins_srtcontrole_options, 8)) insfinish"
                    + "     , COUNT(ins_srtcontrole_options) aantal"
                    + "  FROM ins_srtcontrole";
            var oRs_opt = Oracle.Execute(sql_opt);

            if (oRs_opt("aantal").Value > 0)
              rst.addAction({ action: "insShowInsp", caption: L("lcl_details"), enabler: "eShowInsp" });
            if (oRs_opt("insplan").Value == 1)
            { // Single alleen inplannen, Multi in/herplannen.
              rst.addAction({ action: "insPlanInline", caption: L("lcl_ins_schedule"), multi: false, enabler: "ePlan" });
              rst.addAction({ action: "insPlanMulti", caption: L("lcl_ins_schedule_multi"), onlyMulti: true, multi: true, multiOnce: true, enabler: "ePlanMulti" });
            }
            if (oRs_opt("insstart").Value == 2)
              rst.addAction({ action: "insStart", caption: L("lcl_ins_start"), multi: !tiny, multiOnce: true, enabler: "eStart" });
            if (oRs_opt("insclose").Value == 4)
              rst.addAction({ action: "insClose", caption: L("lcl_ins_stop"), multi: !tiny, multiOnce: true, enabler: "eClose" });
            if (oRs_opt("insfinish").Value == 8)
              rst.addAction({ action: "insFinish", caption: L("lcl_ins_finish"), multi: !tiny, multiOnce: true, enabler: "eFinish" });
            oRs_opt.Close();
          }
          else
          {
            rst.addAction({ action: "insDelete", caption: L("lcl_delete"), enabler: "eDelete", single: false, multi: !tiny, multiOnce: true});
            if (hasWriteINSMAN) // Ik heb INSMAN rechten nodig om multi te kunnen editen. Met alleen INSUSE rechten mag ik dat vooralsnog niet.
              rst.addAction({ action: "insMultiEdit", caption: L("lcl_ins_multi_edit"), enabler: "eEditMulti", multi: !tiny, single: false, multiOnce: true});
            rst.addAction({ action: "insMultiMove", caption: L("lcl_ins_multi_move"), enabler: "NotExist", multi: !tiny, single: false, multiOnce: true});
            if (user.has("WEB_RESMSU"))
                rst.addAction({ action: "insMultiReserve", caption: L("lcl_ins_multi_reserve"), enabler: "NotExist", multi: !tiny, single: false, multiOnce: true});
            if (user.has("WEB_INSMAN"))
                rst.addAction({ action: "insMultiSrtdeel", caption: L("lcl_ins_multi_srtdeel"), enabler: "NotExist", multi: !tiny, single: false, multiOnce: true});
          }
        }

        var count = rst.processResultset();

        if (!excel && !print)
        {
%>
              <!-- LEGENDA  -->
            <script type="text/javascript">
            function openLegenda()
            {
                var myPosition = "right top+30";
                if (elems.$originalHeaderRow && elems.$originalHeaderRow.length)
                    myPosition = "right-15 top+"+(parseInt(elems.$fcltFrameHeader.css("top"))+30);
                params = { width: 250,
                           minWidth: 250,
                           minHeight: 10,
                           resizable: false,
                           position: {my: "right top", at: myPosition},
                           title: L("lcl_ins_controle_legenda"),
                           create: FcltMgr.fnCreateCloseButton("div#legenda")
                         };
                   $('div#legenda').dialog(params).dialog('open');
                FcltMgr.resized();
            }
          </script>
            <div id="legenda" style="display:none; line-height: 30px;">
              <table id="inslegenda">
                <tr class="expired1">
                  <td title="<%=safe.htmlattr(L("lcl_ins_controle_soon"))%>"><%=safe.html(L("lcl_ins_controle_soon"))%></td>
                </tr>
                <tr class="expired2">
                  <td title="<%=safe.htmlattr(L("lcl_ins_controle_soon"))%>"><%=safe.html(L("lcl_ins_controle_late"))%></td>
                </tr>
              </table>
            </div>
<%
        }
      }
%>
    </body>
  </html>
<%
}
%>
