<% /*
     $Revision$
     $Id$
*/
%>
<!-- #include file="../PRS/prs.inc" -->
<!-- #include file="../Shared/discx3d.inc" -->
<!-- #include file="../Shared/getkenmerksql.inc" -->
<!-- #include file="../Shared/flexfiles.inc" -->
<%

var BIND_RUIMTE = 0x01;
var BIND_WERKPL = 0x02;
var BIND_TERREI = 0x04;
var BIND_AFDELI = 0x08;
var BIND_PERSOO = 0x10;
var BIND_INSDEE = 0x20; // Onderdeel

ins = {checkAutLevel:
           function (pAutfunction, pUser_key)
           {
               // De DISTINCT in het volgende statement is erg belangrijk
               // We staan multiedit toe van objecten van verschillende disciplines
               //    echter alleen als de gebruiker voor al die disciplines exact dezelfde
               //    alg_level_write en prs_level_write heeft. Anders wordt het veel te complex.
               var sql =  "SELECT distinct fac_gebruiker_alg_level_write, fac_gebruiker_prs_level_write "
                        + "  FROM fac_v_webgebruiker w, fac_functie f, ins_deel idd "
                        + " WHERE w.ins_discipline_key = idd.ins_discipline_key "
                        + "   AND w.fac_functie_key = f.fac_functie_key "
                        + "   AND w.prs_perslid_key = " + pUser_key
                        + "   AND fac_functie_code = '"+pAutfunction+"' "
                        + "   AND ins_deel_key IN (" + inskeystring + ")"

               var oRs = Oracle.Execute(sql)
               if (oRs.eof)
                   return false;

               /*globaal*/ alg_level = oRs("fac_gebruiker_alg_level_write").Value;
               /*globaal*/ prs_level = oRs("fac_gebruiker_prs_level_write").Value;

               if (alg_level==9 && prs_level==9)
                   return false; // Alleen leesrechten op *alle* objecten blijkbaar

               oRs.MoveNext();
               if (!oRs.eof)
                   return false; // "Autorisatie te complex! Kies alleen objecten van dezelfde discipline");

               return true; // Okido
           },

       setinspectstatus:
           function (deelsrtcontrole_key, ins_inspect_status_key, uitvoerende)
           { // Zet de status en geef de bijpassende tracking en notificatie.
             var sql = "BEGIN ins.setinspectstatus(" + deelsrtcontrole_key + ", " + ins_inspect_status_key + ", " + user_key + "); END;"
             Oracle.Execute(sql);
             // In geval van CND/MJB willen we de gebreken resetten wanneer de laatste taak wordt afgemeld
             // dat is een heel een rijtje voorwaarden, dat willen we zo zuinig mogelijk doen
             if (ins_inspect_status_key == 6) {
                // taak werd afgemeld, dan moeten we kijken of we nog iets moeten doen
                ins.process_mjb_gebreken(deelsrtcontrole_key);
             }
           },

       process_mjb_gebreken:
            function (deelsrtcontrole_key)
            {
              // Finish all related "gebreken"-calls is this is the last task on that object
              if (S("cnd_gebreken_srtdisc_key") > 0) {
                  var cndsql = "BEGIN cnd.process_mjb_gebreken(" + deelsrtcontrole_key  + ", " + (user_key>0?user_key:"NULL") + "); END;";
                  Oracle.Execute(cndsql);
              }
            },

       trackdeelupdate:
           // Let op: dit moet wellicht niet altijd (aangeroepen na save)
           function (ins_key, ptxt, nonoti) // Nonoti onderdrukt notificatie
           {
             return shared.trackaction((nonoti?"#":"") + "INSUPD", ins_key, ptxt);
           },

       trackinspectupdate:
           // Let op: dit moet wellicht niet altijd (aangeroepen na save)
           function (deelsrtcontrole_key, ptxt)
           {
             shared.trackaction("INSCUP", deelsrtcontrole_key, ptxt);
           },

       tracksrtdeelupdate:
           function (srtdeel_key, ptxt)
           {
              shared.trackaction("INSSUP", srtdeel_key, ptxt);
           },

       getBindingItemString:
           function(bind, bind_key, parent_key)
           {
             var sql;
             var binding_item = L("lcl_unknown");
             switch (bind)
             {
                 case 'A':
                 {
                     sql = "SELECT " + S("prs_dep_string")
                         + " FROM prs_v_afdeling d"
                         + " WHERE d.prs_afdeling_key = " + bind_key;
                     break;
                 }

                 case 'P':
                 {
                     sql = "SELECT prs_perslid_naam_full"
                         + " FROM prs_v_perslid_fullnames_all pf"
                         + " WHERE pf.prs_perslid_key = " + bind_key;
                     break;
                 }

                 case 'C':
                 {
                     sql = "SELECT " + S("prs_contactpers_string")
                         + " FROM prs_contactpersoon cp"
                         + " WHERE cp.prs_contactpersoon_key = " + bind_key;
                     break;
                 }

                 case 'R':
                 {
                     sql = "SELECT o.alg_plaatsaanduiding || DECODE(o.alg_plaatsomschrijving, '','' ,' (' || o.alg_plaatsomschrijving || ')')"
                         + "  FROM ins_v_alg_overzicht o "
                         + " WHERE o.alg_onroerendgoed_type = 'R'"  // ins_v_alg_overzicht levert anders ook de werkplekken in die ruimte op
                         + "   AND o.alg_ruimte_key = " + bind_key;
                     break;
                 }

                 case 'W':
                 {
                     sql = "SELECT pa.alg_plaatsaanduiding || DECODE(a.alg_ruimte_omschrijving,NULL,'',' (' || a.alg_ruimte_omschrijving || ')')"
                         + " FROM alg_ruimte a"
                         + ", ins_v_alg_overzicht pa"
                         + " WHERE a.alg_ruimte_key = pa.alg_ruimte_key"
                         + " AND pa.alg_onroerendgoed_type = 'W'"  // ten overvloede
                         + " AND pa.prs_werkplek_key = " + bind_key;
                     break;
                 }

                 case 'T':
                 {
                     sql = "SELECT pa.alg_plaatsaanduiding || DECODE(t.alg_terreinsector_naam,NULL,'',' (' || t.alg_terreinsector_naam || ')')"
                         + " FROM alg_terreinsector t"
                         + ", ins_v_alg_overzicht pa"
                         + " WHERE t.alg_terreinsector_key = pa.alg_terreinsector_key"
                         + " AND pa.alg_onroerendgoed_type = 'T'"  // ten overvloede
                         + " AND t.alg_terreinsector_key = " + bind_key;
                   break;
                 }

                 case 'I':
                 {
                     sql = "SELECT ins_deel_omschrijving"
                         + " FROM ins_deel d"
                         + " WHERE d.ins_deel_key = " + parent_key;
                   break;
                 }

                 default: INTERNAL_ERROR_UNKNOWN_BIND;
             }
             var oRs = Oracle.Execute(sql);
             if (!oRs.eof)
                 binding_item = oRs(0).Value;
             oRs.Close();
             return binding_item;
           },

       getGGD:
           function(obj_keys)
           {
             if (obj_keys.length > 0)
             {
               // deelgegevens_sql is ins_v_deel_gegevens_keys waarbij geen gebruik gemaakt is van ins_v_aanwezigdeel
               // omdat daarin ook nog "ins_deel_parent_key is null" staat.
               var deelgegevens_sql = " SELECT de.ins_alg_locatie_key alg_locatie_key"
                                    + "      , ve.alg_gebouw_key      alg_gebouw_key"
                                    + "      , ru.alg_verdieping_key  alg_verdieping_key"
                                    + "      , de.ins_alg_ruimte_key  alg_ruimte_key"
                                    + "      , TO_NUMBER(NULL)        prs_werkplek_key"
                                    + "      , TO_NUMBER(NULL)        alg_terreinsector_key"
                                    + "      , TO_NUMBER(NULL)        prs_afdeling_key"
                                    + "      , TO_NUMBER(NULL)        prs_perslid_key"
                                    + "      , de.ins_deel_key        ins_deel_key"
                                    + "   FROM ins_v_deelenonderdeel de"
                                    + "      , alg_ruimte            ru"
                                    + "      , alg_verdieping        ve"
                                    + "  WHERE de.ins_deel_verwijder IS NULL"
                                    + "    AND (  (de.ins_alg_ruimte_key = ru.alg_ruimte_key)"
                                    + "        AND de.ins_alg_ruimte_type = 'R')"
                                    + "    AND (  (ru.alg_verdieping_key = ve.alg_verdieping_key)"
                                    + "        AND de.ins_alg_ruimte_type = 'R')"
                                    + "  UNION ALL"
                                    + " SELECT de.ins_alg_locatie_key"
                                    + "      , ve.alg_gebouw_key"
                                    + "      , ru.alg_verdieping_key"
                                    + "      , ru.alg_ruimte_key"
                                    + "      , de.ins_alg_ruimte_key"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , de.ins_deel_key"
                                    + "   FROM ins_v_deelenonderdeel de"
                                    + "      , prs_werkplek          wp"
                                    + "      , alg_ruimte            ru"
                                    + "      , alg_verdieping        ve"
                                    + "  WHERE de.ins_deel_verwijder IS NULL"
                                    + "    AND (  (de.ins_alg_ruimte_key = wp.prs_werkplek_key)"
                                    + "        AND de.ins_alg_ruimte_type = 'W')"
                                    + "    AND (  (wp.prs_alg_ruimte_key = ru.alg_ruimte_key)"
                                    + "        AND de.ins_alg_ruimte_type = 'W')"
                                    + "    AND ru.alg_verdieping_key = ve.alg_verdieping_key"
                                    + "  UNION ALL"
                                    + " SELECT de.ins_alg_locatie_key"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , de.ins_alg_ruimte_key"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , de.ins_deel_key"
                                    + "   FROM ins_v_deelenonderdeel de"
                                    + "  WHERE de.ins_deel_verwijder IS NULL"
                                    + "    AND de.ins_alg_ruimte_type = 'T'"
                                    + "  UNION ALL"
                                    + " SELECT de.ins_alg_locatie_key"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , de.ins_alg_ruimte_key"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , de.ins_deel_key"
                                    + "   FROM ins_v_deelenonderdeel de"
                                    + "  WHERE de.ins_deel_verwijder IS NULL"
                                    + "    AND de.ins_alg_ruimte_type = 'A'"
                                    + "  UNION ALL"
                                    + " SELECT de.ins_alg_locatie_key"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , TO_NUMBER(NULL)"
                                    + "      , af.prs_afdeling_key"
                                    + "      , de.ins_alg_ruimte_key"
                                    + "      , de.ins_deel_key"
                                    + "   FROM ins_v_deelenonderdeel de"
                                    + "      , prs_perslid           pl"
                                    + "      , prs_afdeling          af"
                                    + "  WHERE de.ins_deel_verwijder IS NULL"
                                    + "    AND (  (de.ins_alg_ruimte_key = pl.prs_perslid_key)"
                                    + "        AND de.ins_alg_ruimte_type = 'P')"
                                    + "    AND (  (pl.prs_afdeling_key = af.prs_afdeling_key)"
                                    + "        AND de.ins_alg_ruimte_type = 'P')";

               var sql = "SELECT dg.prs_perslid_key"
                       + "     , dg.prs_afdeling_key"
                       + "     , dg.alg_locatie_key"
                       + "     , dg.alg_gebouw_key"
                       + "     , dg.alg_terreinsector_key"
                       + "     , dg.alg_verdieping_key"
                       + "     , dg.alg_ruimte_key"
                       + "     , " + S("alg_loc_string") + " loc_oms"
                       + "     , " + S("alg_geb_string") + " geb_oms"
                       + "     , " + S("alg_ter_string") + " ter_oms"
                       + "     , v.alg_verdieping_omschrijving ver_oms"
                       + "     , g.alg_gebouw_code || '-' || v.alg_verdieping_code || '-' || r.alg_ruimte_nr rui_oms"
                       + "  FROM (" + deelgegevens_sql + ") dg"
                       + "     , alg_v_aanweziglocatie l"
                       + "     , alg_v_aanweziggebouw g"
                       + "     , alg_v_aanwezigterreinsector t"
                       + "     , alg_v_aanwezigverdieping v"
                       + "     , alg_v_aanwezigruimte r"
                       + " WHERE dg.alg_locatie_key = l.alg_locatie_key(+)"
                       + "   AND dg.alg_gebouw_key = g.alg_gebouw_key(+)"
                       + "   AND dg.alg_terreinsector_key = t.alg_terreinsector_key(+)"
                       + "   AND dg.alg_verdieping_key = v.alg_verdieping_key(+)"
                       + "   AND dg.alg_ruimte_key = r.alg_ruimte_key(+)"
                       + "   AND dg.ins_deel_key IN (" + obj_keys.join(",") + ")"
                       + " ORDER BY prs_perslid_key DESC"; // Eerst de plaatsgebonden objecten.
               var oRs = Oracle.Execute(sql);
               var nrPlaatsGebondenObjects = 0;
               var diffL = false; // Meegegeven objecten bevinden zich op verschillende locaties.
               var diffG = false; // Meegegeven objecten bevinden zich in verschillende gebouwen.
               var diffT = false; // Meegegeven objecten bevinden zich in verschillende terreinen.
               var diffV = false; // Meegegeven objecten bevinden zich op verschillende verdiepingen.
               var diffR = false; // Meegegeven objecten bevinden zich in verschillende ruimten.
               var prs_key = oRs("prs_perslid_key").Value;
               var afd_key = oRs("prs_afdeling_key").Value;
               var loc_key = oRs("alg_locatie_key").Value;
               var geb_key = oRs("alg_gebouw_key").Value;
               var ter_key = oRs("alg_terreinsector_key").Value;
               var ver_key = oRs("alg_verdieping_key").Value;
               var rui_key = oRs("alg_ruimte_key").Value;
               var loc_oms = oRs("loc_oms").Value;
               var geb_oms = oRs("geb_oms").Value;
               var ter_oms = oRs("ter_oms").Value;
               var ver_oms = oRs("ver_oms").Value;
               var rui_oms = oRs("rui_oms").Value;
               if (prs_key == null && afd_key == null)
                 nrPlaatsGebondenObjects++;
               while (!oRs.eof)
               {
                 if (oRs("prs_perslid_key").Value == null && oRs("prs_afdeling_key").Value == null)
                 { // Object is niet persoons- of afdelingsgebonden.
                   nrPlaatsGebondenObjects++;
                   if (!diffL && loc_key != oRs("alg_locatie_key").Value)
                     diffL = diffG = diffV = diffR = true;
                   else if (!diffG && (geb_key != oRs("alg_gebouw_key").Value || oRs("alg_gebouw_key").Value == null))
                     diffG = diffV = diffR = true;

                   if (!diffT && (ter_key != oRs("alg_terreinsector_key").Value || oRs("alg_terreinsector_key").Value == null))
                     diffT = true;

                   if (!diffV && ver_key != oRs("alg_verdieping_key").Value)
                     diffV = diffR = true;
                   else if (!diffR && rui_key != oRs("alg_ruimte_key").Value)
                     diffR = true;
                 }
                 oRs.MoveNext();
               }
               oRs.Close();
               if (nrPlaatsGebondenObjects == 0)
                 return null; // Er zijn geen plaatsgebonden objecten gevonden.
               else if (!diffR)
                 return {alg_key: rui_key, alg_type: "R", alg_oms: rui_oms, ver_key: ver_key, ver_oms: ver_oms, geb_key: geb_key, geb_oms: geb_oms, loc_key: loc_key, loc_oms: loc_oms};
               else if (!diffV)
                 return {alg_key: ver_key, alg_type: "V", alg_oms: ver_oms, geb_key: geb_key, geb_oms: geb_oms, loc_key: loc_key, loc_oms: loc_oms};
               else if (!diffT)
                 return {alg_key: ter_key, alg_type: "T", alg_oms: ter_oms, loc_key: loc_key, loc_oms: loc_oms};
               else if (!diffG)
                 return {alg_key: geb_key, alg_type: "G", alg_oms: geb_oms, loc_key: loc_key, loc_oms: loc_oms};
               else if (!diffL)
                 return {alg_key: loc_key, alg_type: "L", alg_oms: loc_oms};
               else
                 return null;
             }
             else
              return null;
           },

       getinspectstatustext:
           function (p)
           {
             var statustekst = "??";
             var s = parseInt(p, 10);
             switch (s) {
                 case 0: { statustekst = L("lcl_ins_controle_pending"); break; }
                 case 2: { statustekst = L("lcl_ins_controle_gestart"); break; }
                 case 3: { statustekst = L("lcl_ins_controle_ter_uitvoer"); break; }
                 case 5: { statustekst = L("lcl_ins_controle_act_req"); break; }
                 case 6: { statustekst = L("lcl_ins_controle_afgerond"); break; }
             }
             if (__Logging> 0)
               statustekst += " ("+String(p)+")";
             return statustekst;
          },

        getscenariostatustext:
           function (p)
           {
             var statustekst = "??";
             var s = parseInt(p, 10);
             switch (s) {
                 case 0: { statustekst = L("lcl_ins_new"); break; }
                 case 6: { statustekst = L("lcl_ins_verwerkt"); break; }
             }
             if (__Logging > 0)
               statustekst += " (" + String(p) + ")";
             return statustekst;
           },

       updateKenmerkdeel:
           function(ins_key, params)
           { // Wijzigbare flexkenmerken altijd opslaan
             params = params || [];
             currentKenmerkenSQL = "SELECT v.ins_kenmerk_key"
                                 + "     , v.ins_kenmerkdeel_waarde"
                                 + "     , k.ins_kenmerk_toonbaar"
                                 + "     , k.fac_functie_key"
                                 + "  FROM ins_kenmerkdeel v"
                                 + "     , ins_kenmerk k"
                                 + " WHERE k.ins_kenmerk_key = v.ins_kenmerk_key"
                                 + "   AND v.ins_kenmerkdeel_verwijder IS NULL"
                                 + "   AND v.ins_deel_key = " + ins_key;

             allKenmerkenSQL     = "SELECT COALESCE (" + lcl.xsql("k.ins_kenmerk_omschrijving", "k.ins_kenmerk_key")
                                 + "              ,  " + lcl.xsql("t.ins_srtkenmerk_omschrijving", "t.ins_srtkenmerk_key") + ") kenmerk_omschrijving"
                                 + "     , t.ins_srtkenmerk_kenmerktype kenmerk_kenmerktype"
                                 + "     , t.ins_srtkenmerk_systeem     kenmerk_systeem"
                                 + "     , k.ins_kenmerk_toonbaar       kenmerk_readonly"
                                 + "     , k.ins_kenmerk_inlijst        kenmerk_inlijst"
                                 + "     , k.ins_kenmerk_uniek          kenmerk_uniek"
                                 + "     , fac_kenmerkdomein_key"
                                 + "  FROM ins_kenmerk k"
                                 + "     , ins_srtkenmerk t"
                                 + " WHERE k.ins_srtkenmerk_key = t.ins_srtkenmerk_key"
                                 + "   AND k.ins_kenmerk_key = "; /* wordt in saveFlexkenmerken uitgebreid */

             var flextrack = saveFlexKenmerken(ins_key,
                                               { kenmerkTable: "ins_kenmerkdeel",
                                                 kenmerkParentKey : "ins_deel_key",
                                                 kenmerkWaarde: "ins_kenmerkdeel_waarde",
                                                 kenmerkKey: "ins_kenmerk_key",
                                                 kenmerkToonbaar: "ins_kenmerk_toonbaar",
                                                 currentKenmerkenSQL: currentKenmerkenSQL,
                                                 allKenmerkenSQL: allKenmerkenSQL,
                                                 requestQF: Request.Form,
                                                 isNew: params.isnew,
                                                 flexPath: "INS/I",
                                                 multiMode: params.multimode,
                                                 tracking: true,
                                                 module: "INS"
                                               });

             //
             if (params.copy)
             {
                var flexsql = "SELECT k_old.ins_kenmerk_key k_old"
                            + "     , k_old.ins_kenmerk_key k_new"
                            + "  FROM ins_srtkenmerk t"
                            + "     , ins_kenmerk k_old"
                            + "     , ins_srtdeel s"
                            + "     , ins_srtgroep g"
                            + " WHERE t.ins_srtkenmerk_key = k_old.ins_srtkenmerk_key"
                            + "   AND g.ins_srtgroep_key = s.ins_srtgroep_key"
                            + "   AND (  (   k_old.ins_srtinstallatie_key = s.ins_srtdeel_key"
                            + "          AND k_old.ins_kenmerk_niveau = 'S'"
                            + "          )"
                            + "       OR (   k_old.ins_srtinstallatie_key = s.ins_srtgroep_key"
                            + "          AND k_old.ins_kenmerk_niveau = 'G'"
                            + "          )"
                            + "       OR (   k_old.ins_srtinstallatie_key = g.ins_discipline_key"
                            + "          AND k_old.ins_kenmerk_niveau = 'D'"
                            + "          )"
                            + "       )"
                            + "   AND t.ins_srtkenmerk_kenmerktype IN ('F', 'E', 'M')"
                            + "   AND t.ins_srtkenmerk_verwijder IS NULL"
                            + "   AND k_old.ins_kenmerk_verwijder IS NULL"
                            + "   AND s.ins_srtdeel_key = " + params.sort;
                //
                CopyFlexFolders("INS", "I", params.copy_key, "I", ins_key, flexsql);
             }

             return flextrack;
           },

       isSleCil:
           // Niveau kan de volgende waarden hebben:
           // null  : ins_deel (niet meegegeven)
           // 'S'   : ins_srtdeel
           // 'G'   : ins_srtgroup (Not used yet)
           // 'D'   : ins_discipline
           function(key, niveau)
           { // Is de key een ins_deel_key of ins_srtdeel_key vsleutel of een cilinder
             var isSC;
             switch (niveau)
             {
               case "S": // ins_srtdeel
                         var sql = "SELECT sd.ins_srtgroep_key"
                                 + "  FROM ins_srtdeel sd"
                                 + " WHERE sd.ins_srtdeel_key = " + key;
                         break;
               case "G": // ins_srtgroep
                         var sql = "SELECT sg.ins_srtgroep_key"
                                 + "  FROM ins_srtgroep sg"
                                 + " WHERE sg.ins_srtgroep_key = " + key;
                         break;
               case "D": // ins_discipline
                        var sql = "SELECT sg.ins_srtgroep_key"
                                + "  FROM ins_srtgroep sg"
                                + " WHERE sg.ins_discipline_key = " + key;
                             break;
               default: // ins_deel
                        var sql = "SELECT sd.ins_srtgroep_key"
                                + "  FROM ins_deel d"
                                + "     , ins_srtdeel sd"
                                + " WHERE d.ins_srtdeel_key = sd.ins_srtdeel_key"
                                + "   AND d.ins_deel_key = " + key;
             }
             var oRs = Oracle.Execute(sql);
             var groep_key = oRs("ins_srtgroep_key").Value;
             oRs.Close();
             return (groep_key == S("sle_ins_srt_groep_key") || groep_key == S("cil_ins_srt_groep_key"));
           },

       //PF: idee om dit te versnellen door voorkennis te vergaren. De selecties zijn erg zwaar
       // eerste stap: in singlerecordmode zo weinig mogelijk query doen.
       // Bepaalt of we op één object schrijfrechten hebben
       // return True als het mag, false als het niet mag
       // Pas op: parameter alg_key kan ook prs_perslid of afdeling zijn afhankelijk van bind!!
       checkAutSQL:
           function (pUser_key, bind, alg_key, disc_key)
           {
               // Helaas, we moeten 'ingewikkeld' gaan controleren
               // We weten ondertussen al de fac_gebruiker_alg_level_write dus het volgende kan
               // heel efficient.....
               // Alle ruimtes op maximaal afstand 'alg_level' van *mij*
               var fac_v_my_disc_onrgoed_write = ""
                    + "SELECT a.alg_ruimte_key"
                    + "  FROM alg_v_onrgoed_familie a,"
                    + "       alg_v_onrgoed_familie aa,"
                    + "       alg_v_my_room mr"
                    + " WHERE mr.alg_ruimte_key = aa.alg_ruimte_key"
                    + "   AND mr.prs_perslid_key = " + pUser_key
                    + "   AND a.alg_onrgoed_elder_key = aa.alg_onrgoed_elder_key"
                    + "   AND aa.niveau = a.niveau" // Noodzakelijk want ALG_LOCATIE heeft eigen sequence
                    + "   AND aa.niveau >= " + alg_level

               // Alle afdelingen op maximaal afstand 'alg_level' van *mij*
               var fac_v_my_disc_afdelingen_write = ""
                    +   "SELECT a.prs_afdeling_key "
                    + "     FROM prs_v_afdeling_familie a, "
                    + "          prs_v_afdeling_familie aa "
                    + "    WHERE aa.prs_afdeling_key = " + user.prs_afdeling_key()
                    + "      AND a.prs_afdeling_elder_key = aa.prs_afdeling_elder_key "
                    + "      AND aa.niveau = a.niveau "
                    + "      AND aa.niveau >= " + prs_level

               switch (bind)
               {
                 case 'R':
                 case 'W':
                 case 'T':
                   if (alg_level == 9)  return false; // Zeker niet op basis van alg_scope
                   if (alg_level == -1) return true; // Zeker wel op basis van alg_scope
                   if (bind == 'T') // Speciaal geval voor terreinsectoren
                   {
                       if (alg_level > 2)  return false; // Zeker niet op basis van alg_scope
                       rsql = " SELECT 1"
                           + "   FROM alg_v_my_location avml, alg_terreinsector ats"
                           + "  WHERE avml.alg_locatie_key = ats.alg_locatie_key"
                           + "   AND avml.prs_perslid_key = " + pUser_key
                           + "   AND ats.alg_terreinsector_key = " + alg_key
                   }
                   else
                       rsql = " SELECT 1"   // plaatsgebonden en gebruiker heeft een plaats (werkplek)
                           + "   FROM ("+fac_v_my_disc_onrgoed_write+") oga"
                           + "  WHERE oga.alg_ruimte_key = " + alg_key
                       break;

                 case 'P':
                   if (prs_level == 9)  return false; // Zeker niet op basis van prs_scope
                   if (prs_level == -1) return true; // Zeker wel op basis van prs_scope
                    rsql= " SELECT 2"    // persoonsgebonden
                       + "   FROM ("+fac_v_my_disc_afdelingen_write+") aa, prs_perslid p"
                       + "  WHERE p.prs_perslid_key = " + alg_key
                       + "    AND aa.prs_afdeling_key = p.prs_afdeling_key"
                       + "    AND rownum=1";
                       break;

                 case 'A':
                   if (prs_level == 9)  return false; // Zeker niet op basis van prs_scope
                   if (prs_level == -1) return true; // Zeker wel op basis van prs_scope
                   rsql= " SELECT 3"   // afdelingsgebonden
                       + "   FROM ("+fac_v_my_disc_afdelingen_write+") aa"
                       + "  WHERE aa.prs_afdeling_key = " + alg_key
                       + "    AND rownum=1";
                       break;
               }
               return !(Oracle.Execute(rsql).eof);
           },

       // Check de autorisatie van alle objecten. We eisen overal schrijfrechten op
       // We testen per unieke ins_alg_ruimte_type, ins_alg_ruimte_key, ins_discipline_key
       // waardoor er een sterke performanceverbetering is als bijvoorbeeld
       // alle objecten van dezelfde discipline zijn en van dezelfde ruimte/persoon/afdeling
       checkAutSQLMultiple:
           function (autfunction)
           {
               var sql, oRs;
               sql = "SELECT ins_alg_ruimte_type, ins_alg_ruimte_key, ins_discipline_key "
                   + "  FROM ins_v_deelenonderdeel WHERE ins_deel_key IN (" + inskeystring + ")"
                   + " GROUP BY ins_alg_ruimte_type, ins_alg_ruimte_key, ins_discipline_key";
               oRs = Oracle.Execute( sql );

               while (mayEdit && !oRs.Eof)
               {
                   var bind = oRs("ins_alg_ruimte_type").Value;
                   var alg_key = oRs("ins_alg_ruimte_key").Value; // Kan ook prs_perslid of afdeling zijn!!
                   var disc_key = oRs("ins_discipline_key").Value;

                   mayEdit = ins.checkAutSQL(user_key, bind, alg_key, disc_key);

                   oRs.moveNext();
               }
               return mayEdit;
           },

        ins_disciplineinfo:
           function _ins_disciplineinfo(ins_discipline_key) {
               var sql = "SELECT ins_discipline_key"
                       + "     , (SELECT COUNT(*)"
                       + "          FROM fac_faq ff"
                       + "             , mld_stdmeldingfaq sf"
                       + "         WHERE ff.fac_faq_key = sf.fac_faq_key"
                       + "           AND sf.ins_discipline_key = md.ins_discipline_key"
                       + "           AND BITAND (fac_faq_level, 1) = 1"   // Voor fe
                       + "           AND fac_faq_datum < SYSDATE"
                       + "           AND (fac_faq_lang = " + safe.quoted_sql(user_lang) + " OR fac_faq_lang IS NULL)) aantal_fefaq"
                       + "     , (SELECT COUNT(*)"
                       + "          FROM fac_faq ff"
                       + "             , mld_stdmeldingfaq sf"
                       + "         WHERE ff.fac_faq_key = sf.fac_faq_key"
                       + "           and sf.ins_discipline_key = md.ins_discipline_key"
                       + "           AND BITAND (fac_faq_level, 2) = 2"   // Voor fo
                       + "           AND fac_faq_datum < SYSDATE"
                       + "           AND (fac_faq_lang = " + safe.quoted_sql(user_lang) + " OR fac_faq_lang IS NULL)) aantal_fofaq"
                       + "     , ins_discipline_module"
                       + "     , ins_discipline_omschrijving"
                       + "     , ins_discipline_min_level"
                       + "     , ins_srtdiscipline_key"
                       + "     , ins_discipline_kpnverplicht"
                       + "     , prs_kostensoort_key"
                       + "     , ins_discipline_email"
                       + "     , ins_discipline_btw"
                       + "     , ins_discipline_opmerking"
                       + "     , ins_discipline_ktopercentage"
                       + "     , ins_discipline_ktodrempel"
                       + "     , ins_discipline_volgnr"
                       + "  FROM mld_discipline md"
                       + " WHERE md.ins_discipline_key = " + ins_discipline_key;
               var oRs = Oracle.Execute(sql);

               var result = { ins_discipline_key: oRs("ins_discipline_key").Value,
                              aantal_fefaq: oRs("aantal_fefaq").Value,
                              aantal_fofaq: oRs("aantal_fofaq").Value,
                              module: oRs("ins_discipline_module").Value,
                              omschrijving: oRs("ins_discipline_omschrijving").Value,
                              min_level: oRs("ins_discipline_min_level").Value,
                              ins_srtdiscipline_key: oRs("ins_srtdiscipline_key").Value,
                              kpnverplicht: oRs("ins_discipline_kpnverplicht").Value,
                              prs_kostensoort_key: oRs("prs_kostensoort_key").Value,
                              email: oRs("ins_discipline_email").Value,
                              btw: oRs("ins_discipline_btw").Value,
                              opmerking: oRs("ins_discipline_opmerking").Value,
                              ktopercentage: oRs("ins_discipline_ktopercentage").Value,
                              ktodrempel: oRs("ins_discipline_ktodrempel").Value,
                              volgnr: oRs("ins_discipline_volgnr").Value
                            };

                if (result.aantal_fefaq > 0)
                {
                    result.canFAQUSEread = user.checkAutorisation("WEB_FAQUSE", true)!=null;
                }
                if (result.aantal_fofaq > 0)
                {
                    result.canFAQFOFread = user.checkAutorisation("WEB_FAQFOF", true)!=null;
                }
               oRs.Close();

               return result;
        },

        photoinfo: function _photoinfo(pins_deel_key, pins_deel_image)
        {
            var props = flexProps("INSPHD", pins_deel_key, null, null, { getFiles: true, getFile: pins_deel_image });
            var result;
            if (props.files.length > 0)
            {
                result = { photomap: props.RelativePath
                         , photopath: props.RelativePath + props.files[0].name
                         , photopaththumb: props.RelativePath + "thumb/" + props.files[0].name
                         , isDefault: false
                         };
            }
            else
            {
                result = { photoicon: I("fa-camera-retro fa-4x")
                         , isDefault: true
                         };
            }
            return result;
        },

       func_enabled_deel: // Wat mag ik zoal op dit specifieke object?
                          // autodetect sleutels
           function _func_enabled_deel(pins_deel_key, params)
           {
               var isql = "SELECT d.ins_discipline_key"
                        + "     , d.ins_alg_ruimte_key"
                        + "     , d.ins_alg_ruimte_type"
                        + "     , d.ins_alg_ruimte_key_org"
                        + "     , d.ins_alg_ruimte_type_org"
                        + "     , isd.ins_srtgroep_key"
                        + "     , d.ins_deel_actief"
                        + "     , d.prs_perslid_key_beh"
                        + "     , isd.ins_srtdeel_uitleenbaar"
                        + "  FROM ins_v_deelenonderdeel d"
                        + "     , ins_srtdeel isd"
                        + " WHERE d.ins_srtdeel_key = isd.ins_srtdeel_key"
                        + "   AND d.ins_deel_key = " + pins_deel_key;
               var ioRs = Oracle.Execute(isql);
               var srtgroep_key = ioRs("ins_srtgroep_key").Value;
               var actief = ioRs("ins_deel_actief").Value == 1;
               var beheerder_key = ioRs("prs_perslid_key_beh").value;
               var objectbeheerder = S("ins_can_edit_own_objects") == 1 && (beheerder_key == user_key);
               var objectuitleenbaar = ioRs("ins_srtdeel_uitleenbaar").Value == 1;

               var fronto = params && params.urole? params.urole == "fo" : false;
               var isSleCil = (srtgroep_key == S("sle_ins_srt_groep_key") || srtgroep_key == S("cil_ins_srt_groep_key"));
               if (isSleCil)
               {
                 var alg_key = ioRs("ins_alg_ruimte_key_org").Value? ioRs("ins_alg_ruimte_key_org").Value : ioRs("ins_alg_ruimte_key").Value;
                 var iresult = user.func_enabled("SLE",
                                                 null, // ins_discipline doet niet ter zake
                                                 alg_key, // alg_key
                                                 null); // hier zou alleen een prs_key in mogen, we testen zo afzonderlijk
                 var readslebof = iresult.canRead("WEB_SLEBOF");
                 iresult.readslebof = readslebof;
                 iresult.canRead = readslebof; // Lezen
                 iresult.canReadAny = iresult.canRead;

                 var writeslebof = iresult.canWrite("WEB_SLEBOF");
                 var writeslefof = iresult.canWrite("WEB_SLEFOF");
                 iresult.canChange = readslebof; // Wijzigen
                 iresult.writeslebof = writeslebof;
                 iresult.writeslefof = writeslefof;
                 iresult.canDelete = writeslebof; // Verwijderen
                 iresult.canChange = writeslebof; // Wijzigen
                 iresult.canReadNotes = iresult.canChange; // Notities zien.
                 iresult.canWriteNotes = iresult.canChange; // Notities aanmaken/wijzigen.
                 iresult.canChangeOwn = (iresult.readuse || iresult.readman) && objectbeheerder;
                 iresult.canChangeAlg = (iresult.canChange && !fronto) || iresult.canChangeOwn; // Wijzigen algemene gegevens
                 iresult.canCopy = writeslebof; // Kopiëren
                 iresult.isSleCil = true;
               }
               else // Gewone objecten
               {
                 var iresult = ins.func_enabled_scope(ioRs("ins_discipline_key").Value,
                                                      ioRs("ins_alg_ruimte_type").Value,
                                                      ioRs("ins_alg_ruimte_key").Value,
                                                      params);
                 if (!iresult)
                    return { canReadAny: false }; // Aanroeper moet hier (of andere canFunctie) op controleren
                                                  // Vanuit PDA wordt dan eventueel met melding (of reservering) op dit object
                                                  // Daarom niet al te hard er uit klappen hier.
                 iresult.canReadAny = true;
                 iresult.canChangeOwn = (iresult.readuse || iresult.readman) && objectbeheerder;
                 iresult.canChange = iresult.canChange || iresult.canChangeOwn;
                 iresult.canReadHistory = iresult.canWrite("WEB_INSMAN"); // Historie zien.
                 iresult.canReadNotes = iresult.canChange || (objectuitleenbaar && iresult.writefof); // Notities zien.
                 iresult.canWriteNotes = iresult.canReadNotes; // Notities aanmaken/wijzigen.
                 iresult.canChangeAlg = iresult.canChangeAlg || iresult.canChangeOwn;
                 iresult.writeslebof = false;
                 iresult.writeslefof = false;

                 if (params && params.srtcont_key > 0)
                 {
                   // Als scenario niet is meegegeven dan default 1 nemen.
                   params.scen_key = params.scen_key || 1;
                   var sql = "SELECT idsc.ins_deelsrtcontrole_key"
                           + "  FROM ins_deelsrtcontrole idsc"
                           + " WHERE idsc.ins_deel_key = " + pins_deel_key
                           + "   AND idsc.ins_srtcontrole_key = " + params.srtcont_key
                           + "   AND idsc.ins_deelsrtcontrole_status IN (6)"
                           + "   AND idsc.ins_scenario_key = 1";
                   var oRs = Oracle.Execute(sql);
                   var hasInspect = !oRs.eof;
                   oRs.Close();

                   var sql = "SELECT xcp.ins_srtcontrole_periode"
                           + "     , xcp.ctr_discipline_key"
                           + "     , xcp.ctr_ismjob"
                           + "  FROM ins_v_defined_inspect_xcp xcp"
                           + " WHERE xcp.ins_srtcontrole_key = " + params.srtcont_key
                           + "   AND xcp.ins_deel_key = " + pins_deel_key
                           + "   AND xcp.ins_scenario_key = 1"
                   var oRs = Oracle.Execute(sql);
                   var periode = oRs("ins_srtcontrole_periode").Value;
                   var ctr_discipline_key = oRs("ctr_discipline_key").Value;
                   var ctr_ismjob = oRs("ctr_ismjob").Value == 1;
                   oRs.Close();

                   var ins_deelsrtcontrole_status = -1;
                   var canChangeCycle = true; // Als de periode groter als 0 is, wordt er wel gekeken of er een lopende taak is. Als de periode 0 is, dan is er geen lopdende taak.
                   var vervaldatum = null;
                   var isc_options = 0;
                   var vervallen = false;
                   var canDoNextAction = false;
                   var isFreezeYear = false;
                   if (periode > 0)
                   {
                     var mjb_freeze_or_sys_year = Math.max(S("mjb_freeze_year"), new Date().getFullYear());
                     var mjb_start_year = S("mjb_start_year");
                     // Voor het bepalen van de autorisatie voor inspecties, moet gekeken worden naar de gegevens van de Active Situatie (AS).
                     var sql = "SELECT insp.ins_deelsrtcontrole_key"
                             + "     , insp.ins_deelsrtcontrole_status"
                             + "     , CASE"
                             + "       WHEN lastactivectrstatus IN (2, 3, 5)"
                             + "       THEN 0"
                             + "       ELSE 1"
                             + "       END canChangeCycle"
                             + "     , insp.vervaldatum"
                             + "     , insp.isc_mode"
                             + "     , options"
                             + "     , freezedate_year"
                             // Moment mode(0):   Inspectie kan pas geaccordeerd(gestart(2)), Gereed gemeld/Afgemeld(5) of voltooid/afgerond(6) worden:
                             //                   1) op of na de geplande inspectiedatum.
                             //                   2) als er nog nooit is geinspecteerd en er nog geen inspectie ingepland is.
                             //                   3) als de inspectie gestart of gereed gemeld is, want anders had de inspectie nooit begonnen mogen worden.
                             // Interval mode(1): Inspectie kan pas geaccordeerd(gestart(2)), Gereed gemeld/Afgemeld(5) of voltooid/afgerond(6) worden:
                             //                   1) als het de eerste inspectie is.
                             //                   2) a) inspectie is de laatste:     als de voorlaatste inspectie is voltooid/afgerond(6). Deze mag namelijk niet geaccordeerd(gestart(2)) zijn.
                             //                      b) inspectie is de voorlaatste: als deze inspectie gestart(2) of Gereed gemeld/Afgemeld(5) is. De laatste inspectie is dan ingepland(0).
                             // Is in de moment modus de invoer na het volgende berekende inspectietijdstip? Voor interval modus is dit altijd het geval.
                             // Als er nog nooit is geinspecteerd en er is er nog geen ingepland dan is het ook ok.
                             // Als de inspectie gestart of gereed gemeld is dan is het ook ok, want anders had de inspectie nooit begonnen mogen worden.
                             + "     , CASE"
                             // Interval mode(1).
                             + "       WHEN insp.isc_mode = 1"
                             + "       THEN"
                             + "            CASE"
                             + "            WHEN insp.penultimate_dsc_key IS NULL"
                             + "            THEN 1"
                             + "            WHEN insp.ins_deelsrtcontrole_key = insp.penultimate_dsc_key AND"
                             + "                 (insp.ins_deelsrtcontrole_status IN (2, 3, 5))"
                             + "            THEN 1"
                             + "            WHEN (SELECT id2.ins_deelsrtcontrole_status"
                             + "                    FROM ins_deelsrtcontrole id2"
                             + "                   WHERE id2.ins_deelsrtcontrole_key = insp.penultimate_dsc_key) = 6"
                             + "            THEN 1"
                             + "            ELSE 0"
                             + "            END"
                             // Moment mode(0).
                             + "       WHEN (insp.ins_deelsrtcontrole_status IS NULL AND 1 = " + (hasInspect? 0 : 1) + ") OR" // Er is nog nooit geinspecteerd en er is er geen ingepland.
                             + "            insp.ins_deelsrtcontrole_status IN (2, 3, 5)"
                             + "       THEN  1"
                             + "       WHEN insp.ins_deelsrtcontrole_status = 6 AND"  // insp.isc_mode = 0 want anders is de vorige when geldig.
                             + "            SYSDATE >= CASE insp.eenheid"
                             + "                       WHEN 0"
                             + "                       THEN TRUNC (insp.inspectie_next, 'HH')"
                             + "                       ELSE TRUNC (insp.inspectie_next, 'DD')"
                             + "                       END"
                             + "       THEN 1"
                             + "       WHEN insp.ins_deelsrtcontrole_status = 0 AND"
                             + "            SYSDATE >= COALESCE (CASE insp.eenheid"  // insp.isc_mode = 0 want anders is de vorige when geldig.
                             + "                                 WHEN 0"
                             + "                                 THEN TRUNC (insp.plandatum, 'HH')"
                             + "                                 ELSE TRUNC (insp.plandatum, 'DD') END"
                             + "                               , CASE insp.eenheid"
                             + "                                 WHEN 0"
                             + "                                 THEN TRUNC (insp.inspectie_next, 'HH')"
                             + "                                 ELSE TRUNC (insp.inspectie_next, 'DD')"
                             + "                                 END)"
                             + "       THEN 1"
                             + "       ELSE 0"
                             + "       END canDoNextAction"
                             // Bepaling in welk jaar er een inspectie is gepland.
                             // 1) In het jaar dat er nog een geaccordeerde/bevroren(2) inspectie actief is.
                             // 2) In het jaar van de plandatum.
                             // 3) Er is nog geen inspectie geweest en de startdatum is ingevuld.
                             //    Er geldt dan het volgende:
                             //    Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
                             //    Voor Vervanging(2) of Certificering(3):
                             //    a) Als registratiedatum het verst in de toekomst ligt: Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
                             //    b) Als de startdatum het verst in de toekomst ligt: Eerste inspectie tonen op de startdatum.
                             //    De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
                             // 4) Er is nog geen inspectie geweest en alleen de aanmaakdatum/Registratiedatum ligt in het huidige jaar of in de toekomst.
                             //    Voor Controle(1):
                             //    a) Als registratiedatum < freeze jaar dan eerste inspectie tonen in het freeze jaar
                             //    b) Anders inspectie tonen in het registratiejaar.
                             //    Voor Vervanging(2) of Certificering(3):
                             //    a) Als (registratiedatum + periode) < freeze jaar dan eerste inspectie tonen in het freeze jaar
                             //    b) Anders inspectie tonen in het (registratiejaar + periode)
                             // 5) Er is nog geen inspectie geweest en de startdatum is niet ingevuld en registratiedatum ligt in het verleden. Berekenen jaar.
                             //    a) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Controle(1).
                             //       Volgende inspectie is in het freeze jaar.
                             //    b) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Vervanging(2) of Certificering(3).
                             //       Nextdate is na het freeze jaar?
                             //       Ja)  Vorige inspectie ligt na het start jaar en ligt niet in het aanmaak jaar?
                             //            Ja)  Volgende inspectie is in het freeze jaar.
                             //            Nee) Volgende inspectie is het jaar van de nextdate.
                             //       Nee) De laatst ingeplande inspectie (nextdate) is na of in het start jaar?
                             //            Ja)  Volgende inspectie is in het freeze jaar.
                             //            Nee) Volgende inspectie is in het jaar "nextdatum + periode".
                             //    c) Laatste inspectie is niet NULL. Er is al 1 of meerdere keren geinspecteerd.
                             //       Was de laatste inspectie niet succesvol
                             //       Niet succesvol: De volgende inspectie dan in het freeze jaar weer uitvoeren.
                             //       Succesvol:      Ligt de laatst ingeplande inspectie (nextdate) na dit jaar?
                             //                         Ja)  Volgende inspectie is het jaar van de nextdate (in de toekomst).
                             //                         Nee) Volgende inspectie is in het freeze jaar.
                             + "     , CASE"
                             + "       WHEN"
                             + "         EXTRACT(YEAR FROM "
                             + "           COALESCE(CASE"                   // Taak is geaccordeerd (gefreezed). Freeze jaar is het huidige (vervangings)jaar.
                             + "                    WHEN insp.ins_deelsrtcontrole_status IN (2, 3)"
                             + "                    THEN insp.ins_deelsrtcontrole_freezedate"
                             + "                    ELSE NULL"
                             + "                    END"
                             + "                  , CASE"
                             + "                    WHEN insp.ins_deelsrtcontrole_status IN (0, 2, 3)"
                             + "                    THEN" // 2) Plandatum.
                             + "                      CASE"
                             + "                      WHEN insp.plandatum IS NOT NULL"
                             + "                      THEN"
                             + "                        CASE"
                             + "                        WHEN EXTRACT(YEAR FROM insp.plandatum) < " + mjb_freeze_or_sys_year
                             + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                             + "                        ELSE insp.plandatum"
                             + "                        END"
                             + "                      ELSE NULL"
                             + "                      END"
                             + "                    ELSE NULL"
                             + "                    END"
                             + "                  , CASE"
                             + "                    WHEN insp.laatste IS NULL AND"
                             + "                         insp.ins_srtcontroledl_xcp_startdat IS NOT NULL"
                             + "                    THEN" // 3) Startdatum is ingevuld en ligt in het verleden of de toekomst en er is nog geen inspectie geweest.
                             + "                      CASE"
                             + "                      WHEN EXTRACT(YEAR FROM insp.ins_srtcontroledl_xcp_startdat) >= EXTRACT(YEAR FROM insp.ins_deel_aanmaak)"
                             + "                      THEN" // 3a) Startdatum op of na aanmaakdatum/registratiedatum.
                             + "                        CASE"
                             + "                        WHEN EXTRACT(YEAR FROM insp.ins_srtcontroledl_xcp_startdat) < " + mjb_freeze_or_sys_year
                             + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                             + "                        ELSE insp.ins_srtcontroledl_xcp_startdat"
                             + "                        END"
                             + "                      ELSE" // 3b) Aanmaakdatum/Registratiedatum is na de startdatum.
                             + "                        CASE"
                             + "                        WHEN insp.ctr_controle_type = 1"  // Controle(1).
                             + "                        THEN"
                             + "                          CASE"
                             + "                          WHEN EXTRACT(YEAR FROM insp.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                             + "                          THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                             + "                          ELSE insp.ins_deel_aanmaak" // Registratiedatum.
                             + "                          END"
                             + "                        ELSE"  // Vervanging(2), Certificering(3).
                             + "                          CASE"
                             + "                          WHEN EXTRACT(YEAR FROM ADD_MONTHS(insp.ins_deel_aanmaak, 12 * insp.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                             + "                          THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                             + "                          ELSE ADD_MONTHS(insp.ins_deel_aanmaak, 12 * insp.ins_srtcontrole_periode)" // 1 periode na registratiedatum.
                             + "                          END"
                             + "                        END"
                             + "                      END"
                             + "                    ELSE NULL"
                             + "                    END"
                             + "                  , CASE"
                             + "                    WHEN insp.laatste IS NULL AND"
                             + "                         EXTRACT(YEAR FROM insp.ins_deel_aanmaak) >= EXTRACT(YEAR FROM SYSDATE)" // Alleen de aanmaakdatum/registratiedatum is ingevuld.
                             + "                    THEN" // 4) Aanmaakdatum/Registratiedatum is ingevuld en ligt in de toekomst en er is nog geen inspectie geweest.
                             + "                      CASE"
                             + "                      WHEN insp.ctr_controle_type = 1"  // Controle(1).
                             + "                      THEN"
                             + "                        CASE"
                             + "                        WHEN EXTRACT( YEAR FROM insp.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                             + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                             + "                        ELSE insp.ins_deel_aanmaak"
                             + "                        END"
                             + "                      ELSE"  // Vervanging(2), Certificering(3).
                             + "                        CASE"
                             + "                        WHEN EXTRACT( YEAR FROM ADD_MONTHS(insp.ins_deel_aanmaak, 12 * insp.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                             + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                             + "                        ELSE ADD_MONTHS(insp.ins_deel_aanmaak, 12 * insp.ins_srtcontrole_periode)"
                             + "                        END"
                             + "                      END"
                             + "                    ELSE NULL"
                             + "                    END"
                             + "                  , CASE" // 5) Berekenen jaar.
                             + "                    WHEN insp.laatste IS NULL AND insp.ctr_controle_type = 1"  // Controle(1).
                             + "                    THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')" // 5a)
                             + "                    WHEN insp.laatste IS NULL AND insp.ctr_controle_type != 1" // Vervanging(2), Certificering(3).
                             + "                    THEN"                   // 5b) Er is nog geen inspectie geweest
                             + "                      CASE"
                             + "                      WHEN EXTRACT(YEAR FROM insp.inspectie_next0) > " + mjb_freeze_or_sys_year
                             + "                      THEN"                 // Nextdate is na de freeze datum.
                             + "                        CASE"
                             + "                        WHEN EXTRACT(YEAR FROM ADD_MONTHS(insp.inspectie_next0, -1 * 12 * insp.ins_srtcontrole_periode)) >= " + mjb_start_year + " AND"
                             + "                             EXTRACT(YEAR FROM ADD_MONTHS(insp.inspectie_next0, -1 * 12 * insp.ins_srtcontrole_periode)) != EXTRACT(YEAR FROM insp.ins_deel_aanmaak)"
                             + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"     // Vorige inspectie ligt tussen start en freeze jaar (Nu ligt er ook tussen).
                             + "                        ELSE insp.inspectie_next0"
                             + "                        END"
                             + "                      ELSE"                 // Nextdate is voor of in het freeze jaar.
                             + "                        CASE"
                             + "                        WHEN EXTRACT(YEAR FROM insp.inspectie_next0) >= " + mjb_start_year
                             + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"                           // Nextdate tussen start en freeze jaar.
                             + "                        ELSE ADD_MONTHS(insp.inspectie_next0, 12 * insp.ins_srtcontrole_periode)"  // Nextdate voor het start jaar.
                             + "                        END"
                             + "                      END"
                             + "                    ELSE"                   // 5c) Laatste IS NOT NULL. Er is al een inspectie geweest.
                             + "                      CASE"
                             + "                      WHEN isSuccess = 0"                                    // De laatste inspectie was niet succesvol,
                             + "                      THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"       // De volgende inspectie dan in het freeze jaar weer uitvoeren.
                             + "                      WHEN EXTRACT(YEAR FROM insp.inspectie_next0) > EXTRACT(YEAR FROM SYSDATE)"
                             + "                      THEN insp.inspectie_next0"                             // Volgende inspectie is in de toekomst.
                                                                                                             // Geaccordeerde laatste inspectie wordt in het begin al afgevangen.
                                                                                                             // en niet hier zoals bij org_nextdate in functie getmjblist_sql.
                             + "                      ELSE TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"       // Laatst ingeplande inspectie is nog steeds niet uitgevoerd. Dus opnieuw in het freeze jaar tonen zodat deze daar gefreezed kan worden.
                             + "                      END"
                             + "                    END)) = " + mjb_freeze_or_sys_year
                             + "       THEN 1"
                             + "       ELSE 0"
                             + "       END isFreezeYear"
                             + "  FROM ("
                             // De view ins_v_defined_inspect_xcp levert de volgende regels op
                             // Alle Active Situatie (AS) soort controle's die geen uitzondering (XCP) record hebben maar wel een scenario.
                             // en
                             // Alle Active Situatie (AS) soort controle's die:
                             //   a) geen uitzondering (XCP) record hebben en geen scenario.
                             //   b) een uitzondering (XCP) record hebben.
                             // Hier niet van belang: Alle soort controles van de scenario's (AND xcp.ins_scenario_key = 1).
                             + "        SELECT idsc.ins_deelsrtcontrole_key"
                             + "             , idsc.ins_deelsrtcontrole_datum"
                             + "             , idsc.ins_deelsrtcontrole_status"
                             + "             , COALESCE((SELECT MAX(id2.ins_deelsrtcontrole_status)"
                             + "                           FROM ins_deelsrtcontrole id2"
                             + "                          WHERE id2.ins_deel_key = idsc.ins_deel_key"
                             + "                            AND id2.ins_srtcontrole_key = idsc.ins_srtcontrole_key"
                             + "                            AND id2.ins_scenario_key = 1"
                             + "                            AND id2.ins_deelsrtcontrole_status IN (2, 3, 5))"
                             + "                      , (SELECT id.ins_deelsrtcontrole_status"
                             + "                           FROM ins_deelsrtcontrole id"
                             + "                          WHERE id.ins_deelsrtcontrole_key = (SELECT MAX(id2.ins_deelsrtcontrole_key)"
                             + "                                                                FROM ins_deelsrtcontrole id2"
                             + "                                                               WHERE id2.ins_deel_key = idsc.ins_deel_key"
                             + "                                                                 AND id2.ins_srtcontrole_key = idsc.ins_srtcontrole_key"
                             + "                                                                 AND id2.ins_scenario_key = 1))) lastactivectrstatus"
                             + "             , idsc.ins_deel_key"
                             + "             , idsc.ins_srtcontrole_key"
                             + "             , idsc.ins_scenario_key"
                             + "             , xcp.ins_srtcontrole_eind vervaldatum"
                             + "             , xcp.ins_srtcontrole_mode isc_mode"
                             + "             , xcp.ins_srtcontrole_options options"
                             + "             , xcp.ins_srtcontrole_eenheid eenheid"
                             + "             , xcp.ins_srtcontrole_periode"
                             + "             , xcp.ins_deel_aanmaak"
                             + "             , xcp.ctr_controle_type"
                             + "             , idsc.ins_deelsrtcontrole_plandatum plandatum"
                             + "             , ins_srtcontroledl_xcp_startdat"
                             + "             , ins_srtcontroledl_xcp_prio"
                             + "             , CASE"
                             + "               WHEN 1 = " + (hasInspect? 0 : 1) // lastinspect IS NULL
                             + "               THEN (SELECT d.ins_deel_aanmaak FROM ins_deel d WHERE d.ins_deel_key = " + pins_deel_key + ")"
                             + "               WHEN idsc.ins_deelsrtcontrole_status IN (0, 2, 3)"
                             + "               THEN ins_deelsrtcontrole_datum_org"
                             + "               ELSE fac.nextcyclusdate(CASE"
                             + "                                       WHEN xcp.ins_srtcontrole_mode = 0"
                             + "                                       THEN idsc.ins_deelsrtcontrole_datum_org"  // Moment modus (0). Uitgaan van eigenlijke/orginele inspectiedatum.
                             + "                                       ELSE idsc.ins_deelsrtcontrole_datum"      // Interval modus (1). Uitgaan van werkelijke inspectiedatum.
                             + "                                       END"
                             + "                                     , xcp.ins_srtcontrole_mode"
                             + "                                     , xcp.ins_srtcontrole_eenheid"
                             + "                                     , xcp.ins_srtcontrole_periode"
                             + "                                     , xcp.ins_srtcontrole_bits"
                             + "                                     , 1"
                             + "                                     , xcp.ctr_ismjob)"
                             + "               END inspectie_next"
                             + "             , ins.nextcyclusdate(xcp.ins_deel_key, xcp.ins_srtcontrole_key, 1, 0) inspectie_next0"
                             + "             , (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                             + "                  FROM ins_deelsrtcontrole idsc2"
                             + "                 WHERE idsc2.ins_deel_key = " + pins_deel_key
                             + "                   AND idsc2.ins_srtcontrole_key = " + params.srtcont_key
                             + "                   AND idsc2.ins_scenario_key = 1) laatste"
                             + "             , (SELECT ins_controlemode_success"
                             + "                  FROM ins_controlemode"
                             + "                 WHERE ins_controlemode_key = idsc.ins_controlemode_key) isSuccess"
                             + "             , idsc.ins_deelsrtcontrole_freezedate"
                             + "             , EXTRACT(YEAR FROM idsc.ins_deelsrtcontrole_freezedate) freezedate_year"
                             + "             , (SELECT MAX(ins_deelsrtcontrole_key)"
                             + "                  FROM ins_deelsrtcontrole id2"
                             + "                 WHERE id2.ins_deel_key = xcp.ins_deel_key"
                             + "                   AND id2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                             + "                   AND id2.ins_scenario_key = 1"
                             + "                   AND id2.ins_deelsrtcontrole_key NOT IN (SELECT MAX(idsc2.ins_deelsrtcontrole_key)" // NOT IN (laatste). Laatste is niet altijd de insp.ins_deelsrtcontrole_key.
                             + "                                                             FROM ins_deelsrtcontrole idsc2"
                             + "                                                            WHERE idsc2.ins_deel_key = " + pins_deel_key
                             + "                                                              AND idsc2.ins_srtcontrole_key = " + params.srtcont_key
                             + "                                                              AND idsc2.ins_scenario_key = 1)) penultimate_dsc_key"
                             + "          FROM ins_deelsrtcontrole idsc"
                             + "             , ins_v_defined_inspect_xcp xcp"
                             + "         WHERE xcp.ins_srtcontrole_key = idsc.ins_srtcontrole_key(+)" // Er kan nog voor de eerste keer geinspecteerd moeten worden.
                             + "           AND xcp.ins_srtcontrole_key = " + params.srtcont_key
                             + "           AND xcp.ins_deel_key = " + pins_deel_key
                             + "           AND idsc.ins_deel_key(+) = " + pins_deel_key
                             + "           AND idsc.ins_scenario_key(+) = " + params.scen_key
                             // Neem voor de rechten de xcp van de Active Situatie (AS). Die bepaalt of de soort controle vervallen is.
                             + "           AND xcp.ins_scenario_key = 1"
                             + (params.deelsrtcont_key > 0
                               ? "         AND idsc.ins_deelsrtcontrole_key = " + params.deelsrtcont_key
                               : "         AND (idsc.ins_deelsrtcontrole_key IS NULL OR"
                                 + "             idsc.ins_deelsrtcontrole_key = (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                 + "                                               FROM ins_deelsrtcontrole idsc2"
                                 + "                                              WHERE idsc2.ins_deel_key = " + pins_deel_key
                                 + "                                                AND idsc2.ins_srtcontrole_key = " + params.srtcont_key
                                 + "                                                AND idsc2.ins_scenario_key = " + params.scen_key
                                 + "                                            ))")
                             + "       ) insp"
                             + " ORDER BY insp.ins_deelsrtcontrole_datum DESC";
                     var oRs = Oracle.Execute(sql);
                     // Waarden moeten aanwezig zijn. Mocht dat niet zo zijn dan is er iets fout.
                     // Als er nog nooit een inspectie is geweest wordt de status -1.
                     // Als de laatste inspectie is afgerond (status is 6) moet er een nieuwe inspectie gestart worden.
                     ins_deelsrtcontrole_status = oRs("ins_deelsrtcontrole_status").Value != null? oRs("ins_deelsrtcontrole_status").Value : -1;
                     canChangeCycle = oRs("canChangeCycle").Value == 1;
                     vervaldatum = oRs("vervaldatum").Value != null? new Date(oRs("vervaldatum").Value) : null;
                     vervallen = vervaldatum != null && vervaldatum < new Date();
                     isc_options = oRs("options").Value;
                     freezedate_year = oRs("freezedate_year").Value;
                     canDoNextAction = oRs("canDoNextAction").Value == 1;
                     isFreezeYear = oRs("isFreezeYear").Value == 1;
                     oRs.Close();
                   }

                   iresult.canDoNextAction = canDoNextAction;

                   // Voor CTR alleen discipline autorisatie met 3D ja/nee en read/write autorisatie (fac_functie_min_level = 3)
                   ctrresult = user.func_enabled("CTR",
                                                 ctr_discipline_key,
                                                 null, // alg_key is nvt
                                                 null, // prs_key in nvt
                                                 false, // pessimist (checkOptimistic)
                                                 true); // nog even optional (isOptional)

                   // Op een scenario kun je geen inspecties doen. Je kunt alleen inplannen en een planning wijzigen. Verder geen inspectie rechten.
                   var isScenario = params.scen_key > 1;

                   iresult.hasCTRUSERead = ctrresult.canRead("WEB_CTRUSE") || objectbeheerder;   // Heb ik lees rechten om periodieke taken te zien in de actuele situatie?
                   iresult.hasCTRUSEWrite = ctrresult.canWrite("WEB_CTRUSE") || objectbeheerder; // Heb ik schrijf rechten om periodieke taken te begroten in de actuele situatie?
                   iresult.hasCTRAFRWrite = ctrresult.canWrite("WEB_CTRAFR") || objectbeheerder; // Heb ik schrijf rechten om periodieke taken te voltooien in de actuele situatie?
                   iresult.hasCTRFOFRead = ctrresult.canRead("WEB_CTRFOF") || objectbeheerder;   // Heb ik lees rechten om periodieke taken te zien in de actuele situatie?
                   iresult.hasCTRFOFWrite = ctrresult.canWrite("WEB_CTRFOF") || objectbeheerder; // Heb ik schrijf rechten om periodieke taken goed te keuren in de actuele situatie?
                   iresult.hasCTRBOFRead = ctrresult.canRead("WEB_CTRBOF") || objectbeheerder;   // Heb ik lees rechten om periodieke taken te zien in de actuele situatie?
                   iresult.hasCTRBOFWrite = ctrresult.canWrite("WEB_CTRBOF") || objectbeheerder; // Heb ik schrijf rechten om periodieke taken uit te voeren in de actuele situatie?
                   iresult.hasCTRSENRead = ctrresult.canRead("WEB_CTRSEN");                      // Heb ik lees rechten om periodieke taken te zien bij scenario's?
                   iresult.hasCTRSENWrite = ctrresult.canWrite("WEB_CTRSEN");                    // Heb ik schrijf rechten om periodieke taken te begroten bij scenario's?

                   iresult.canShowXcp = ((iresult.hasCTRUSERead && !isScenario) ||
                                         (iresult.hasCTRSENRead && isScenario)) &&
                                        (iresult.canRead("WEB_INSMAN") ); // Exceptions (xcp) waarden inspecties/taken bekijken (waarden in ins_srtcontroledl_xcp tabel).
                   iresult.canChangeXcp = ((iresult.hasCTRUSEWrite && !isScenario && iresult.canWrite("WEB_INSMAN")) ||
                                           (iresult.hasCTRSENWrite && isScenario)); // Exceptions (xcp) waarden inspecties/taken wijzigen (waarden in ins_srtcontroledl_xcp tabel).
                   iresult.canChangeCycle = canChangeCycle;

                   // Alleen taken die nog niet aan een scenario zijn toegevoegd kunnen aan een scenario worden toegevoegd.
                   // INSMAN-write mag geen extra voorwaarde zijn, daar kun je (echte) objecten mee aanmaken en verwijderen, en dat staat hier functioneel los van.
                   // Een taak kan niet aan een scenario worden toegevoegd als er in het freeze jaar (2019) een gestarte of gereed gemelde inspectie is.
                   //iresult.canAddToScen = ((iresult.hasCTRUSEWrite || iresult.hasCTRSENWrite) && !isScenario) &&
                   //                       !((ins_deelsrtcontrole_status == 2 || ins_deelsrtcontrole_status == 3 || ins_deelsrtcontrole_status == 5) && isFreezeYear);
                   iresult.canAddToScen = (iresult.hasCTRSENWrite && !isScenario) &&
                                          ((ins_deelsrtcontrole_status != 2 && ins_deelsrtcontrole_status != 3 && ins_deelsrtcontrole_status != 5) || !isFreezeYear);

                   // Een nieuwe inspectie mag pas weer aangemaakt worden als de laatste inspectie Afgerond(6) is.
                   // Als de inspectie vervallen is moet je alleen nog de lopende inspecties (ingepland of later) kunnen gereedmelden en/of afronden,
                   // zodat deze inspectie afgerond kan worden. Nieuwe inspectie kunnen nooit meer beginnen.
                   // Eerste inspectie of verwerkte inspectie kan niet gewijzigd worden.
                   iresult.canMsuEdit = periode > 0 && iresult.writemsu && ins_deelsrtcontrole_status == 6 && !isScenario;
                   iresult.canInspEdit = periode > 0 &&
                                         ((iresult.readuse && ins_deelsrtcontrole_status != -1 && ins_deelsrtcontrole_status != 6) ||
                                          iresult.canMsuEdit) &&
                                         !vervallen && actief &&
                                         ((iresult.hasCTRUSEWrite && !isScenario) ||
                                           (iresult.hasCTRSENWrite && isScenario));
                   // Bestaande inspecties moet je altijd kunnen zien. Ook als het object vervallen is of als de periode op 0 is gezet.
                   iresult.canInspShow = (periode > 0 || params.deelsrtcont_key > 0) && iresult.readuse && (ins_deelsrtcontrole_status >= 0 || params.deelsrtcont_key > 0) &&
                                         iresult.hasCTRUSERead && !isScenario;
                   // Bij eerste inspectie of verwerkte inspectie kan er gepland worden.
                   iresult.canInspPlanReq = periode > 0 && iresult.readuse && !vervallen &&
                                            actief &&
                                            iresult.hasCTRUSEWrite && !isScenario && // Niet van toepassing voor scenario. Voor scenario is er trouwens al een planrecord aanwezig.
                                            ((isc_options & 1) == 1);
                   iresult.canInspPlan = iresult.canInspPlanReq &&
                                         (ins_deelsrtcontrole_status == -1 || ins_deelsrtcontrole_status == 6) &&
                                         !ctr_ismjob;
                   iresult.canInspPlanMulti = iresult.canInspPlanReq &&
                                              (ins_deelsrtcontrole_status == -1 || ins_deelsrtcontrole_status == 0 || ins_deelsrtcontrole_status == 6) &&
                                              !ctr_ismjob;
                   iresult.canInspPlanMjb = iresult.canInspPlanReq &&
                                            ((ins_deelsrtcontrole_status == -1 || ins_deelsrtcontrole_status == 6) ||
                                             (ins_deelsrtcontrole_status == 2 || ins_deelsrtcontrole_status == 3) && freezedate_year <= mjb_freeze_or_sys_year) // Laatste taak is een geaccordeerde/bevroren of ter uitvoering staande taak in of voor het freeze jaar.
                                            ctr_ismjob;
                   // Bij eerste inspectie, geplande inspectie of verwerkte inspectie kan er gestart worden.
                   // Als je de inspectie gestart hebt, mag je het ook weer terugdraaien.
                   iresult.canInspStartUnstartReq = periode > 0 && iresult.readuse && canDoNextAction && !vervallen &&
                                                    actief && iresult.hasCTRFOFWrite &&
                                                    ((isc_options & 2) == 2) &&
                                                    !isScenario;
                   iresult.canInspStartReq   = iresult.canInspStartUnstartReq && (ins_deelsrtcontrole_status <= 0 || ins_deelsrtcontrole_status == 6);
                   iresult.canInspUnstartReq = iresult.canInspStartUnstartReq && ins_deelsrtcontrole_status == 2;
                   iresult.canInspStart = iresult.canInspStartReq && !ctr_ismjob;
                   // Bevriezen gebeurt altijd in het kalenderjaar MAX(S("mjb_freeze_year"), SYSDATE).
                   // Dan is er voor het freeze kalenderjaar een bedrag ingevuld.
                   // Mocht het bedrag 0 zijn, dan moet er tijdens heb bevriezen een lcl aan de opmerking worden toegevoegd, dat de taak door een hogere prio taak wordt uitgevoerd.
                   iresult.canInspFreeze = iresult.canInspStartReq && isFreezeYear && ctr_ismjob;
                   iresult.canInspUnFreeze = iresult.canInspUnstartReq && ctr_ismjob;
                   iresult.canInspExecute = periode > 0 && iresult.readuse && canDoNextAction && !vervallen &&
                                            ins_deelsrtcontrole_status == 2 &&
                                            actief && iresult.hasCTRBOFWrite &&
                                            ((isc_options & 2) == 2) &&
                                            !isScenario && isFreezeYear && ctr_ismjob;
                   iresult.canInspUnexecute = periode > 0 && iresult.readuse && canDoNextAction && !vervallen &&
                                              ins_deelsrtcontrole_status == 3 &&
                                              actief && iresult.hasCTRBOFWrite &&
                                              ((isc_options & 2) == 2) &&
                                              !isScenario && isFreezeYear && ctr_ismjob;
                   iresult.canInspMoveUp = S("mjb_enable_moveup") == 1 && periode > 0 && iresult.readuse &&
                                           canDoNextAction && !vervallen &&
                                           (ins_deelsrtcontrole_status == 2 || ins_deelsrtcontrole_status == 3) &&
                                           actief && iresult.hasCTRUSEWrite &&
                                           ((isc_options & 2) == 2) &&
                                           !isScenario &&
                                           freezedate_year < mjb_freeze_or_sys_year && // Het is een geaccordeerde/bevroren of ter uitvoering staande taak van voor het freeze jaar (!isScenario geldt dan ook).
                                           ctr_ismjob;
                   // Bij eerste inspectie, geplande inspectie, gestarte inspectie, ter uitvoering staande of verwerkte inspectie kan er gereedgemeld/afgerond worden.
                   iresult.canInspClose = periode > 0 && iresult.readuse && canDoNextAction &&
                                          ((!vervallen && (ins_deelsrtcontrole_status < 5 || ins_deelsrtcontrole_status == 6)) ||
                                           (ins_deelsrtcontrole_status == 0 || ins_deelsrtcontrole_status == 2 || ins_deelsrtcontrole_status == 3)) &&
                                          actief && iresult.hasCTRUSEWrite &&
                                          ((isc_options & 4) == 4) &&
                                          !isScenario && !ctr_ismjob;
                   // Afronden kan vanuit elke status. Alleen vanuit status Gereed gemeld/Afgemeld(5) kan het zonder gegevens in te vullen.
                   iresult.canInspFinishReq = periode > 0 && iresult.readuse && canDoNextAction &&
                                              actief && ((isc_options & 8) == 8) &&
                                              iresult.hasCTRUSERead && !isScenario; // Scenario kan niet afgerond worden.
                   iresult.canInspFinish = iresult.canInspFinishReq && iresult.hasCTRAFRWrite && !ctr_ismjob;
                   iresult.canInspEdit = iresult.canInspEdit || iresult.canInspFinish; // Als ik de taak mag voltooien, dan mag ik de taak ook wijzigen. Dat kan ik namelijk ook tijdens het voltooien.
                   iresult.canInspFinishMjb = iresult.canInspFinishReq && iresult.hasCTRAFRWrite && (ins_deelsrtcontrole_status == 2 || ins_deelsrtcontrole_status == 3) && ctr_ismjob;
                   // Alleen als de inspectie gereedgemeld is kan SNEL afgerond worden zonder gegevens in te vullen.
                   iresult.canInspFastFinish = periode > 0 && iresult.canInspFinish && ins_deelsrtcontrole_status == 5;
                 }
                 else
                 {
                   iresult.canDoNextAction = true;
                 }

                 // Als scenario niet is meegegeven dan default 1 nemen.
                 var scen_key = params && params.scen_key? params.scen_key : 1;
                 var isScenario = scen_key > 1;

                 // Zijn er soort controles waar de user WEB_CTRUSE lees of schrijf rechten op heeft?
                 // Eerst WEB_CTRUSE lezen.
                 var bsql = "SELECT COUNT(*) aantal"
                          + "  FROM (SELECT xcp.ins_srtcontrole_key"
                          + "          FROM ins_v_defined_inspect_xcp xcp"
                          + "         WHERE xcp.ins_deel_key = " + pins_deel_key
                          + "           AND xcp.ctr_discipline_key IN (SELECT w.ins_discipline_key"                         // Alleen van de disciplines waar ik schrijf rechten op heb meetellen.
                          + "                                           FROM fac_v_webgebruiker w"
                          + "                                              , fac_functie f"
                          + "                                          WHERE w.fac_functie_key = f.fac_functie_key "
                          + "                                            AND f.fac_functie_code = 'WEB_CTRUSE'"
                          + "                                            AND w.fac_gebruiker_prs_level_read < 9"
                          + "                                            AND w.fac_gebruiker_alg_level_read < 9"
                          + "                                            AND w.prs_perslid_key = " + user_key + "))";
                 var boRs = Oracle.Execute(bsql);
                 var has_ctruse_read = boRs("aantal").Value > 0;
                 boRs.close();
                 var has_ctrsen_read = false;
                 if (!has_ctruse_read && isScenario) // anders misschien WEB_CTRSEN
                 {
                     var bsql = "SELECT COUNT(*) aantal"
                              + "  FROM (SELECT xcp.ins_srtcontrole_key"
                              + "          FROM ins_v_defined_inspect_xcp xcp"
                              + "         WHERE xcp.ins_deel_key = " + pins_deel_key
                              + "           AND xcp.ctr_discipline_key IN (SELECT w.ins_discipline_key"                         // Alleen van de disciplines waar ik schrijf rechten op heb meetellen.
                              + "                                           FROM fac_v_webgebruiker w"
                              + "                                              , fac_functie f"
                              + "                                          WHERE w.fac_functie_key = f.fac_functie_key "
                              + "                                            AND f.fac_functie_code = 'WEB_CTRSEN'"
                              + "                                            AND w.fac_gebruiker_prs_level_read < 9"
                              + "                                            AND w.fac_gebruiker_alg_level_read < 9"
                              + "                                            AND w.prs_perslid_key = " + user_key + "))";
                     var boRs = Oracle.Execute(bsql);
                     has_ctrsen_read = boRs("aantal").Value > 0;
                     boRs.close();
                 }

                 iresult.hasAnyReadXcp = ((has_ctruse_read && !isScenario) || (has_ctrsen_read && isScenario)) &&
                                         iresult.canRead("WEB_INSMAN"); // Enige rechten om exceptions (xcp) waarden te lezen.

                 // Nu WEB_CTRUSE schrijven.
                 var bsql = "SELECT COUNT(*) aantal"
                          + "  FROM (SELECT xcp.ins_srtcontrole_key"
                          + "          FROM ins_v_defined_inspect_xcp xcp"
                          + "         WHERE xcp.ins_deel_key = " + pins_deel_key
                          + "           AND xcp.ctr_discipline_key IN (SELECT w.ins_discipline_key"                         // Alleen van de disciplines waar ik schrijf rechten op heb meetellen.
                          + "                                           FROM fac_v_webgebruiker w"
                          + "                                              , fac_functie f"
                          + "                                          WHERE w.fac_functie_key = f.fac_functie_key "
                          + "                                            AND f.fac_functie_code = 'WEB_CTRUSE'"
                          + "                                            AND w.fac_gebruiker_prs_level_write < 9"
                          + "                                            AND w.fac_gebruiker_alg_level_write < 9"
                          + "                                            AND w.prs_perslid_key = " + user_key + "))";
                 var boRs = Oracle.Execute(bsql);
                 var has_ctruse_write = boRs("aantal").Value > 0;
                 boRs.close();
                 var has_ctrsen_write = false;
                 if (!has_ctruse_write && isScenario) // anders misschien WEB_CTRSEN?
                 {
                     var bsql = "SELECT COUNT(*) aantal"
                              + "  FROM (SELECT xcp.ins_srtcontrole_key"
                              + "          FROM ins_v_defined_inspect_xcp xcp"
                              + "         WHERE xcp.ins_deel_key = " + pins_deel_key
                              + "           AND xcp.ctr_discipline_key IN (SELECT w.ins_discipline_key"                         // Alleen van de disciplines waar ik schrijf rechten op heb meetellen.
                              + "                                           FROM fac_v_webgebruiker w"
                              + "                                              , fac_functie f"
                              + "                                          WHERE w.fac_functie_key = f.fac_functie_key "
                              + "                                            AND f.fac_functie_code = 'WEB_CTRSEN'"
                              + "                                            AND w.fac_gebruiker_prs_level_write < 9"
                              + "                                            AND w.fac_gebruiker_alg_level_write < 9"
                              + "                                            AND w.prs_perslid_key = " + user_key + "))";
                     var boRs = Oracle.Execute(bsql);
                     has_ctrsen_write = boRs("aantal").Value > 0;
                     boRs.close();
                 }

                 iresult.hasAnyWriteXcp = ((has_ctruse_write && !isScenario) || (has_ctrsen_write && isScenario)) &&
                                          iresult.canWrite("WEB_INSMAN"); // Enige rechten om exceptions (xcp) waarden te schrijven.
                 iresult.canDoAnyInspect = (has_ctruse_write && !isScenario) &&
                                           iresult.canRead("WEB_INSMAN"); // Enige rechten om inspecties te doen (Actuele situatie). Wordt alleen nog gebruikt voor PDA/Mobile.
               }
               ioRs.Close();
               iresult.canWriteFlags = iresult.canWrite("WEB_INSBOF") || iresult.canWrite("WEB_INSFOF"); // Kan ik flags aanpassen
               return iresult;
           },

       func_enabled_scope: // Wat mag ik zoal op deze specifieke scope?
                           // levert null als zelfs nog geen leesrechten
           function (ins_discipline_key, ins_alg_ruimte_type, ins_alg_ruimte_key, params)
           {
               var iresult = {canAdd: false, canDelete: false, canChange: false}; // Verwijderen en Wijzigen
               var fronto = params && params.urole? params.urole == "fo" : false;
               if (ins_alg_ruimte_type == "A")
               {
                 var afd_key = ins_alg_ruimte_key;

                 iresult = user.func_enabled("INS",
                                             ins_discipline_key,
                                             null, // alg_key is nvt
                                             null, // hier zou alleen een prs_key in mogen, we testen zo afzonderlijk
                                             false, // pessimist
                                             true); // nog even optional
                 if (!iresult || !iresult.anyfound)
                    return null;
                 var canWriteINSMAN = iresult.canWrite("WEB_INSMAN") && prs.canWriteAfdeling(afd_key, "WEB_INSMAN");
                 var canWriteINSUSE = iresult.canWrite("WEB_INSUSE") && prs.canWriteAfdeling(afd_key, "WEB_INSUSE");
                 var canWriteINSFOF = iresult.canWrite("WEB_INSFOF") && prs.canWriteAfdeling(afd_key, "WEB_INSFOF");
                 iresult.writeman = canWriteINSMAN;
                 iresult.writeuse = canWriteINSUSE;
                 iresult.writefof = canWriteINSFOF;
                 iresult.canAdd = canWriteINSMAN; // Toevoegen.
                 iresult.canDelete = canWriteINSMAN; // Verwijderen
                 iresult.canChange = canWriteINSMAN || canWriteINSUSE; // Wijzigen
                 iresult.canChangeAlg = canWriteINSMAN && !fronto; // Wijzigen algemene gegevens
                 iresult.canCopy = canWriteINSMAN; // Kopiëren
               }
               else if (ins_alg_ruimte_type == "P" || ins_alg_ruimte_type == "C")
               {
                 var ruimte_perslid_key = (ins_alg_ruimte_type == "P" ? ins_alg_ruimte_key : null);
                 iresult = user.func_enabled("INS",
                                             ins_discipline_key,
                                             null, // alg_key is nvt
                                             ruimte_perslid_key,
                                             false, // pessimist
                                             true); // nog even optional
                 if (!iresult || !iresult.anyfound)
                    return null;
                 if (ins_alg_ruimte_type == "P" && iresult.canRead("WEB_INSMIN"))
                 {
                   iresult.readmin = ins_alg_ruimte_key == user_key;
                   if (!iresult.readmin)
                   {
                     var funcodes = 0;
                     for (prop in iresult._funcodes)
                       if (iresult._funcodes.propertyIsEnumerable(prop))
                           funcodes++;
                     if (funcodes == 1) // Ik heb alleen WEB_INSMIN en ben niet de eigenaar, dan heb ik dus geen enkele rechten
                       return null;
                   }
                 }
                 iresult.writeman = iresult.canWrite("WEB_INSMAN");
                 iresult.writeuse = iresult.canWrite("WEB_INSUSE");
                 iresult.writefof = iresult.canWrite("WEB_INSFOF");
                 iresult.canAdd = iresult.canWrite("WEB_INSMAN"); // Toevoegen.
                 iresult.canDelete = iresult.canWrite("WEB_INSMAN"); // Verwijderen
                 iresult.canChange = iresult.canWrite("WEB_INSMAN") || iresult.canWrite("WEB_INSUSE"); // Wijzigen
                 iresult.canChangeAlg = iresult.canWrite("WEB_INSMAN") && !fronto; // Wijzigen algemene gegevens
                 iresult.canCopy = iresult.canWrite("WEB_INSMAN"); // Kopiëren
               }
               else
               { // alg_ruimte_type is een werkplek, ruimte of terrein.
                 var alg_ruimte_key = ins_alg_ruimte_key;
                 var alg_ruimte_type = ins_alg_ruimte_type;

                 if (alg_ruimte_type == "W")
                 {
                   var sql = "SELECT w.prs_alg_ruimte_key"
                           + " FROM prs_werkplek w"
                           + " WHERE w.prs_werkplek_key = " + alg_ruimte_key;
                   var oRs = Oracle.Execute(sql);
                   alg_ruimte_key = oRs("prs_alg_ruimte_key").Value;
                   oRs.Close();
                 }
                 // Voor alg_ruimte_type = "T" bevat alg_ruimte_key de alg_terreinsector_key. Dit is een geldige alg_onroerendgoed_key.

                 iresult = user.func_enabled("INS",
                                             ins_discipline_key,
                                             alg_ruimte_key,
                                             null, // prs_key
                                             false, // Pessimist.
                                             true);
                 if (!iresult || !iresult.anyfound)
                    return null;

                 // Alleen backoffice mag verwijderen, dus "WEB_INSMAN" als autorisatie functie nemen.
                 iresult.writeman = iresult.canWrite("WEB_INSMAN");
                 iresult.writeuse = iresult.canWrite("WEB_INSUSE");
                 iresult.writefof = iresult.canWrite("WEB_INSFOF");
                 iresult.canAdd = iresult.canWrite("WEB_INSMAN"); // Toevoegen.
                 iresult.canDelete = iresult.canWrite("WEB_INSMAN"); // Verwijderen.
                 iresult.canChange = iresult.canWrite("WEB_INSMAN") || iresult.canWrite("WEB_INSUSE"); // Wijzigen.
                 iresult.canChangeAlg = iresult.canWrite("WEB_INSMAN") && !fronto; // Wijzigen algemene gegevens.
                 iresult.canCopy = iresult.canWrite("WEB_INSMAN"); // Kopiëren.
               }
               // Let op: WEB_INSMSU is niet discipline gebonden en zit dus niet in iresult
               var autparamsINSMSU = user.checkAutorisation("WEB_INSMSU", true);
               iresult.writemsu = autparamsINSMSU && autparamsINSMSU.PRSwritelevel < 9 && autparamsINSMSU.ALGwritelevel < 9; // Wijzigen Afgeronde gegevens.
               iresult.readuse = iresult.canRead("WEB_INSUSE"); // Inzien.
               iresult.readman = iresult.canRead("WEB_INSMAN");
               return iresult;
           },

      func_get_nextdate: // Bepaal de volgende inspectie datum.
           function _func_get_nextdate(pins_key, psrtcont_key, pscen_key, params)
           {
             var mjb_freeze_or_sys_year = Math.max(S("mjb_freeze_year"), new Date().getFullYear());
             var mjb_start_year = S("mjb_start_year");
             var nextdate = null;

             // Is het een mjob discipline en is de eenheid jaarlijks?
             sql = "SELECT cdp.ctr_disc_params_ismjob"
                 + "     , isc.ins_srtcontrole_eenheid"
                 + "  FROM ins_srtcontrole isc"
                 + "     , ctr_disc_params cdp"
                 + " WHERE isc.ctr_discipline_key = cdp.ctr_ins_discipline_key"
                 + "   AND isc.ins_srtcontrole_key = " + psrtcont_key;
             oRs = Oracle.Execute(sql);
             var ismjob = !oRs.eof && oRs("ctr_disc_params_ismjob").Value == 1;
             var isjaarlijks = oRs("ins_srtcontrole_eenheid").Value == 4;
             oRs.Close();

             if (ismjob && isjaarlijks)
             { // MJOB taken.
               // Bereken de volgende orginele inspectiedatum (nextdate).
               // Het kan een mjob inspectie zijn en dan kan de laatste inspectie niet succesvol zijn.
               // In dat geval kan ik ins.nextcyclusdate(ins_key, srtcont_key, scen_key) niet gebruiken.
               // 1) De laatste inspectie is succesvol voltooid: De volgende met ins.nextcyclusdate() te berekenen.
               // 2) De laatste inspectie is NIET succesvol voltooid. De volgende is in het freeze jaar.
               // 3) De laatste inspectie is geaccordeerd/bevroren/gestart(2): De volgende is een periode verder als het freeze jaar.
               // 4) Er is geen inspectie geweest of gestart.

               var sql = "SELECT idsc.ins_deelsrtcontrole_key"
                       + "     , idsc.ins_deelsrtcontrole_status"
                       + "     , cm.ins_controlemode_success"
                       + "     , idsc.ins_deelsrtcontrole_freezedate"
                       + "  FROM ins_deelsrtcontrole idsc"
                       + "     , ins_controlemode cm"
                       + " WHERE idsc.ins_controlemode_key = cm.ins_controlemode_key(+)"
                       + "   AND cm.ins_controlemode_success(+) = 1"
                       + "   AND idsc.ins_deel_key = " + pins_key
                       + "   AND idsc.ins_srtcontrole_key = " + psrtcont_key
                       + "   AND idsc.ins_deelsrtcontrole_status > 0"
                       + "   AND idsc.ins_scenario_key = " + pscen_key
                       + " ORDER BY idsc.ins_deelsrtcontrole_key DESC"; // De laatste inspectie boven aan de lijst.
               var oRsM = Oracle.Execute(sql);

               var max_dsc_key = -1;
               var dsc_status = -1;
               var cm_success = false;
               var dsc_freezedate = null;
               if (!oRsM.eof)
               { // Er is een laatste geaccordeerde of succesvol voltooide inspectie en is het eerste record.
                 var max_dsc_key = oRsM("ins_deelsrtcontrole_key").Value;
                 var dsc_status = oRsM("ins_deelsrtcontrole_status").Value || -1;
                 var cm_success = (oRsM("ins_controlemode_success").Value || 0) == 1;
                 var dsc_freezedate = oRsM("ins_deelsrtcontrole_freezedate").Value != null? new Date(oRsM("ins_deelsrtcontrole_freezedate").Value) : null;
               }
               oRsM.Close();

               if (dsc_status == 6 && cm_success)        // 1) De laatste inspectie is succesvol voltooid: De volgende met ins.nextcyclusdate() te berekenen.
               { // De laatste inspectie is een succesvol afgeronde inspectie. De volgende met ins.nextcyclusdate() te berekenen.
                 sql = "SELECT ins.nextcyclusdate (" + pins_key
                     + ", " + psrtcont_key
                     + ", " + pscen_key
                     + ", 1) nextdate FROM DUAL"
                 var oRsN = Oracle.Execute(sql);
                 nextdate = new Date(oRsN("nextdate").Value);
                 oRsN.Close();
               }
               else if (dsc_status == 6 && !cm_success)  // 2) De laatste inspectie is NIET succesvol voltooid. De volgende is in het freeze jaar.
               { // De laatste inspectie is een NIET succesvol afgeronde inspectie. De volgende is in het freeze jaar.
                 nextdate = new Date(mjb_freeze_or_sys_year, 0, 1); // 1 januari van het freeze jaar.
               }
               else if (dsc_status == 2 || dsc_status == 3)                 // 3) De laatste inspectie is geaccordeerd/bevroren/gestart(2): De volgende is een periode verder als het freeze jaar.
               { // De laatste inspectie is geaccordeerd/bevroren/gestart(2) of ter uitvoering(3): De volgende is een periode verder als het freeze jaar.
                 sql = "SELECT fac.nextcyclusdate(" + dsc_freezedate.toSQL()
                     + "                        , xcp.ins_srtcontrole_mode"
                     + "                        , xcp.ins_srtcontrole_eenheid"
                     + "                        , xcp.ins_srtcontrole_periode"
                     + "                        , xcp.ins_srtcontrole_bits"
                     + "                        , 1"
                     + "                        , " + (ismjob? "1" : "0") + ") nextdate"
                     + "  FROM ins_v_defined_inspect_xcp xcp"
                     + " WHERE xcp.ins_deel_key = " + pins_key
                     + "   AND xcp.ins_srtcontrole_key = " + psrtcont_key
                     + "   AND xcp.ins_scenario_key = " + pscen_key;
                 var oRsN = Oracle.Execute(sql);
                 nextdate = new Date(oRsN("nextdate").Value);
                 oRsN.Close();
               }
               else                                      // 4) Er is geen inspectie geweest of gestart.
               { // Er is geen inspectie geweest of gestart.

                 // Registratiedatum en startdatum ophalen.
                 var sql = "SELECT d.ins_deel_aanmaak"
                         + "     , scx.ins_srtcontroledl_xcp_startdat"
                         + "     , scx.ins_srtcontrole_periode"
                         + "  FROM ins_deel d"
                         + "     , ins_v_defined_inspect_xcp scx"
                         + " WHERE d.ins_deel_key = scx.ins_deel_key"
                         + "   AND d.ins_deel_key = " + pins_key
                         + "   AND scx.ins_srtcontrole_key = " + psrtcont_key
                         + "   AND scx.ins_scenario_key = " + pscen_key;
                 var oRs = Oracle.Execute(sql);
                 var aanmaakdatum = new Date(oRs("ins_deel_aanmaak").Value);
                 var startdatum = oRs("ins_srtcontroledl_xcp_startdat").Value != null? new Date(oRs("ins_srtcontroledl_xcp_startdat").Value) : null;
                 var srtcontrole_periode = oRs("ins_srtcontrole_periode").Value;
                 oRs.Close();

                 // 1) Er is nog geen inspectie geweest en de startdatum is ingevuld of de registratiedatum ligt in de toekomst.
                 //    Er geldt dan het volgende:
                 //    Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
                 //    Voor Vervanging(2) of Certificering(3): a) Als registratiedatum het verst in de toekomst ligt:
                 //                                               Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
                 //                                            b) Als de startdatum het verst ligt: Eerste inspectie tonen op de startdatum.
                 // 2) Er is nog geen inspectie geweest en de startdatum is niet ingevuld en registratiedatum ligt in het verleden. Berekenen jaar.
                 //    a) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Controle(1).
                 //       Volgende inspectie is in het freeze jaar.
                 //    b) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Vervanging(2) of Certificering(3).
                 //       Nextdate is na het freeze jaar?
                 //       Ja)  De laatst ingeplande inspectie (nextdate) ligt na het start jaar en ligt niet in het aanmaak jaar?
                 //            Ja)  Volgende inspectie is in het freeze jaar.
                 //            Nee) Volgende inspectie is het jaar van de nextdate.
                 //       Nee) De laatst ingeplande inspectie (nextdate) is na of in het start jaar?
                 //            Ja)  Volgende inspectie is in het freeze jaar.
                 //            Nee) Volgende inspectie is in het jaar "nextdatum + periode".
                 if (startdatum)
                 { // 1) Startdatum is ingevuld en ligt in het verleden of de toekomst.
                   if (startdatum.getFullYear() >= aanmaakdatum.getFullYear())
                   { // Startdatum op of na aanmaakdatum/registratiedatum.
                     if (startdatum.getFullYear() < mjb_freeze_or_sys_year)
                       nextdate = new Date(mjb_freeze_or_sys_year, 1, 1);
                     else
                       nextdate = startdatum;
                   }
                   else // Aanmaakdatum/Registratiedatum is na de startdatum.
                   {
                     var sql = "SELECT dp.ctr_disc_params_controle_type"
                             + "  FROM ins_srtcontrole isc"
                             + "     , ctr_disc_params dp"
                             + " WHERE isc.ctr_discipline_key = dp.ctr_ins_discipline_key"
                             + "   AND isc.ins_srtcontrole_key = " + psrtcont_key;
                     var oRs = Oracle.Execute(sql);
                     var controle_type = oRs("ctr_disc_params_controle_type").Value;
                     oRs.Close();

                     if (controle_type == 1)
                     { // Controle(1).
                       if (aanmaakdatum.getFullYear() < mjb_freeze_or_sys_year)
                         nextdate = new Date(mjb_freeze_or_sys_year, 1, 1);
                       else
                         nextdate = new Date(aanmaakdatum); // Registratiedatum.
                     }
                     else
                     { // Vervanging(2), Certificering(3).
                       if ((aanmaakdatum.getFullYear() + srtcontrole_periode) < mjb_freeze_or_sys_year)
                         nextdate = new Date(mjb_freeze_or_sys_year, 1, 1);
                       else
                         nextdate = new Date(aanmaakdatum.setFullYear(aanmaakdatum.getFullYear() + srtcontrole_periode)); // 1 periode na registratiedatum.
                     }
                   }
                 }
                 else if (aanmaakdatum.getFullYear() >= new Date().getFullYear()) // Alleen de aanmaakdatum/registratiedatum is ingevuld.
                 { // Aanmaakdatum/Registratiedatum is ingevuld en ligt in de toekomst en er is nog geen inspectie geweest.
                   if (controle_type == 1)
                   { // Controle(1).
                     if (aanmaakdatum.getFullYear() < mjb_freeze_or_sys_year)
                       nextdate = new Date(mjb_freeze_or_sys_year, 1, 1);
                     else
                       nextdate = new Date(aanmaakdatum); // Registratiedatum.
                   }
                   else
                   { // Vervanging(2), Certificering(3).
                     if ((aanmaakdatum.getFullYear() + srtcontrole_periode) < mjb_freeze_or_sys_year)
                       nextdate = new Date(mjb_freeze_or_sys_year, 1, 1);
                     else
                       nextdate = new Date(aanmaakdatum.setFullYear(aanmaakdatum.getFullYear() + srtcontrole_periode)); // 1 periode na registratiedatum.
                   }
                 }
                 else
                 { // 2) Berekenen jaar.
                   if (controle_type == 1)
                   {
                     nextdate = new Date(mjb_freeze_or_sys_year, 1, 1);
                   }
                   else
                   { // Vervanging(2), Certificering(3).

                     // Bepaal de volgende berekende inspectiedatum.
                     sql = "SELECT ins.nextcyclusdate (" + pins_key
                         + ", " + psrtcont_key
                         + ", " + pscen_key
                         + ", 1) nextdate FROM DUAL"
                     var oRsN = Oracle.Execute(sql);
                     var nextdate1 = new Date(oRsN("nextdate").Value);
                     oRsN.Close();


                     if (nextdate1.getFullYear() > mjb_freeze_or_sys_year)
                     { // Nextdate is na de freeze datum.
                       if ((nextdate1.getFullYear() - srtcontrole_periode) >= mjb_start_year &&
                           (nextdate1.getFullYear() - srtcontrole_periode) != aanmaakdatum.getFullYear())
                         nextdate = new Date(mjb_freeze_or_sys_year, 1, 1); // Nu en berekende vorige inspectie liggen tussen start en freeze jaar.
                       else
                         nextdate = nextdate1;
                     }
                     else
                     { // Nextdate is voor of in het freeze jaar.
                       if (nextdate1.getFullYear() >= mjb_start_year)
                         nextdate = new Date(mjb_freeze_or_sys_year, 1, 1); // Nextdate tussen start en freeze jaar.
                       else
                         nextdate = new Date(nextdate1.setFullYear(nextdate1.getFullYear() + srtcontrole_periode)); // Nextdate voor het start jaar. 1 Periode verder.
                     }
                   }
                 }
               }
             }
             else
             { // Periodieke taken.
               // Zijn er inspecties geweest voor dit object of is er een plandatum voor dit object ingevuld zodat we de volgende inspectiedatum kunnen berekenen?
               var sql = "SELECT ins_deelsrtcontrole_datum"
                       + "  FROM ins_deelsrtcontrole idsc"
                       + " WHERE idsc.ins_srtcontrole_key = " + psrtcont_key
                       + "   AND idsc.ins_deel_key = " + pins_key
                       + "     AND idsc.ins_scenario_key = " + pscen_key
                       + "   AND idsc.ins_deelsrtcontrole_datum IS NOT NULL";
               var oRs = Oracle.Execute(sql);

               if (!oRs.eof)
               { // Bereken de volgende inspectiedatum. Het object is minstens 1 keer geinspecteerd.
                 sql = "SELECT ins.nextcyclusdate (" + pins_key
                     + ", " + psrtcont_key
                     + ", 1" // Periodieke taken kent geen scenario's.
                     + ", 1) nextdate FROM DUAL";
                 var oRsN = Oracle.Execute(sql);
                 nextdate = new Date(oRsN("nextdate").Value);
                 oRsN.Close();
               }
               else
               { // Er zijn nog geen inspecties geweest voor dit object en er is nog geen plandatum voor dit object ingevuld.
                 // Volgende inspectiedatum kunnen we tegenwoordig bepalen.
                 // Als er een startdatum is na de registratiedatum dan is dat de startdatum of anders is deze te berekenen vanaf de registratiedatum/aanmaakdatum.
                 sql = "SELECT ins_deel_aanmaak"
                     + "     , ins_srtcontroledl_xcp_startdat"
                     + "  FROM ins_v_defined_inspect_xcp"
                     + " WHERE ins_deel_key = " + pins_key
                     + "   AND ins_srtcontrole_key = " + psrtcont_key
                     + "   AND ins_scenario_key = 1";
                 var oRsS = Oracle.Execute(sql);
                 var aanmaakdatum = new Date(oRsS("ins_deel_aanmaak").Value);
                 var startdatum = oRsS("ins_srtcontroledl_xcp_startdat").Value != null? new Date(oRsS("ins_srtcontroledl_xcp_startdat").Value) : null;
                 oRsS.Close();
                 if (startdatum != null && aanmaakdatum <= startdatum)
                   nextdate = startdatum;
                 else if (startdatum != null && aanmaakdatum > startdatum)
                   nextdate = 1;
                 else
                 {
                   sql = "SELECT ins.nextcyclusdate (" + pins_key
                       + ", " + psrtcont_key
                       + ", 1" // Periodieke taken kent geen scenario's.
                       + ", 1) nextdate FROM DUAL";
                   var oRsN = Oracle.Execute(sql);
                   nextdate = new Date(oRsN("nextdate").Value);
                   oRsN.Close();
                 }
               }
               oRs.Close();
             }

             return nextdate;
           },

      testInspectInsert: // Mag ik een inspectie record uitvoeren.
           function _testInspectInsert(pins_key, psrtcont_key, pscen_key)
           { // PLAT#54019: Voorkomen dat er een ins_deelsrtcontrole record (inspectie) wordt toegevoegd als er een ingeplande inspectie is.
             //             Als dit gebeurt dan een foutmelding geven zodat bekend wordt hoe deze records worden aangemaakt.
             var sql_f = "SELECT 'x'"
                       + "  FROM   ins_deelsrtcontrole"
                       + "  WHERE  ins_deel_key = " + pins_key
                       + "     AND ins_srtcontrole_key = " + psrtcont_key
                       + "     AND ins_scenario_key = " + pscen_key
                       + "     AND ins_deelsrtcontrole_status = 0";
             var oRs_f = Oracle.Execute(sql_f);
             if (!oRs_f.eof)
             {
               __DoLog("Er wordt geprobeerd om een inspectie aan te maken terwijl er al een ingeplande inspectie aanwezig is (testInspectInsert)");
               shared.simpel_page("Er wordt geprobeerd om een inspectie aan te maken terwijl er al een ingeplande inspectie aanwezig is");
             }
             oRs_f.Close();

             return;
           },

       getresdeel_sql:
           function ()
           {
              return " (SELECT res_ins_deel_key,"
                   + "         MIN(res_deel_key) res_deel_key,"
                   + "         MIN(res_deel_opmerking) res_deel_opmerking,"
                   + "         COUNT(*) res_deel_count"
                   + "  FROM (SELECT res_deel_key"
                   + "             , res_ins_deel_key"
                   + "             , " + lcl.xsqla('res_deel_opmerking', 'res_deel_key')
                   + "         FROM res_deel"
                   + "        WHERE res_deel_verwijder IS NULL"
                   + "          AND res_deel_vervaldatum IS NULL"
                   + "        UNION ALL"
                   + "        SELECT res_deel_key"
                   + "             , res_ins_deel_key"
                   + "             , " + lcl.xsqla('res_deel_opmerking', 'res_deel_key')
                   + "         FROM res_deel"
                   + "        WHERE res_deel_verwijder IS NULL"
                   + "          AND res_deel_vervaldatum > SYSDATE) "
                   + "  GROUP BY res_ins_deel_key)"
           },

       getobjectinspect_sql:
           function (pautfunction, params)
           { // Lever de objecten of inpectie sql op.
             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");
             var minfo = (urole == "mi"); // NOT APPLICABLE?
             var frontend = (urole == "fe" || (!fronto && !backo && !minfo));

             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 bld_key_arr = params.bld_key_arr   || [];
             var terr_key_arr = params.terr_key_arr || [];       // FGII parameters
             var flr_key_arr = params.flr_key_arr   || [];
             var room_key_arr = params.room_key_arr || [];       // FGII parameters
             var wpl_key = params.wpl_key;
             var deel = params.deel;
             var deel_opm = params.deel_opm;
             var note_text = params.note_text;
             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 objsrt_oms = params.objsrt_oms;
             var insSensOnly = params.insSensOnly;
             var groep = params.groep;
             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 verantw_key = params.verantw_key;
             var beh_key = params.beh_key;
             var cpersoon_key = params.cpersoon_key;
             var dienst_key = params.dienst_key;
             var cnt_bedrijf_key = params.cnt_bedrijf_key;
             var mld_key = params.mld_key;
             var fgraph = params.fgraph;                   // FGII parameters
             var ins_key_arr = params.ins_key_arr;         // FGII parameters
             var parent_key = params.parent_key;
             var koppel_key = params.koppel_key;
             var comp_key = params.comp_key;               // FGII parameters
             var insObjIncl = params.insObjIncl;
             var expObjIncl = params.expObjIncl;
             var insLentOut = params.insLentOut;
             var insAvail = params.insAvail;
             var lentoutAction = params.lentoutAction;
             var lentoutDateFrom = params.lentoutDateFrom;
             var lentoutDateTo = params.lentoutDateTo;
             var insSuccessY = params.insSuccessY;
             var insSuccessN = params.insSuccessN;
             var embedded = params.embedded;
             var tiny = params.tiny || parent_key || koppel_key;
             var inspsoonfrom = params.inspsoonfrom;
             var inspsoonto = params.inspsoonto;
             var donedatefrom = params.donedatefrom;
             var donedateto = params.donedateto;
             var inspect = params.inspect;
             var mobile = params.mobile;
             var inacObjIncl = params.inacObjIncl;
             var inspClosed = params.inspClosed;
             var inspDone = params.inspDone;
             var inspBusy = params.inspBusy;
             var inspSoon = params.inspSoon;
             var mjob = params.mjob;
             var insFlexParams = params.insFlexParams;
             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 groepering = params.groepering;

             var srtnoti_arr = [];
             var mjb_freeze_or_sys_year = Math.max(S("mjb_freeze_year"), new Date().getFullYear());
             var mjb_start_year = S("mjb_start_year");

             var sql_objincl = "";
             if (insObjIncl || parent_key > 0 || koppel_key > 0)  // gekoppeld zijn is sterker dan geen onderdeel zijn
               sql_objincl = "";
             else
               sql_objincl += " AND dl.ins_deel_parent_key IS NULL ";

             // Is er een wildcard aanwezig in de zoektekst.
             // Als er een wildcard aanwezig is dan wel het vervaldatum filter meenemen
             var wildcard_present = deel && (deel.indexOf("*") >= 0 || deel.indexOf("%") >= 0);

             if (!expObjIncl && ((backo && (!deel || wildcard_present)) || !backo))
               sql_objincl += " AND (dl.ins_deel_vervaldatum IS NULL OR dl.ins_deel_vervaldatum > TRUNC(SYSDATE)"
                            + (insLentOut ? " OR dl.ins_alg_ruimte_key_org IS NOT NULL" : "")
                            + ")";

             var hasPosition = false; // Had the user selected something on the left side of the filter dialog
             var hasOwner = false;    // .... or on the right side

             sql = "";
             sqlOwner = sqlOwnerA = sqlOwnerB = sqlPosition = "";

             if (ins_key_arr || parent_key)
             {
                hasPosition = true; // we don't need other filters and these objects
             }
             else
             {
               if (reg_key_arr.length || dist_key_arr.length || loc_key_arr.length || bld_key_arr.length || terr_key_arr.length || flr_key_arr.length || room_key_arr.length || wpl_key)
               {
                 hasPosition = true;
               }

               if (comp_key || dep_key || persoon_key || cpersoon_key)
               {
                   hasOwner = true;
               }
             }

             if (lentoutAction >= 0)
             {
                var sql = "SELECT fac_srtnotificatie_key"
                        + "  FROM fac_srtnotificatie"
                        + " WHERE fac_srtnotificatie_code IN (" + ((lentoutAction & 1) == 1 ? "'INSOUT'" : "'xxxxxx'") + ")"
                        + "    OR fac_srtnotificatie_code IN (" + ((lentoutAction & 2) == 2 ? "'INSINN','INSIN2'" : "'xxxxxx'") + ")"
                        + "    OR fac_srtnotificatie_code IN (" + ((lentoutAction == 0) ? "'INSOUT','INSINN','INSIN2'" : "'xxxxxx'") + ")";
                var oRs = Oracle.Execute(sql);
                while (!oRs.eof)
                {
                    srtnoti_arr.push(oRs("fac_srtnotificatie_key").Value);
                    oRs.MoveNext();
                }
                oRs.Close();
                var sqlLentTracking = ", (SELECT f.fac_tracking_refkey"
                                    + "        , MAX(f.fac_tracking_datum) fac_tracking_datum"
                                    + "     FROM fac_tracking f"
                                    + "    WHERE f.fac_srtnotificatie_key IN (" + srtnoti_arr.join(",") + ")";
                if (lentoutDateFrom && lentoutDateTo)
                    sqlLentTracking += "      AND f.fac_tracking_datum BETWEEN " + lentoutDateFrom.toSQL(true) + " AND " + lentoutDateTo.toSQL(true);
                else if (lentoutDateFrom && !lentoutDateTo)
                    sqlLentTracking += "      AND f.fac_tracking_datum >= " + lentoutDateFrom.toSQL(true);
                else if (!lentoutDateFrom && lentoutDateTo)
                    sqlLentTracking += "      AND f.fac_tracking_datum <= " + lentoutDateTo.toSQL(true);
                sqlLentTracking += "    GROUP BY f.fac_tracking_refkey"
                                 + "  ) t"

             }

             ///////////////////////////////////////////////////////////
             //
             //  Start building the query to fetch all objects satisfying
             //  the conditions the user has built with all select boxes
             //
             //  We already have set globals
             //  sql_objincl  SQL-query part to in/exclude sub-objects
             //  sql_owner    SQL-query part to filter owner(bound) objects
             //  filtering on object-discipline etc. will be added after building location/owner
             //
             ///////////////////////////////////////////////////////////

             // not a combined query but either location based or department/person based

             // PF: deze subquery geeft de *oorspronkelijke* plaats/eigenaar (als tekst)
             //     van het object voor het geval dat deze op dit moment uitgeleend is, anders NULL
             //     Dit is alleen relevant bij fronto, daar wordt deze herkomst weergegeven.

             sqlInspectie_select = " NULL";
             sqlInspectie_from = "";
             sqlInspectie_where = "";
             // Voor periodieke inspecties is de scenario key NULL.
             if (fronto)
             {
               sqlLentOutFrom = "CASE WHEN  dl.ins_alg_ruimte_type_org = 'A'"
                              + "     THEN (SELECT " + S("prs_dep_string")
                              + "             FROM prs_v_afdeling d"
                              + "            WHERE d.prs_afdeling_key = dl.ins_alg_ruimte_key_org)"
                              + "     WHEN dl.ins_alg_ruimte_type_org = 'P'"
                              + "     THEN (SELECT " + S("prs_pers_string")  // keertje omschrijven naar prs_perslid_naam_full
                              + "             FROM prs_perslid p"
                              + "            WHERE p.prs_perslid_key = dl.ins_alg_ruimte_key_org)"
                              + "     WHEN dl.ins_alg_ruimte_type_org IN ('R', 'T', 'W')"
                              + "     THEN (SELECT o.alg_plaatsaanduiding"
                              + "             FROM ins_v_alg_overzicht o"
                              + "            WHERE o.alg_onroerendgoed_keys = dl.ins_alg_ruimte_key_org"
                              + "              AND o.alg_onroerendgoed_type = dl.ins_alg_ruimte_type_org)"
                              + "     ELSE NULL"
                              + "     END";
             }
             else
             {
               sqlLentOutFrom = " NULL";
               // Geeft  NULL als geen inspectie nodig
               // Eerstvolgende inspectie moet komen/had moeten komen: COALESCE (ins_deelsrtcontrole_datum, ins_deel_aanmaak) + ins_srtcontrole_periode
               if (inspect)
               {
                   var lastinspect = "EXISTS (SELECT 1"
                                   + "          FROM ins_deelsrtcontrole idsc"
                                   + "         WHERE idsc.ins_srtcontrole_key = di.ins_srtcontrole_key"
                                   + "           AND idsc.ins_deelsrtcontrole_status IN (5, 6)"
                                   + "           AND idsc.ins_deel_key = di.ins_deel_key"
                                   + "           AND idsc.ins_scenario_key = 1)";

                   // Eerstvolgende inspectie
                   var sqlNext = "SELECT"
                               + (inspDone
                                 ? ""
                                 : "     ab,")
                               + "       ins_deel_key"
                               + "     , ctr_ismjob"
                               + (inspDone
                                 ? "   , inspectie_date"
                                 : "   , ins_deelsrtcontrole_freezedate"
                                   + " , ins_deelsrtcontrole_datum"
                                   + " , ins_srtcontrole_periode"
                                   + " , ins_srtcontrole_bits")
                               + "     , ins_srtcontrole_mode"
                               + "     , ins_srtcontroledl_xcp_startdat"
                               + "     , ins_srtcontroledl_xcp_prio"
                               + "     , inspectie_eenheid"
                               + "     , inspectie_eind"
                               + "     , ins_srtcontrole_omschrijving"
                               + "     , ins_srtcontrole_opmerking"
                               + "     , ins_srtcontrole_key"
                               + "     , options"
                               + "     , ins_deelsrtcontrole_key"
                               + "     , ins_deelsrtcontrole_status"
                               + "     , ins_deelsrtcontrole_plandatum"
                               + "     , ins_deelsrtcontrole_datum_org"
                               + "     , ctr_controle_type"
                               + "     , periode"
                               + (!mobile
                                 ? "   , groepoms"
                                 + (inspDone ? "   , inspecteur_key" : "")
                                 + "   , ins_controlemode_success"
                                 + "   , ctr_disc_key"
                                 + "   , ctr_disc_oms"
                                 : ""
                                 )
                               + "      , prs_dienst_key"
                               + "   FROM ("
                               + (inspDone
                                 ? "      SELECT 1 rn" // Afgehandelde inspecties.
                                   + "         , di.ins_deel_key"
                                   + "         , di.ctr_ismjob"
                                   + "         , dsc.ins_deelsrtcontrole_datum inspectie_date"
                                   + "         , di.ins_srtcontrole_mode"
                                   + "         , dsc.prs_perslid_key inspecteur_key"
                                   + "         , di.ins_srtcontroledl_xcp_startdat"
                                   + "         , di.ins_srtcontroledl_xcp_prio"
                                   + "         , di.ins_srtcontrole_eenheid inspectie_eenheid"
                                   + "         , di.ins_srtcontrole_eind inspectie_eind"
                                   + "         , " + lcl.xsqla("di.ins_srtcontrole_omschrijving", "di.ins_srtcontrole_key")
                                   + "         , " + lcl.xsqla("di.ins_srtcontrole_opmerking", "di.ins_srtcontrole_key")
                                   + "         , di.ins_srtcontrole_options options"
                                   + "         , di.ins_srtcontrole_key"
                                   + "         , -1 ins_deelsrtcontrole_status"
                                   + "         , TO_NUMBER(NULL) ins_deelsrtcontrole_key"
                                   + "         , (SELECT idsc.ins_deelsrtcontrole_plandatum"
                                     + "            FROM ins_deelsrtcontrole idsc"
                                     + "           WHERE idsc.ins_deelsrtcontrole_key = dsc.ins_deelsrtcontrole_key)" // Afgehandelde inspecties.
                                   + "           ins_deelsrtcontrole_plandatum"
                                   + "         , (SELECT idsc.ins_deelsrtcontrole_datum_org"
                                     + "            FROM ins_deelsrtcontrole idsc"
                                     + "           WHERE idsc.ins_deelsrtcontrole_key = dsc.ins_deelsrtcontrole_key)" // Afgehandelde inspecties.
                                   + "           ins_deelsrtcontrole_datum_org"
                                   // Er moet naar de laatste UITGEVOERDE (afgeronde(6)) inspectie gekeken worden om te bepalen of de laatste inspectie een SUCCESS was.
                                   + "         , di.ctr_controle_type"
                                   + "         , di.ins_srtcontrole_periode periode"
                                   + (!mobile
                                     ? "       , di.ins_srtcontrole_groep groepoms"
                                     + "       , (SELECT cm.ins_controlemode_success"
                                     + "            FROM ins_deelsrtcontrole idsc"
                                     + "               , ins_controlemode cm"
                                     + "           WHERE idsc.ins_controlemode_key = cm.ins_controlemode_key"
                                     + "             AND idsc.ins_deelsrtcontrole_key = dsc.ins_deelsrtcontrole_key)  ins_controlemode_success"
                                     + "       , di.ctr_discipline_key ctr_disc_key"
                                     + "       , (SELECT ins_discipline_omschrijving"
                                     + "            FROM ctr_discipline"
                                     + "           WHERE ins_discipline_key = di.ctr_discipline_key) ctr_disc_oms"
                                     : ""
                                     )
                                   + "         , (SELECT isc1.prs_dienst_key"
                                     + "            FROM ins_srtcontrole isc1"
                                     + "           WHERE isc1.ins_srtcontrole_key = di.ins_srtcontrole_key) prs_dienst_key" // In 2019.1 vervangen door di.prs_dienst_key (Voor 2019.1 aan view ins_v_defined_inspect_xcp toevoegen).
                                   + "      FROM ins_v_defined_inspect_xcp di"
                                   + "         , ins_deelsrtcontrole dsc" // Alle inspecties meenemen als het vinkbokje "Afgehandeld" (inspDone) is aangevinkt.
                                   + "     WHERE di.ins_deel_key = dsc.ins_deel_key"
                                   + "       AND di.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                                   + "       AND di.ins_scenario_key = dsc.ins_scenario_key"
                                   + "       AND di.ins_scenario_key = 1"
                                   + (srtcontrole_key_arr.length
                                     ? "     AND di.ins_srtcontrole_key IN (" + srtcontrole_key_arr.join(",") + ")"
                                     : "")
                                   + (insSuccessY && insSuccessN  // Ze kunnen niet beiden false zijn.
                                     ? ""
                                     : "     AND (SELECT cm.ins_controlemode_success"
                                       + "          FROM ins_deelsrtcontrole idsc"
                                       + "             , ins_controlemode cm"
                                       + "         WHERE idsc.ins_controlemode_key = cm.ins_controlemode_key"
                                       + "           AND idsc.ins_deelsrtcontrole_key = (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                       + "                                                 FROM ins_deelsrtcontrole idsc2"
                                       + "                                                WHERE idsc2.ins_deel_key = di.ins_deel_key"
                                       + "                                                  AND idsc2.ins_srtcontrole_key = di.ins_srtcontrole_key"
                                       + "                                                  AND idsc2.ins_deelsrtcontrole_status IN (5, 6)"
                                       + "                                                  AND idsc2.ins_scenario_key = 1)) = " + (insSuccessY? "1" : "0"))
                                   + "       AND di.ctr_discipline_key IN (SELECT w.ins_discipline_key"
                                   + "                                       FROM fac_v_webgebruiker w"
                                   + "                                          , fac_functie f"
                                   + "                                      WHERE w.fac_functie_key = f.fac_functie_key "
                                   + "                                        AND f.fac_functie_code = 'WEB_CTRUSE'"
                                   + "                                        AND w.fac_gebruiker_prs_level_read < 9"
                                   + "                                        AND w.fac_gebruiker_alg_level_read < 9"
                                   + "                                        AND w.prs_perslid_key = " + user_key + ")"
                                   + "    ORDER BY inspectie_date)"
                                 : (inspSoon || (!inspSoon && !inspBusy && !inspClosed)
                                   ? "    SELECT 1 rn" // inspecties die nog nooit zijn uitgevoerd/ingepland. Er is nog geen ins_deelsrtcontrole regel aanwezig en dus ook geen plandatum/respijtdatum.
                                     + "         , 'A' ab" // Om aan te geven dat dit inspecties zijn die nog nooit zijn uitgevoerd/ingepland.
                                     + "         , di.ins_deel_key"
                                     + "         , di.ctr_ismjob"
                                     + "         , NULL ins_deelsrtcontrole_freezedate"
                                     + "         , NULL ins_deelsrtcontrole_datum"
                                     + "         , di.ins_srtcontrole_mode"
                                     + "         , di.ins_srtcontrole_periode"
                                     + "         , di.ins_srtcontrole_bits"
                                     + "         , di.ins_srtcontroledl_xcp_startdat"
                                     + "         , di.ins_srtcontroledl_xcp_prio"
                                     + "         , di.ins_srtcontrole_eenheid inspectie_eenheid"
                                     + "         , di.ins_srtcontrole_eind inspectie_eind"
                                     + "         , " + lcl.xsqla("di.ins_srtcontrole_omschrijving", "di.ins_srtcontrole_key")
                                     + "         , " + lcl.xsqla("di.ins_srtcontrole_opmerking", "di.ins_srtcontrole_key")
                                     + "         , di.ins_srtcontrole_key"
                                     + "         , di.ins_srtcontrole_options options"
                                     + "         , -1 ins_deelsrtcontrole_status"
                                     + "         , TO_NUMBER(NULL) ins_deelsrtcontrole_key"
                                     + "         , NULL ins_deelsrtcontrole_plandatum"
                                     + "         , NULL ins_deelsrtcontrole_datum_org"
                                     + "         , di.ctr_controle_type"
                                     + "         , di.ins_srtcontrole_periode periode"
                                     + (!mobile
                                       ? "       , di.ins_srtcontrole_groep groepoms"
                                       + "       , NULL ins_controlemode_success"
                                       + "       , di.ctr_discipline_key ctr_disc_key"
                                       + "       , (SELECT ins_discipline_omschrijving"
                                       + "            FROM ctr_discipline"
                                       + "           WHERE ins_discipline_key = di.ctr_discipline_key) ctr_disc_oms"
                                       : ""
                                       )
                                     + "         , (SELECT isc1.prs_dienst_key"
                                       + "            FROM ins_srtcontrole isc1"
                                       + "           WHERE isc1.ins_srtcontrole_key = di.ins_srtcontrole_key) prs_dienst_key" // In 2019.1 vervangen door di.prs_dienst_key (Voor 2019.1 aan view ins_v_defined_inspect_xcp toevoegen).
                                     + "      FROM ins_v_defined_inspect_xcp di"
                                     + "     WHERE (di.ins_deel_key, di.ins_srtcontrole_key) NOT IN"
                                     + "                 (SELECT ins_deel_key, ins_srtcontrole_key"
                                     + "                    FROM ins_deelsrtcontrole)"
                                     + "       AND di.ins_scenario_key = 1"
                                     + (srtcontrole_key_arr.length
                                       ? "     AND di.ins_srtcontrole_key IN (" + srtcontrole_key_arr.join(",") + ")"
                                       : "")
                                     + "       AND di.ctr_discipline_key IN (SELECT w.ins_discipline_key"
                                     + "                                       FROM fac_v_webgebruiker w"
                                     + "                                          , fac_functie f"
                                     + "                                      WHERE w.fac_functie_key = f.fac_functie_key "
                                     + "                                        AND f.fac_functie_code = 'WEB_CTRUSE'"
                                     + "                                        AND w.fac_gebruiker_prs_level_read < 9"
                                     + "                                        AND w.fac_gebruiker_alg_level_read < 9"
                                     + "                                        AND w.prs_perslid_key = " + user_key + ")"
                                     + "  UNION ALL"
                                   : "")
                                   // Inspecties die al eens zijn uitgevoerd of inspecties die voor het eerst zijn ingepland(0) of gestart(2) maar nog geen uitgevoerde/afgemelde(6) inspectie hebben.
                                   + "    SELECT RANK ()" // Volgnummertje toekennen.
                                   + "              OVER ("
                                   + "                 PARTITION BY di.ins_deel_key, idsc.ins_srtcontrole_key" // Soort van group-by
                                   + "                 ORDER BY ins_deelsrtcontrole_key DESC) rn"  // Op volgorde zetten/Rangschikken/Sorteren op inspectiedatum.
                                   + "         , 'B' ab"
                                   + "         , di.ins_deel_key"
                                   + "         , di.ctr_ismjob"
                                   + "         , idsc.ins_deelsrtcontrole_freezedate"
                                   + "         , idsc.ins_deelsrtcontrole_datum"
                                   + "         , di.ins_srtcontrole_mode"
                                   + "         , di.ins_srtcontrole_periode"
                                   + "         , di.ins_srtcontrole_bits"
                                   + "         , ins_srtcontroledl_xcp_startdat"
                                   + "         , ins_srtcontroledl_xcp_prio"
                                   + "         , di.ins_srtcontrole_eenheid inspectie_eenheid"
                                   + "         , di.ins_srtcontrole_eind inspectie_eind"
                                   + "         , " + lcl.xsqla("di.ins_srtcontrole_omschrijving", "di.ins_srtcontrole_key")
                                   + "         , " + lcl.xsqla("di.ins_srtcontrole_opmerking", "di.ins_srtcontrole_key")
                                   + "         , di.ins_srtcontrole_key"
                                   + "         , di.ins_srtcontrole_options options"
                                   + "         , idsc.ins_deelsrtcontrole_status"
                                   + "         , idsc.ins_deelsrtcontrole_key"
                                   + "         , CASE"
                                   + "           WHEN idsc.ins_deelsrtcontrole_status IN (0, 2, 3)"
                                   + "           THEN idsc.ins_deelsrtcontrole_plandatum"
                                   + "           ELSE NULL"
                                   + "           END ins_deelsrtcontrole_plandatum"
                                   + "         , idsc.ins_deelsrtcontrole_datum_org"
                                   + "         , di.ctr_controle_type"
                                   + "         , di.ins_srtcontrole_periode periode"
                                   + (!mobile
                                     ? "       , di.ins_srtcontrole_groep groepoms"
                                     + "       , NULL ins_controlemode_success"
                                     + "       , di.ctr_discipline_key ctr_disc_key"
                                     + "       , (SELECT ins_discipline_omschrijving"
                                     + "            FROM ctr_discipline"
                                     + "           WHERE ins_discipline_key = di.ctr_discipline_key) ctr_disc_oms"
                                     : ""
                                     )
                                   + "         , (SELECT isc1.prs_dienst_key"
                                     + "            FROM ins_srtcontrole isc1"
                                     + "           WHERE isc1.ins_srtcontrole_key = di.ins_srtcontrole_key) prs_dienst_key" // In 2019.1 vervangen door di.prs_dienst_key (Voor 2019.1 aan view ins_v_defined_inspect_xcp toevoegen).
                                   + "      FROM ins_deelsrtcontrole idsc"
                                   + "         , ins_v_defined_inspect_xcp di"
                                   + "         , ins_controlemode cm"
                                   + "     WHERE idsc.ins_controlemode_key = cm.ins_controlemode_key(+)"
                                   + "       AND idsc.ins_srtcontrole_key = di.ins_srtcontrole_key"
                                   + "       AND idsc.ins_deel_key = di.ins_deel_key"
                                   + "       AND idsc.ins_scenario_key = 1"
                                   + "       AND di.ins_scenario_key = 1"
                                   + (srtcontrole_key_arr.length
                                     ? "     AND di.ins_srtcontrole_key IN (" + srtcontrole_key_arr.join(",") + ")"
                                     : "")
                                   + "       AND di.ctr_discipline_key IN (SELECT w.ins_discipline_key"
                                   + "                                       FROM fac_v_webgebruiker w"
                                   + "                                          , fac_functie f"
                                   + "                                      WHERE w.fac_functie_key = f.fac_functie_key "
                                   + "                                        AND f.fac_functie_code = 'WEB_CTRUSE'"
                                   + "                                        AND w.fac_gebruiker_prs_level_read < 9"
                                   + "                                        AND w.fac_gebruiker_alg_level_read < 9"
                                   + "                                        AND w.prs_perslid_key = " + user_key + ")"
                                   + "    )")
                               + " WHERE rn = 1"
                               // Voor afgehandelde inspecties ook inspecties met periode 0 tonen.
                               + (!inspDone
                                 ? "   AND periode > 0"
                                 : "")
                               // Alleen bij "Afgehandeld" vervallen inspecties tonen.
                               // Indien vervallen maar nog niet afgerond dan ook de inspectie tonen (status = 0,2,3 altijd tonen).
                               + (inspBusy || inspClosed || inspSoon
                               ? "   AND (inspectie_eind IS NULL OR inspectie_eind > SYSDATE OR ins_deelsrtcontrole_status IN (0, 2, 3))"
                               : "");

                   sqlInspectie_select = "       ispn.ctr_ismjob"
                                       + (inspDone
                                         ? "   , inspectie_date"
                                         : "   , ispn.ins_deelsrtcontrole_freezedate"
                                           + " , ispn.ins_deelsrtcontrole_datum"
                                           + " , ispn.ins_srtcontrole_periode"
                                           + " , ispn.ins_srtcontrole_bits")
                                       + "     , ispn.ins_srtcontrole_mode"
                                       + "     , ispn.ins_srtcontroledl_xcp_startdat"
                                       + "     , ispn.ins_srtcontroledl_xcp_prio"
                                       + "     , ispn.ins_srtcontrole_omschrijving"
                                       + "     , ispn.ins_srtcontrole_opmerking"
                                       + "     , ispn.ins_srtcontrole_key"
                                       + "     , ispn.options"
                                       + "     , ispn.ins_deelsrtcontrole_key"
                                       + "     , ispn.ins_deelsrtcontrole_status"
                                       + "     , ispn.ins_deelsrtcontrole_plandatum"
                                       + "     , ispn.ins_deelsrtcontrole_datum_org"
                                       + "     , ispn.inspectie_eind"
                                       + "     , ispn.inspectie_eenheid"
                                       + "     , ispn.ctr_controle_type"
                                       + "     , ispn.periode"
                                       + (!mobile
                                         ? "   , ispn.groepoms"
                                         + "   , ispn.ins_controlemode_success"
                                         + "   , ispn.ctr_disc_key"
                                         + "   , ispn.ctr_disc_oms"
                                         : ""
                                         )
                                       + "     , ispn.prs_dienst_key";

                   sqlInspectie_from = "       , (" + sqlNext + ") ispn";

                   sqlInspectie_where = " AND ispn.ins_deel_key = dl.ins_deel_key";
               }
             }

             if (insSensOnly)
             {
                var sensorthresholdstate_sql = " CASE WHEN ins_srtdeel_sensortype != 0 AND ins_srtdeel_statethreshold is not null"
                                             + " THEN ins.state_diff (ins_deel_state, ins_srtdeel_statethreshold) END thresholdstate"
                                             + ", ins_deel_state "
                                             + ", ins_deel_statedate ";
             }

             if (fronto)
             {
                 var  sqlKenmerkBewerkbaar_select = ", CASE WHEN k.km900>0 THEN 1 ELSE 0 END bewerkbaar";
                 var  sqlKenmerkBewerkbaar_from = "( SELECT sd.ins_srtdeel_key"
                                                + " , COUNT (km.ins_kenmerk_volgnummer) km900"
                                                + "    FROM ins_srtkenmerk sk"
                                                + "       , ins_kenmerk km"
                                                + "       , ins_srtdeel sd"
                                                + "       , ins_srtgroep gr"
                                                + "   WHERE km.ins_srtkenmerk_key = sk.ins_srtkenmerk_key"
                                                + "     AND gr.ins_srtgroep_key = sd.ins_srtgroep_key"
                                                + "     AND km.ins_kenmerk_verwijder IS NULL"
                                                + "     AND sk.ins_srtkenmerk_verwijder IS NULL"
                                                + "     AND (   (   km.ins_srtinstallatie_key = sd.ins_srtdeel_key"
                                                + "             AND km.ins_kenmerk_niveau = 'S')"
                                                + "          OR (   km.ins_srtinstallatie_key = sd.ins_srtgroep_key"
                                                + "             AND km.ins_kenmerk_niveau = 'G')"
                                                + "          OR (   km.ins_srtinstallatie_key = gr.ins_discipline_key"
                                                + "             AND km.ins_kenmerk_niveau = 'D'))"
                                                + "     AND BITAND(km.ins_kenmerk_rolcode,4) = 4"
                                                + "   GROUP BY sd.ins_srtdeel_key) k";
                 var  sqlKenmerkBewerkbaar_where = " AND dl.ins_srtdeel_key = k.ins_srtdeel_key(+)";
             }
             else // Dan doen we er toch niets mee
             {
                 sqlKenmerkBewerkbaar_select = ", 0 bewerkbaar";
                 sqlKenmerkBewerkbaar_from = "DUAL";
                 sqlKenmerkBewerkbaar_where = "";
             }

             sqlReservering_from = "( SELECT rrd.res_rsv_deel_key"
                                 + "       , rrd.res_rsv_deel_van"
                                 + "       , rrd.res_rsv_deel_tot"
                                 + "    FROM res_rsv_deel rrd"
                                 + "   WHERE rrd.res_rsv_deel_afgemeld IS NULL"
                                 + ") rs";
             sqlReservering_where = " AND rs.res_rsv_deel_key(+) = dl.res_rsv_deel_key";


             // Setting ins_auth_obj_lendout: Authorization scope for objects which are lended out {0=owner(borrower) (default) | 1=basic place/owner}
             //
             // Voor UITGELEENDE objecten geldt: ins_alg_ruimte_type = 'P' en ins_alg_ruimte_type_org IN ('A', 'P', 'C', 'T', 'R', 'W')
             // 0=owner(borrower):   De feitelijke eigenaar wordt als de normale eigenaar beschouwd (lener = eigenaar) => autorisatie op ins_alg_ruimte_key.
             // 1=basic place/owner: De oorsprokelijke plaats/eigenaar wordt als de normale plaats/eigenaar beschouwd => autorisatie op ins_alg_ruimte_key_org.
             //
             // Voor NIET UITGELEENDE objecten is er geen verschil => ins_alg_ruimte_type IN ('A', 'P', 'C', 'T', 'R', 'W') en ins_alg_ruimte_type_org IS NULL
             //                                                       altijd autorisatie op ins_alg_ruimte_key.
             //
             // Autorisatie op de basis plaats/eigenaar (ins_alg_ruimte_key_org) toepassen.
             // Alleen 1) als de Setting ins_auth_obj_lendout = 1.
             //        2) bij uitleenregistratie (fronto).
             //        3) als het object is uitgeleend (insLentOut).
             var auth_org = S("ins_auth_obj_lendout") == 1 && fronto && insLentOut;
             if (!hasPosition || fronto)
             { // Position filter would imply only place-objects
               sqlOwner_select = "SELECT TO_CHAR(NULL) plaats"
                               + "     , NULL alg_locatie_key"
                               + "     , NULL alg_locatie_omschrijving"
                               + "     , NULL alg_locatie_adres"
                               + "     , NULL alg_locatie_plaats"
                               + (groepering > 0
                                 ? "   , NULL geb_ter_key"
                                   + " , NULL geb_ter_omschrijving"
                                 : "")
                               + (groepering == 12
                                 ? "   , NULL prs_perslid_key_verantw_key"
                                   + " , NULL verantwoordelijke"
                                 : "")
                               + (inspDone || !inspect
                                 ? ""
                                 : "   , ispn.ab")
                               + "     , " + lcl.xsql("s.ins_srtdeel_omschrijving", "s.ins_srtdeel_key") + " soort"
                               + "     , dl.ins_deel_omschrijving"
                               + "     , dl.ins_deel_image"
                               + "     , dl.prs_perslid_key_beh"
                               + "     , (SELECT prs_perslid_naam_full FROM prs_v_perslid_fullnames_all WHERE prs_perslid_key = prs_perslid_key_beh) objectbeheerder"
                               + "     , " + lcl.xsql("d.ins_discipline_omschrijving", "d.ins_discipline_key") + " ins_disc_oms"
                               + "     , " + lcl.xsql("g.ins_srtgroep_omschrijving", "g.ins_srtgroep_key") + " ins_groep_oms"
                               + "     , dl.ins_deel_key"
                               + "     , dl.ins_alg_ruimte_type"
                               + "     , dl.res_rsv_deel_key"      // gereserveerde object
                               + "     , dl.ins_alg_ruimte_type_org"
                               + "     , dl.ins_deel_parent_key"
                               + "     , (SELECT ins_deel_omschrijving FROM ins_deel WHERE ins_deel_key = dl.ins_deel_parent_key) parent_omschrijving"
                               + "     , " + sqlLentOutFrom + " uitgegeven_vanuit"
                               + "     , rs.res_rsv_deel_van"
                               + "     , rs.res_rsv_deel_tot"
                               + "     , " + sqlInspectie_select
                               + "     , dl.ins_deel_aanmaak"
                               + (insSensOnly
                                 ? ", " + sensorthresholdstate_sql
                                 : "")
                               + (!mobile
                                 ? "   , s.ins_srtdeel_code"
                                   + " , dl.ins_deel_opmerking"
                                   + " , dl.ins_deel_aantal"
                                   + " , s.ins_srtdeel_eenheid"
                                   + " , s.ins_srtdeel_key"
                                   + " , s.ins_srtdeel_upper"
                                   + " , dl.ins_deel_getekend"
                                   + " , dl.ins_discipline_key"
                                   + " , -1 alg_district_key"
                                   + " , dl.ins_deel_x" // is coordinaat bekend?
                                   + " , dl.ins_deel_y"
                                   + " , dl.ins_deel_dwgx" // is dwg coordinaat bekend?
                                   + " , dl.ins_deel_dwgy"
                                   + " , s.ins_srtgroep_key"
                                   + " , dl.ins_deel_upper"
                                   + " , s.ins_srtdeel_uitleenbaar"
                                   + " , dl.ins_alg_ruimte_key_org"
                                   + " , rd.res_deel_key"
                                   + " , rd.res_deel_opmerking"
                                   + " , rd.res_deel_count"
                                   + (inspDone
                                     ? ", (SELECT prs_perslid_naam_full FROM prs_v_perslid_fullnames_all WHERE prs_perslid_key = inspecteur_key) inspecteur"
                                     : "")
                                   + " , dl.ins_deel_vervaldatum"
                                   + " , (SELECT idn2.ins_deel_note_omschrijving"
                                   + "				FROM ins_deel_note idn2"
                                   + "			   WHERE     idn2.ins_deel_key = dl.ins_deel_key"
                                   + "					 AND idn2.ins_deel_note_key ="
                                   + "						 (SELECT MAX (idn3.ins_deel_note_key)"
                                   + "							FROM ins_deel_note idn3"
                                   + "						   WHERE idn3.ins_deel_key = dl.ins_deel_key))"
                                   + "				 notitie"
                                   + " , (SELECT MAX (idn4.ins_deel_note_aanmaak)"
                                   + "				FROM ins_deel_note idn4"
                                   + "			   WHERE idn4.ins_deel_key = dl.ins_deel_key)"
                                   + "				 notitiedatum"
                                   + " , dl.ins_deel_actief"
                                   + " , dl.ins_deel_flag"
                                   + " , dl.ins_deel_mjb_score1"
                                   + " , dl.ins_deel_mjb_score2"
                                   + " , s.ins_srtdeel_mjb_grensscore1"
                                   + (lentoutAction >= 0 ? " , t.fac_tracking_datum" : "")
                                 : "")
                               + (insFlexParams && insFlexParams.anyflex
                                 ?       insFlexParams.sql
                                 : "");

               sqlOwner_from = " FROM ins_v_deelenonderdeel dl"
                             + "    , ins_discipline d"
                             + "    , ins_srtgroep g"
                             + "    , ins_srtdeel s"
                             + (lentoutAction >= 0 ? sqlLentTracking : "")
                             + (verantw_key
                               ? "  , ins_v_alg_overzicht o"
                               : "")
                             + sqlInspectie_from
                             + ", " + ins.getresdeel_sql() + " rd"
                             + ", " + sqlReservering_from;

               sqlOwner_where = " WHERE s.ins_srtdeel_key = dl.ins_srtdeel_key"
                              + " AND dl.ins_deel_verwijder IS NULL"
                              + " AND dl.ins_deel_key =  rd.res_ins_deel_key(+)"
                              + " AND dl.ins_deel_module = 'INS'"
                              + " AND dl.ins_discipline_key = d.ins_discipline_key"
                              + " AND s.ins_srtgroep_key = g.ins_srtgroep_key"
                              + " AND s.ins_srtgroep_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + ")"
                              + ( lentoutAction >= 0
                                ? " AND dl.ins_deel_key = t.fac_tracking_refkey" + (lentoutAction == 0 ? "(+)" : "")
                                : ""
                                )
                             + (verantw_key
                               ? " AND o.alg_onroerendgoed_keys = dl.ins_alg_ruimte_key_org"
                                 + " AND o.alg_onroerendgoed_type = dl.ins_alg_ruimte_type_org"
                               : "")
                              + sql_objincl
                              + sqlInspectie_where
                              + sqlReservering_where
                              + (fronto
                                ? " AND s.ins_srtdeel_uitleenbaar = 1"
                                : "")
                              + (koppel_key
                                ? " AND idk.ins_deelkoppeling_verwijder IS NULL"
                                  + " AND ((     dl.ins_deel_key = idk.ins_deelkoppeling_naar_key"
                                  + "        AND idk.ins_deelkoppeling_van_key=" + koppel_key
                                  + "      )"
                                  + "   OR (     dl.ins_deel_key = idk.ins_deelkoppeling_van_key"
                                  + "        AND idk.ins_deelkoppeling_naar_key=" + koppel_key + "))"
                                : "")
                              + ((insLentOut && !insAvail)
                                 ? " AND dl.ins_alg_ruimte_key_org IS NOT NULL"
                                 : (!insLentOut && insAvail)
                                    ? " AND dl.ins_alg_ruimte_key_org IS NULL"
                                    : "");

               if (loc_key_arr.length || bld_key_arr.length)
               {
                   sqlOwner_from += ", (SELECT alg_ruimte_key"
                                  + "     FROM alg_v_allonroerendgoed"
                                  + "    WHERE " + (bld_key_arr.length ? "alg_gebouw_key" : "alg_locatie_key")
                                  + "      IN (" + (bld_key_arr.length ? bld_key_arr.join(",") : loc_key_arr.join(",")) + ")"
                                  + "  ) a";
                   sqlOwner_where += " AND dl.ins_alg_ruimte_key_org = a.alg_ruimte_key";
               }

               sqlOwnerA = sqlOwner_select
                         + "    , CASE WHEN dl.ins_alg_ruimte_type_org IS NOT NULL"
                         + "           THEN (SELECT p.prs_perslid_naam_full"
                         + "                   FROM prs_v_perslid_fullnames_all p"
                         + "                  WHERE p.prs_perslid_key = dl.ins_alg_ruimte_key)"
                         + "           ELSE (SELECT " + S("prs_dep_string")
                         + "                   FROM prs_v_afdeling d"
                         + "                  WHERE prs_afdeling_key = dl.ins_alg_ruimte_key)"
                         + "           END uitgeleend_aan"
                         + "    , NULL alg_ruimte_key " // person key
                         + (groepering == 11
                           ? ", afn.prs_afdeling_naam"
                           : "")
                         + (!mobile
                           ? sqlKenmerkBewerkbaar_select
                             + ", b.prs_bedrijf_key prs_bedrijf_key" // bedrijf key
                             + ", ab.prs_afdeling_key1"
                             + ", CASE WHEN dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'P'"
                             + "       THEN (SELECT p.prs_perslid_email"
                             + "               FROM prs_perslid p"
                             + "              WHERE p.prs_perslid_key = dl.ins_alg_ruimte_key)"
                             + "       WHEN dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'C'"
                             + "       THEN (SELECT cp.prs_contactpersoon_email"
                             + "               FROM prs_contactpersoon cp"
                             + "              WHERE cp.prs_contactpersoon_key = dl.ins_alg_ruimte_key)"
                             + "       ELSE b.prs_bedrijf_email"
                             + "       END uitgeleend_aan_email"
                             + ", dl.ins_alg_ruimte_key prs_afdeling_key" // department key
                             + (koppel_key? ", ins_deelkoppeling_omschrijving, ins_deelkoppeling_van_key, ins_deelkoppeling_naar_key" : "")
                           : "")
                         + sqlOwner_from
                         + ", prs_v_afdeling_boom ab"
                         + ", prs_bedrijf b"
                         + (groepering == 11
                           ? ", prs_v_afdeling_fullnames afn"
                           : "")
                         + ", " + sqlKenmerkBewerkbaar_from
                         + (koppel_key
                           ? ", (SELECT *"
                           + "     FROM ins_deelkoppeling"
                           + "    WHERE     ins_deelkoppeling_van_key = " + koppel_key
                           + "           OR ins_deelkoppeling_naar_key = " + koppel_key + ") idk"
                           : "")
                         + sqlOwner_where
                         + (groepering == 11
                           ? " AND ab.prs_afdeling_key = afn.prs_afdeling_key"
                           : "")
                         + sqlKenmerkBewerkbaar_where
                         + " AND ab.prs_bedrijf_key = b.prs_bedrijf_key";

               if (auth_org)
                 // Object is uitgeleend.
                 sqlOwnerA_org = sqlOwnerA
                               + " AND dl.ins_alg_ruimte_key_org = ab.prs_afdeling_key"
                               + " AND dl.ins_alg_ruimte_type_org = 'A'";

               sqlOwnerA += " AND dl.ins_alg_ruimte_key = ab.prs_afdeling_key"
                          + " AND dl.ins_alg_ruimte_type = 'A'" // Object is NIET uitgeleend, anders was het type "C" of "P".
                          + ( !inacObjIncl && ((backo && !deel) || !backo)
                            ? " AND dl.ins_deel_actief = 1"
                            : ""
                            );

               sqlOwnerP = sqlOwner_select
                         + "    , CASE WHEN (dl.ins_alg_ruimte_type = 'P')"
                         + "           THEN (SELECT p.prs_perslid_naam_full"
                         + "                   FROM prs_v_perslid_fullnames_all p"
                         + "                  WHERE p.prs_perslid_key = dl.ins_alg_ruimte_key)"
                         + "           WHEN (dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'C')"
                         + "           THEN (SELECT "+S("prs_contactpers_string")
                         + "                   FROM prs_contactpersoon cp"
                         + "                  WHERE cp.prs_contactpersoon_key = dl.ins_alg_ruimte_key)"
                         + "           ELSE NULL"
                         + "           END uitgeleend_aan"
                         + "    , dl.ins_alg_ruimte_key alg_ruimte_key " // person key
                         + (groepering == 11
                           ? ", afn.prs_afdeling_naam"
                           : "")
                         + (!mobile
                           ? sqlKenmerkBewerkbaar_select
                             + ", b.prs_bedrijf_key prs_bedrijf_key " // bedrijf key
                             + ", ab.prs_afdeling_key1"
                             + ", p.prs_perslid_email uitgeleend_aan_email"
                             + ", p.prs_afdeling_key prs_afdeling_key" // department key
                             + (koppel_key? ", ins_deelkoppeling_omschrijving, ins_deelkoppeling_van_key, ins_deelkoppeling_naar_key" : "")
                           : "")
                         + sqlOwner_from
                         + ", prs_perslid p"
                         + ", prs_v_afdeling_boom ab"
                         + ", prs_bedrijf b"
                         + (groepering == 11
                           ? ", prs_v_afdeling_fullnames afn"
                           : "")
                         + ", " + sqlKenmerkBewerkbaar_from
                         + (koppel_key
                           ? ", (SELECT *"
                           + "     FROM ins_deelkoppeling"
                           + "    WHERE     ins_deelkoppeling_van_key = " + koppel_key
                           + "           OR ins_deelkoppeling_naar_key = " + koppel_key + ") idk"
                           : "")
                         + sqlOwner_where
                         + (groepering == 11
                           ? " AND ab.prs_afdeling_key = afn.prs_afdeling_key"
                           : "")
                         + sqlKenmerkBewerkbaar_where
                         + " AND p.prs_afdeling_key = ab.prs_afdeling_key"
                         + " AND ab.prs_bedrijf_key = b.prs_bedrijf_key"
                         + " AND dl.ins_alg_ruimte_key = p.prs_perslid_key";

               if (auth_org)
                 // Object is uitgeleend.
                 sqlOwnerP_org = sqlOwnerP
                               + " AND dl.ins_alg_ruimte_type_org = 'P'";

               sqlOwnerP += " AND dl.ins_alg_ruimte_type = 'P'"        // Object is wel of niet uitgeleend.
                          + ( !insLentOut && (!inacObjIncl && ((backo && !deel) || !backo))
                            ? " AND dl.ins_deel_actief = 1"
                            : ""
                            )
                          + (auth_org
                            ? " AND dl.ins_alg_ruimte_key_org IS NULL" // Dit deel kijkt naar NIET uitgeleende objecten. sqlOwnerA_org naar uitgeleende objecten.
                            : "");

               sqlOwnerCP = sqlOwner_select
                          + "    , " + S("prs_contactpers_string") + " uitgeleend_aan"
                          + "    , dl.ins_alg_ruimte_key alg_ruimte_key" // person key
                          + (groepering == 11
                            ? ", NULL prs_afdeling_naam"
                            : "")
                          + (!mobile
                            ? sqlKenmerkBewerkbaar_select
                              + ", (SELECT c.prs_bedrijf_key FROM prs_contactpersoon c WHERE c.prs_contactpersoon_key = dl.ins_alg_ruimte_key) prs_bedrijf_key" // bedrijf key
                              + ", 0 dummy1" // department key
                              + ", cp.prs_contactpersoon_email uitgeleend_aan_email"
                              + ", NULL prs_afdeling_key" // department key
                              + (koppel_key? ", ins_deelkoppeling_omschrijving, ins_deelkoppeling_van_key, ins_deelkoppeling_naar_key" : "")
                            : "")
                          + sqlOwner_from
                          + ", prs_contactpersoon cp"
                          + ", prs_bedrijf b"
                          + ", " + sqlKenmerkBewerkbaar_from
                          + (koppel_key
                            ? ", (SELECT *"
                            + "     FROM ins_deelkoppeling"
                            + "    WHERE     ins_deelkoppeling_van_key = " + koppel_key
                            + "           OR ins_deelkoppeling_naar_key = " + koppel_key + ") idk"
                            : "")
                          + sqlOwner_where
                          + sqlKenmerkBewerkbaar_where
                          + " AND cp.prs_bedrijf_key = b.prs_bedrijf_key"
                          + " AND dl.ins_alg_ruimte_key = cp.prs_contactpersoon_key";

               if (auth_org)
                 // Object is uitgeleend.
                 sqlOwnerCP_org = sqlOwnerCP
                                + " AND dl.ins_alg_ruimte_type_org = 'C'";

               sqlOwnerCP += " AND dl.ins_alg_ruimte_type = 'C'"       // Object is wel of niet uitgeleend.
                          + ( !insLentOut && (!inacObjIncl && ((backo && !deel) || !backo))
                            ? " AND dl.ins_deel_actief = 1"
                            : ""
                            )
                          + (auth_org
                            ? " AND dl.ins_alg_ruimte_key_org IS NULL" // Dit deel kijkt naar NIET uitgeleende objecten. sqlOwnerA_org naar uitgeleende objecten.
                            : "");

             }

             if (!hasOwner || auth_org)
             { // Owner filter would imply only owned objects (!hasOwner)
               // S("ins_auth_obj_lendout") == 1 && fronto && insLentOut => Orginele plaats/eigenaar (ins_alg_ruimte_key_org) is de eigenaar van het object (auth_org).
               //                                                           Deze orginele plaats/eigenaar (ins_alg_ruimte_key_org) kan nu de ingevulde persoon zijn.
               sqlPosition = "SELECT DISTINCT"
                           + " COALESCE(o.alg_terreinsector_naam, o.alg_plaatsaanduiding || DECODE(o.alg_plaatsomschrijving, '','' ,' (' || o.alg_plaatsomschrijving || ')')) plaats"
                           + "     , alg.alg_locatie_key"
                           + "     , alg.alg_locatie_omschrijving"
                           + "     , COALESCE(bld.alg_gebouw_adres,alg.alg_locatie_adres) alg_locatie_adres"  // compatible met hoe het was
                           + "     , alg.alg_locatie_plaats"
                           + (groepering > 0
                             ? "   , COALESCE(o.alg_gebouw_key, o.alg_terreinsector_key) geb_ter_key"
                               + " , COALESCE(o.alg_gebouw_naam, o.alg_terreinsector_naam) geb_ter_omschrijving"
                             : "")
                           + (groepering == 12
                             ? "   , gtv.prs_perslid_key_verantw_key"
                               + " , gtv.verantwoordelijke"
                             : "")
                           + (inspDone || !inspect
                             ? ""
                             : "   , ispn.ab")
                           + "     , " + lcl.xsql('s.ins_srtdeel_omschrijving', 's.ins_srtdeel_key') + " soort"
                           + "     , dl.ins_deel_omschrijving"
                           + "     , dl.ins_deel_image"
                           + "     , dl.prs_perslid_key_beh"
                           + "     , (SELECT prs_perslid_naam_full FROM prs_v_perslid_fullnames_all WHERE prs_perslid_key = prs_perslid_key_beh) objectbeheerder"
                           + "     , " + lcl.xsql('d.ins_discipline_omschrijving', 'd.ins_discipline_key') + " ins_disc_oms"
                           + "     , " + lcl.xsql('g.ins_srtgroep_omschrijving', 'g.ins_srtgroep_key') + " ins_groep_oms"
                           + "     , dl.ins_deel_key"
                           + "     , dl.ins_alg_ruimte_type"
                           + "     , dl.res_rsv_deel_key"      // gereserveerde object
                           + "     , dl.ins_alg_ruimte_type_org"
                           + "     , dl.ins_deel_parent_key"
                           + "     , (SELECT ins_deel_omschrijving FROM ins_deel WHERE ins_deel_key = dl.ins_deel_parent_key) parent_omschrijving"
                           + "     , " + sqlLentOutFrom + " uitgegeven_vanuit"
                           + "     , rs.res_rsv_deel_van"
                           + "     , rs.res_rsv_deel_tot"
                           + "     , " + sqlInspectie_select
                           + "     , dl.ins_deel_aanmaak"
                           + (insSensOnly
                             ? ", " + sensorthresholdstate_sql
                             : ""
                           )
                           + (!mobile
                             ? "   , s.ins_srtdeel_code"
                               + " , dl.ins_deel_opmerking"
                               + " , dl.ins_deel_aantal"
                               + " , s.ins_srtdeel_eenheid"
                               + " , s.ins_srtdeel_key"
                               + " , s.ins_srtdeel_upper"
                               + " , dl.ins_deel_getekend"
                               + " , dl.ins_discipline_key"
                               + " , CASE WHEN dl.ins_alg_ruimte_type IN ('A','P') THEN NULL ELSE alg.alg_district_key END alg_district_key"
                               + " , dl.ins_deel_x" // is coordinaat bekend?
                               + " , dl.ins_deel_y"
                               + " , dl.ins_deel_dwgx" // is dwg coordinaat bekend?
                               + " , dl.ins_deel_dwgy"
                               + " , s.ins_srtgroep_key" // filtering only
                               + " , dl.ins_deel_upper" // filtering only
                               + " , s.ins_srtdeel_uitleenbaar"
                               + " , dl.ins_alg_ruimte_key_org"
                               + " , rd.res_deel_key"
                               + " , rd.res_deel_opmerking"
                               + " , rd.res_deel_count"
                               + (inspDone ? ", (SELECT prs_perslid_naam_full FROM prs_v_perslid_fullnames_all WHERE prs_perslid_key = inspecteur_key) inspecteur" : "")
                               + " , dl.ins_deel_vervaldatum"
                               + " , (SELECT idn2.ins_deel_note_omschrijving"
                               + "				FROM ins_deel_note idn2"
                               + "			   WHERE     idn2.ins_deel_key = dl.ins_deel_key"
                               + "					 AND idn2.ins_deel_note_key ="
                               + "						 (SELECT MAX (idn3.ins_deel_note_key)"
                               + "							FROM ins_deel_note idn3"
                               + "						   WHERE idn3.ins_deel_key = dl.ins_deel_key))"
                               + "				 notitie"
                               + " , (SELECT MAX (idn4.ins_deel_note_aanmaak)"
                               + "				FROM ins_deel_note idn4"
                               + "			   WHERE idn4.ins_deel_key = dl.ins_deel_key)"
                               + "				 notitiedatum"
                               + " , dl.ins_deel_actief"
                               + " , dl.ins_deel_flag"
                               + " , dl.ins_deel_mjb_score1"
                               + " , dl.ins_deel_mjb_score2"
                               + " , s.ins_srtdeel_mjb_grensscore1"
                               + (lentoutAction >= 0 ? " , t.fac_tracking_datum" : "")
                               + (insFlexParams && insFlexParams.anyflex
                                 ?    insFlexParams.sql
                                 : "")
                               + " , CASE WHEN dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'P'"
                               + "        THEN (SELECT p.prs_perslid_naam_full"
                               + "                FROM prs_v_perslid_fullnames_all p"
                               + "               WHERE p.prs_perslid_key = dl.ins_alg_ruimte_key)"
                               + "        WHEN dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'C'"
                               + "        THEN (SELECT " + S("prs_contactpers_string")
                               + "                FROM prs_contactpersoon cp"
                               + "               WHERE cp.prs_contactpersoon_key = dl.ins_alg_ruimte_key)"
                               + "        ELSE NULL"
                               + "        END uitgeleend_aan"
                               + " , dl.ins_alg_ruimte_key alg_ruimte_key"
                               + (groepering == 11
                                 ? " , NULL prs_afdeling_naam"
                                 : "")
                               + sqlKenmerkBewerkbaar_select
                               + " , NULL prs_bedrijf_key"
                               + " , NULL prs_afdeling_key1"
                               + " , CASE WHEN dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'P'"
                               + "        THEN (SELECT p.prs_perslid_email"
                               + "                FROM prs_perslid p"
                               + "               WHERE  p.prs_perslid_key = dl.ins_alg_ruimte_key)"
                               + "        WHEN dl.ins_alg_ruimte_type_org IS NOT NULL AND dl.ins_alg_ruimte_type = 'C'"
                               + "        THEN (SELECT cp.prs_contactpersoon_email"
                               + "                FROM prs_contactpersoon cp"
                               + "               WHERE cp.prs_contactpersoon_key = dl.ins_alg_ruimte_key)"
                               + "        ELSE NULL"
                               + "        END uitgeleend_aan_email"
                               + " , 0 prs_afdeling_key" // department key
                               + (koppel_key? ", ins_deelkoppeling_omschrijving, ins_deelkoppeling_van_key, ins_deelkoppeling_naar_key" : "")
                             : "   , CASE WHEN dl.ins_alg_ruimte_type_org IS NOT NULL"
                               + "        THEN (SELECT p.prs_perslid_naam_full"
                               + "                FROM prs_v_perslid_fullnames_all p"
                               + "               WHERE p.prs_perslid_key = dl.ins_alg_ruimte_key)"
                               + "        ELSE NULL"
                               + "        END uitgeleend_aan"
                               + "     , dl.ins_alg_ruimte_key alg_ruimte_key"
                               + (groepering == 11
                                 ? "   , NULL prs_afdeling_naam"
                                 : ""))
                           + "  FROM ins_v_deelenonderdeel dl"
                           + "     , ins_discipline d"
                           + "     , ins_srtgroep g"
                           + "     , ins_srtdeel s"
                           + (lentoutAction >= 0 ? sqlLentTracking : "")
                           + "     , ins_v_alg_overzicht o"
                           + "     , alg_gebouw bld"
                           + "     , (SELECT d.alg_regio_key"
                               + "         , d.alg_district_key"
                               + "         , l.alg_locatie_key"
                               + "         , l.alg_locatie_omschrijving"
                               + "         , l.alg_locatie_adres"
                               + "         , l.alg_locatie_plaats"
                               + "      FROM alg_district d"
                               + "         , alg_locatie l"
                               + "     WHERE d.alg_district_key = l.alg_district_key"
                               + "    UNION"
                               + "    SELECT NULL, NULL, NULL, NULL, NULL, NULL"
                               + "      FROM DUAL"
                               + "   ) alg"
                           + (groepering == 12
                             ? "   , (SELECT prs_perslid_key_verantw_key"
                               + "         , prs_perslid_naam_full verantwoordelijke"
                               + "         , omschrijving"
                               + "         , alg_gebouw_key"
                               + "         , alg_terreinsector_key"
                               + "      FROM (SELECT COALESCE(prs_perslid_key_verantw, prs_perslid_key_verantw2) prs_perslid_key_verantw_key"
                               + "                 , alg_gebouw_naam omschrijving"  /* was code-naam */
                               + "                 , alg_gebouw_key"
                               + "                 , NULL alg_terreinsector_key"
                               + "              FROM alg_gebouw g"
                               + "            UNION"
                               + "            SELECT COALESCE(prs_perslid_key_verantw2, prs_perslid_key_verantw) prs_perslid_key_verantw_key"
                               + "                 , alg_gebouw_naam omschrijving" /* was code-naam */
                               + "                 , alg_gebouw_key"
                               + "                 , NULL alg_terreinsector_key"
                               + "              FROM alg_gebouw"
                               + "            UNION"
                               + "            SELECT COALESCE(prs_perslid_key_verantw, prs_perslid_key_verantw2) prs_perslid_key_verantw_key"
                               + "                 , alg_terreinsector_naam omschrijving"
                               + "                 , NULL alg_gebouw_key"
                               + "                 , alg_terreinsector_key"
                               + "              FROM alg_terreinsector"
                               + "            UNION"
                               + "            SELECT COALESCE(prs_perslid_key_verantw2, prs_perslid_key_verantw) prs_perslid_key_verantw_key"
                               + "                 , alg_terreinsector_naam omschrijving"
                               + "                 , NULL alg_gebouw_key"
                               + "                 , alg_terreinsector_key"
                               + "              FROM alg_terreinsector) v"
                               + "         , prs_v_perslid_fullnames_all p"
                               + "     WHERE v.prs_perslid_key_verantw_key = p.prs_perslid_key(+)) gtv"
                             : "")
                           + sqlInspectie_from
                           + "     , " + sqlKenmerkBewerkbaar_from
                           + (koppel_key
                             ? ", (SELECT *"
                             + "     FROM ins_deelkoppeling"
                             + "    WHERE     ins_deelkoppeling_van_key = " + koppel_key
                             + "           OR ins_deelkoppeling_naar_key = " + koppel_key + ") idk"
                             : "")
                           + "     , " + ins.getresdeel_sql() + " rd"
                           + "     , " + sqlReservering_from
                           + " WHERE  dl.ins_deel_verwijder IS NULL"
                           + " AND dl.ins_deel_module = 'INS'"
                           + " AND dl.ins_deel_key =  rd.res_ins_deel_key(+)"
                           + " AND dl.ins_discipline_key = d.ins_discipline_key"
                           + " AND s.ins_srtgroep_key = g.ins_srtgroep_key"
                           + " AND s.ins_srtgroep_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + ")"
                           + ( lentoutAction >= 0
                             ? " AND dl.ins_deel_key = t.fac_tracking_refkey" + (lentoutAction == 0 ? "(+)" : "")
                             : ""
                             )
                           + sql_objincl
                           + sqlInspectie_where
                           + sqlKenmerkBewerkbaar_where
                           + " AND s.ins_srtdeel_key = dl.ins_srtdeel_key"
                           + sqlReservering_where
                           + (fronto
                             ? " AND s.ins_srtdeel_uitleenbaar = 1"
                             : "")
                           + ((insLentOut && !insAvail)
                             ? " AND dl.ins_alg_ruimte_key_org IS NOT NULL"
                             : (!insLentOut && insAvail)
                               ? " AND dl.ins_alg_ruimte_key_org IS NULL"
                               : "");

               if (!ins_key_arr && !parent_key && !koppel_key)
               {
                 if (wpl_key)
                   sqlPosition += " AND o.prs_werkplek_key =" + wpl_key;
                 else if (room_key_arr.length)
                   sqlPosition += " AND ((dl.ins_alg_ruimte_key IN (" + room_key_arr.join(",") + ") AND dl.ins_alg_ruimte_type='R')"
                                + " OR (dl.ins_alg_ruimte_key IN (SELECT prs_werkplek_key FROM prs_werkplek WHERE prs_alg_ruimte_key IN (" + room_key_arr.join(",") + ")) AND dl.ins_alg_ruimte_type='W'))";
                 else if (flr_key_arr.length)
                   sqlPosition += " AND o.alg_verdieping_key IN (" + flr_key_arr.join(",") + ")";
                 else if (terr_key_arr.length || bld_key_arr.length)
                 {
                   sqlPosition += " AND (";
                   if (terr_key_arr.length)
                     sqlPosition += "dl.ins_alg_ruimte_key IN (" + terr_key_arr.join(",") + ")";
                   if (terr_key_arr.length && bld_key_arr.length)
                     sqlPosition += " OR ";
                   if (bld_key_arr.length)
                     sqlPosition += " o.alg_gebouw_key IN (" + bld_key_arr.join(",") + ")";
                   sqlPosition += ")";
                   //sqlPosition += " AND (dl.ins_alg_ruimte_key IN (" + terr_key_arr.join(",") + ") OR o.alg_gebouw_key IN (" + bld_key_arr.join(",") + "))";
                 }
                 else if (loc_key_arr.length)
                   sqlPosition += " AND COALESCE(dl.ins_alg_locatie_key, (SELECT d2.ins_alg_locatie_key"
                                + "                                         FROM ins_deel d2"
                                + "                                        WHERE d2.ins_deel_key = dl.ins_deel_parent_key)) IN (" + loc_key_arr.join(",") + ")";
                 else if (dist_key_arr.length)
                   sqlPosition += " AND alg.alg_district_key IN (" + dist_key_arr.join(",") + ")";
                 else if (reg_key_arr.length)
                   sqlPosition += " AND alg.alg_regio_key IN (" + reg_key_arr.join(",") + ")";
                 else if (!terr_key_arr.length && fgraph)
                   sqlPosition += " AND dl.ins_alg_ruimte_key = -1"; // geen terreinen bij fgraph => geen objecten om te laten zien
               }

               if (backo2 && !terr_key_arr.length && inspect)
               {
                 // Als backo2 dan wel de juiste plaatsen waar het bedrijf de scope op heeft.
                 // 1) Scope op gebouwen.
                 // 2) Scope op locaties.
                 // 3) Scope op alle gebouwen en locaties (als er geen enkel gebouw en locatie is geselecteerd bij de dienstlocatiegegevens).
                 sqlPosition += " AND (o.alg_gebouw_key IN (SELECT bdl.alg_gebouw_key"
                              + "                             FROM prs_bedrijfdienstlocatie bdl"
                              + "                            WHERE bdl.prs_dienst_key = ispn.prs_dienst_key"
                              + "                              AND bdl.prs_bedrijf_key IN (SELECT cp.prs_bedrijf_key"
                              + "                                                            FROM prs_contactpersoon cp"
                              + "                                                           WHERE cp.prs_perslid_key = " + user_key + "))"
                              + "   OR dl.ins_alg_locatie_key IN (SELECT bdl.alg_locatie_key"
                              + "                                  FROM prs_bedrijfdienstlocatie bdl"
                              + "                                 WHERE bdl.prs_dienst_key = ispn.prs_dienst_key"
                              + "                                   AND bdl.prs_bedrijf_key IN (SELECT cp.prs_bedrijf_key"
                              + "                                                                 FROM prs_contactpersoon cp"
                              + "                                                                WHERE cp.prs_perslid_key = " + user_key + "))"
                              + "   OR (SELECT COUNT(bdl.prs_bedrijfdienstlocatie_key)"
                              + "         FROM prs_bedrijfdienstlocatie bdl"
                              + "        WHERE bdl.prs_dienst_key = ispn.prs_dienst_key"
                              + "          AND bdl.prs_bedrijf_key IN (SELECT cp.prs_bedrijf_key"
                              + "                                        FROM prs_contactpersoon cp"
                              + "                                       WHERE cp.prs_perslid_key = " + user_key + ")"
                              + "          AND bdl.alg_locatie_key IS NULL"
                              + "          AND bdl.alg_gebouw_key IS NULL) = 1)"
               }

               if (ins_key_arr)
               {
                 sqlPosition += " AND dl.ins_deel_key IN (" + ins_key_arr.join(",") + ")";
               }
               else if (parent_key)
               {
                 sqlPosition += " AND dl.ins_deel_parent_key IN (" + parent_key + ")";
               }
               else if (koppel_key)
               {
                 sqlPosition += " AND idk.ins_deelkoppeling_verwijder IS NULL"
                              + " AND ((     dl.ins_deel_key = idk.ins_deelkoppeling_naar_key"
                              + "        AND idk.ins_deelkoppeling_van_key=" + koppel_key
                              + "      )"
                              + "   OR (     dl.ins_deel_key = idk.ins_deelkoppeling_van_key"
                              + "        AND idk.ins_deelkoppeling_naar_key=" + koppel_key + "))";
               }

               var v_sqlPositionParent = ( params.parent_key
                                         ?   " AND (  (dl.ins_alg_ruimte_type IN ('A','P') AND alg.alg_locatie_key IS NULL)"
                                           + "     OR (dl.ins_alg_ruimte_type NOT IN ('A','P') "
                                           + "         AND alg.alg_locatie_key = o.alg_locatie_key)"
                                           + "     )"
                                         :   " AND alg.alg_locatie_key = o.alg_locatie_key")
                                            +" AND bld.alg_gebouw_key(+) = o.alg_gebouw_key";

               if (auth_org)
                 // Object is uitgeleend.
                 // terr_key is een FGII parameters, dus bij uitlenen nooit gevuld. Gebruik alg_terreinsector_key hoeft niet overwogen te worden zoals hieronder.
                 // Object is uitgeleend en dl.ins_alg_ruimte_type = 'P'.
                 // Eventuele zoekfilters op plaats worden dan ook toegepast op de oorspronkelijke plaats (ins_alg_ruimte_key_org).
               {
                    sqlPosition_org = sqlPosition
                                    + " AND o.alg_onroerendgoed_keys = dl.ins_alg_ruimte_key_org"
                                    + " AND o.alg_onroerendgoed_type = dl.ins_alg_ruimte_type_org"
                                    + " AND dl.ins_alg_ruimte_type_org IN ('T','R','W','A')"
                                    + v_sqlPositionParent;
               }

               sqlPosition += "   AND o.alg_onroerendgoed_keys = dl.ins_alg_ruimte_key"
                            + ( (!inacObjIncl && ((backo && !deel) || !backo))
                              ?  "   AND dl.ins_deel_actief = 1"
                              : ""
                              )
                            // Voor zowel gebouwen als terreinen
                            + " AND o.alg_onroerendgoed_type = dl.ins_alg_ruimte_type"
                            + " AND dl.ins_alg_ruimte_type IN " + ( parent_key
                                                                  ? "('T','R','W','A','P')" // Object is onderdeel, dan wel alle niveaus bekijken.
                                                                  : "('T','R','W','A')"     // Object is NIET uitgeleend, anders was het type "C" of "P".
                                                                  )
                            + v_sqlPositionParent
                            + (groepering == 12
                              ? " AND (o.alg_gebouw_key = gtv.alg_gebouw_key"
                                + " OR o.alg_terreinsector_key = gtv.alg_terreinsector_key)"
                              : "");
             }

             // And some more conditions that apply for both modes (sqlPosition(_org) and hasOwner(_org)):
             var sql_ex = "";
             if (mld_key)
               sql_ex += " AND dl.ins_deel_key IN (SELECT ins_deel_key FROM mld_melding_object WHERE mld_melding_key=" + mld_key + ")";
             if (objsrt_key_arr.length)
               sql_ex += " AND s.ins_srtdeel_key IN (" + objsrt_key_arr.join(",") + ")";
             if (insSensOnly)
               sql_ex += " AND s.ins_srtdeel_sensortype != 0";
             else if (insgroup_key_arr.length)
               sql_ex += " AND s.ins_srtgroep_key IN (" + insgroup_key_arr.join(",") + ")";
             else if (disc_key_arr.length)
               sql_ex += " AND dl.ins_discipline_key IN (" + disc_key_arr.join(",") + ")";

             if (beh_key)
               sql_ex += " AND prs_perslid_key_beh =" + beh_key;
             if (deel)
               sql_ex += " AND dl.ins_deel_upper LIKE " + safe.quoted_sql_wild("%" + deel + "%");
             if (deel_opm)
               sql_ex += " AND UPPER(dl.ins_deel_opmerking) LIKE " + safe.quoted_sql_wild("%" + deel_opm + "%");
             if (note_text)
			       {
               sql_ex += " AND (EXISTS (SELECT 1 FROM ins_deel_note n WHERE n.ins_deel_key = dl.ins_deel_key AND UPPER(ins_deel_note_omschrijving) LIKE " + safe.quoted_sql_wild("%" + note_text + "%") + ")";
               sql_ex += " OR EXISTS (SELECT 1 FROM fac_tracking ft, fac_srtnotificatie fs WHERE UPPER(ft.fac_tracking_oms) LIKE " + safe.quoted_sql_wild("%" + note_text + "%")
                             + " AND ft.fac_srtnotificatie_key = fs.fac_srtnotificatie_key"
                             + " AND fs.fac_srtnotificatie_xmlnode = 'deel' AND fac_tracking_refkey = dl.ins_deel_key))";
             }
             if (objsrt_oms)
               sql_ex += " AND (  (s.ins_srtdeel_upper LIKE " + safe.quoted_sql_wild("%" + objsrt_oms + "%") + ")"
                       + "     OR (s.ins_srtdeel_code_upper LIKE " + safe.quoted_sql_wild("%" + objsrt_oms + "%") + "))";
             if (groep)
               sql_ex += " AND UPPER(groepoms) LIKE " + safe.quoted_sql_wild("%" + groep + "%");
             if (verantw_key)
               sql_ex += " AND dl.ins_alg_ruimte_type IN ('R','T')"
                       + " AND (o.alg_gebouw_key IN (SELECT g.alg_gebouw_key"
                           + "                         FROM alg_v_onroerendgoed aog"
                           + "                            , alg_v_aanweziggebouw g"
                           + "                            , alg_v_aanwezigterreinsector t"
                           + "                        WHERE aog.alg_terreinsector_key = t.alg_terreinsector_key(+)"
                           + "                          AND aog.alg_gebouw_key = g.alg_gebouw_key(+)"
                           + "                          AND (t.prs_perslid_key_verantw  = " + verantw_key
                           + "                            OR t.prs_perslid_key_verantw2 = " + verantw_key
                           + "                            OR g.prs_perslid_key_verantw  = " + verantw_key
                           + "                            OR g.prs_perslid_key_verantw2 = " + verantw_key
                           + "                              )"
                           + "                      )"
                           + " OR"
                           + "  o.alg_terreinsector_key IN (SELECT t.alg_terreinsector_key"
                           + "                                FROM alg_v_onroerendgoed aog"
                           + "                                   , alg_v_aanweziggebouw g"
                           + "                                   , alg_v_aanwezigterreinsector t"
                           + "                               WHERE aog.alg_terreinsector_key = t.alg_terreinsector_key(+)"
                           + "                                 AND aog.alg_gebouw_key = g.alg_gebouw_key(+)"
                           + "                                 AND (t.prs_perslid_key_verantw  = " + verantw_key
                           + "                                   OR t.prs_perslid_key_verantw2 = " + verantw_key
                           + "                                   OR g.prs_perslid_key_verantw  = " + verantw_key
                           + "                                   OR g.prs_perslid_key_verantw2 = " + verantw_key
                           + "                                     )"
                           + "                             )"
                           + " )";

             if (params.flags && params.flags.length > 0 && params.flags.length < S("ins_deel_flags"))
             {
               var filterNull = false;

               for (var i=0; i< params.flags.length; i++)
               {
                 if (params.flags[i] === 0)
                 {
                   filterNull = true;
                 }
               }

               sql_ex += " AND (dl.ins_deel_flag IN (" + params.flags.join(",") + ")";

               if (filterNull)
                 sql_ex += " or dl.ins_deel_flag is null";
               sql_ex += ")";
             }

             if (inspect && ctrdisc_key_arr.length > 0)
               sql_ex += " AND ispn.ctr_disc_key IN (" + ctrdisc_key_arr.join(",") + ")";

             var join_flex_flds = ["dl.ins_deel_key"];
             if (inspect) {
              join_flex_flds.push("ispn.ins_deelsrtcontrole_key");
             }
             sql_ex += getKenmerkSql("INS", join_flex_flds);

             var sql_score = "";
             if (ins_score_enabled)
             {
               // Conditie score.
               // Niet gemeten objecten doen wel mee in dit filter. Deze objecten worden dus niet getoond als er een waarde is ingevuld.
               if (fitness_score1_from > 0)
                 sql_score += " AND dl.ins_deel_mjb_score1 >= " + fitness_score1_from;
               if (fitness_score1_through > 0)
                 sql_score += " AND dl.ins_deel_mjb_score1 <= " + fitness_score1_through;

               // Grenswaarde conditie score.
               // Niet gemeten objecten doen wel mee in dit filter. Deze objecten worden dus niet getoond als er een waarde is ingevuld.
               if (gwfitness_score1_from > 0)
                 sql_score += " AND s.ins_srtdeel_mjb_grensscore1 >= " + gwfitness_score1_from;
               if (gwfitness_score1_through > 0)
                 sql_score += " AND s.ins_srtdeel_mjb_grensscore1 <= " + gwfitness_score1_through;

               // Prioriteitsscore.
               // Niet gemeten objecten doen wel mee in dit filter. Deze objecten worden dus niet getoond als er een waarde is ingevuld.
               if (priority_score2_from > 0)
                 sql_score += " AND dl.ins_deel_mjb_score2 >= " + priority_score2_from;
               if (priority_score2_through > 0)
                 sql_score += " AND dl.ins_deel_mjb_score2 <= " + priority_score2_through;
             }

             // Nu filtercondities voor scores en flexkenmerken toevoegen.
             if (sqlPosition != "")
             {
               sqlPosition += sql_ex + sql_score;
               if (auth_org)
                 sqlPosition_org += sql_ex + sql_score;
             }

             if (sqlPosition != "")
             { // we must consider this: if we know that a room is defined (by filter), we must be
               // able to improve performance by using that condition, mustn't we?
               // furthermore: it's better to let Oracle Prepare
               sqlPosition = discx3d (sqlPosition,
                                      "dl.ins_discipline_key",
                                      "alg.alg_regio_key",
                                      "alg.alg_district_key",
                                      "alg.alg_locatie_key",
                                      "o.alg_gebouw_key",
                                      "o.alg_verdieping_key",
                                      "o.alg_ruimte_key",
                                      "", // b.prs_bedrijf_key: not used because algprs == 0
                                      "", // ab.prs_afdeling_key: not used because algprs == 0
                                      pautfunction,
                                      (disc_key_arr.length? disc_key_arr : []),
                                      0);  // AKZA#430/PF, AKZA#496/MGE

               if (auth_org)
                 sqlPosition_org = discx3d (sqlPosition_org,
                                            "dl.ins_discipline_key",
                                            "alg.alg_regio_key",
                                            "alg.alg_district_key",
                                            "alg.alg_locatie_key",
                                            "o.alg_gebouw_key",
                                            "o.alg_verdieping_key",
                                            "o.alg_ruimte_key",
                                            "", // b.prs_bedrijf_key: not used because algprs == 0
                                            "", // ab.prs_afdeling_key: not used because algprs == 0
                                           pautfunction,
                                           (disc_key_arr.length? disc_key_arr : []),
                                           0);  // AKZA#430/PF, AKZA#496/MGE
             }

             if (sqlOwnerA != "" && sqlOwnerP != "" && sqlOwnerCP != "")
             {
               sqlOwnerA = discx3d (sqlOwnerA,
                                    "dl.ins_discipline_key",
                                    "", // di.alg_regio_key: not used because algprs == 0
                                    "", // l.alg_district_key: not used because algprs == 0
                                    "", // o.alg_locatie_key: not used because algprs == 0
                                    "", // o.alg_gebouw_key: not used because algprs == 0
                                    "", // o.alg_verdieping_key: not used because algprs == 0
                                    "", // o.alg_ruimte_key: not used because algprs == 0
                                    "b.prs_bedrijf_key",
                                    "ab.prs_afdeling_key",
                                    pautfunction,
                                    (disc_key_arr.length? disc_key_arr : []),
                                    1);  // AKZA#430/PF, AKZA#496/MGE

               if (auth_org)
                 sqlOwnerA_org = discx3d (sqlOwnerA_org,
                                          "dl.ins_discipline_key",
                                          "", // di.alg_regio_key: not used because algprs == 0
                                          "", // l.alg_district_key: not used because algprs == 0
                                          "", // o.alg_locatie_key: not used because algprs == 0
                                          "", // o.alg_gebouw_key: not used because algprs == 0
                                          "", // o.alg_verdieping_key: not used because algprs == 0
                                          "", // o.alg_ruimte_key: not used because algprs == 0
                                          "b.prs_bedrijf_key",
                                          "ab.prs_afdeling_key",
                                          pautfunction,
                                          (disc_key_arr.length? disc_key_arr : []),
                                          1);  // AKZA#430/PF, AKZA#496/MGE

               sqlOwnerP = discx3d (sqlOwnerP,
                                    "dl.ins_discipline_key",
                                    "", // di.alg_regio_key: not used because algprs == 0
                                    "", // l.alg_district_key: not used because algprs == 0
                                    "", // o.alg_locatie_key: not used because algprs == 0
                                    "", // o.alg_gebouw_key: not used because algprs == 0
                                    "", // o.alg_verdieping_key: not used because algprs == 0
                                    "", // o.alg_ruimte_key: not used because algprs == 0
                                    "b.prs_bedrijf_key",
                                    "ab.prs_afdeling_key",
                                    pautfunction,
                                    (disc_key_arr.length? disc_key_arr : []),
                                    1);  // AKZA#430/PF, AKZA#496/MGE
               // Geen autorisatie bij externe bedrijven (prs_bedrijf)

               if (auth_org)
                 sqlOwnerP_org = discx3d (sqlOwnerP_org,
                                          "dl.ins_discipline_key",
                                          "", // di.alg_regio_key: not used because algprs == 0
                                          "", // l.alg_district_key: not used because algprs == 0
                                          "", // o.alg_locatie_key: not used because algprs == 0
                                          "", // o.alg_gebouw_key: not used because algprs == 0
                                          "", // o.alg_verdieping_key: not used because algprs == 0
                                          "", // o.alg_ruimte_key: not used because algprs == 0
                                          "b.prs_bedrijf_key",
                                          "ab.prs_afdeling_key",
                                          pautfunction,
                                          (disc_key_arr.length? disc_key_arr : []),
                                          1);  // AKZA#430/PF, AKZA#496/MGE

               // Deelqueries sqlOwnerA en sqlOwnerCP leveren alleen resultaat op als
               // 1) "Beschikbaar" (insAvail) is aangevinkt of
               // 2) Niet naar de _org autorisatie gekeken hoeft te worden (!auth_org).
               //    !auth_org = S("ins_auth_obj_lendout") == 0 || !fronto || !insLentOut;
               //              =  Authorization scope for objects which are lended out is 0=owner(borrower) of
               //                 ik zit niet bij uitleenregistratie of
               //                 object is niet uitgeleend.
               sqlOwner = (insAvail || !auth_org
                          ? sqlOwnerA + sql_ex + sql_score + " UNION " + sqlOwnerCP + sql_ex + sql_score + " UNION "
                          : "")
                        + sqlOwnerP + sql_ex + sql_score
                        + (auth_org // S("ins_auth_obj_lendout") == 1 && fronto && insLentOut
                          ? " UNION " + sqlOwnerA_org + sql_ex + sql_score + " UNION " + sqlOwnerP_org + sql_ex + sql_score + " UNION " + sqlOwnerCP_org + sql_ex + sql_score
                          : "");

               // Now apply user filtering on this query:
               if (persoon_key)
               {
                 sqlOwner = "SELECT * FROM (" + sqlOwner + ") x WHERE x.ins_alg_ruimte_type = 'P' AND x.alg_ruimte_key = " + persoon_key;
               }
               else if (cpersoon_key)
               {
                 sqlOwner = "SELECT * FROM (" + sqlOwner + ") x WHERE x.ins_alg_ruimte_type = 'C' AND x.alg_ruimte_key = " + cpersoon_key;
               }
               else if (dep_key)
               {
                 sqlOwner = "SELECT * FROM (" + sqlOwner + ") x WHERE x.prs_afdeling_key = " + dep_key;
               }
               else if (comp_key)
               {
                 sqlOwner = "SELECT * FROM (" + sqlOwner + ") x WHERE x.prs_bedrijf_key = " + comp_key;
               }
             }

             if (auth_org && sqlPosition != "" && persoon_key)
             {
               sqlPosition_org = "SELECT * FROM (" + sqlPosition_org + ") x WHERE x.ins_alg_ruimte_type = 'P' AND x.alg_ruimte_key = " + persoon_key;
             }

             sql = (sqlOwner != ""
                   ? sqlOwner + (sqlPosition != ""? " UNION ALL " : "")
                   : "")
                 + (!hasOwner
                   ? sqlPosition
                   : "")
                 + (auth_org && sqlPosition != ""
                   ? (!hasOwner? " UNION " : "") + sqlPosition_org
                   : "");

             var sql_bdl = "";
             var sql_cs = "";
             if (inspect)
             {
               sql += " AND (ins_deel_vervaldatum IS NULL OR ins_deel_vervaldatum > SYSDATE)";
               // drie vinkjes 111 is 'te laat', 'binnenkort', 'nog niet'


               // De binnenkort tijden.
               // Let op: Als de "Binnenkort" datums worden veranderd, wordt de tijd aangepast in begin van de dag (00:00).
               //         Als de inspsoonfrom tijd vandaag is moet ook de huidige tijd mee worden genomen. Ander niet.
               var inspsoonfrom_is_today = false;
               var dtsoonfrom = null;
               if (inspsoonfrom)
               {
                 // Als de inspsoonfrom tijd vandaag is moet ook de huidige tijd mee worden genomen. Ander niet.
                 // Als de inspsoon tijden worden veranderd wordt de tijd begin van de dag (00:00).
                 inspsoonfrom_is_today = (inspsoonfrom.midnight().getTime() == new Date().midnight().getTime());
                 if (inspsoonfrom_is_today)
                 { // De inspsoonfrom is vandaag. De huidige tijd meenemen.
                   var time = new Date().getTime() - new Date().midnight().getTime();
                   dtsoonfrom = new Date(inspsoonfrom.midnight().getTime() + time);
                 }
                 else
                   // De inspsoonfrom is NIET vandaag. De tijd wordt begin van de dag (00:00).
                   dtsoonfrom = new Date(inspsoonfrom.midnight().getTime());
               }

               var dtsoonto = null;
               if (inspsoonto)
               {
                 var inspsoonto_is_today = (inspsoonto.midnight().getTime() == new Date().midnight().getTime());
                 if (inspsoonto_is_today)
                    dtsoonto = new Date(inspsoonto.setHours(23, 59, 59)); // Beide datums zijn vandaag. Dan dtsoonto einde van de dag nemen.
                 else if (inspsoonfrom_is_today)
                 { // De inspsoonfrom is vandaag. Ook voor de tot datum de huidige tijd meenemen.
                   var time = new Date().getTime() - new Date().midnight().getTime();
                   dtsoonto = new Date(inspsoonto.midnight().getTime() + time);
                 }
                 else
                   // De inspsoonfrom is NIET vandaag. De tijd wordt eind van de dag (23:59).
                   dtsoonto = new Date(inspsoonto.setHours(23, 59, 59));
               }

               // De afgehandeld tijden.
               // Let op: Als de donedateto tijd vandaag is moet ook de huidige tijd mee worden genomen. Ander niet.
               var donedateto_is_today = false;
               var dtdonedateto = null;
               if (donedateto)
               {
                 // Als de donedateto tijd vandaag is moet ook de huidige tijd mee worden genomen. Ander niet.
                 // Als de donedate tijden worden veranderd wordt de tijd eind van de dag (23:59).
                 donedateto_is_today = (donedateto.midnight().getTime() == new Date().midnight().getTime());
                 if (donedateto_is_today)
                 { // De donedateto is vandaag. De huidige tijd meenemen.
                   var time = new Date().getTime() - new Date().midnight().getTime();
                   dtdonedateto = new Date(donedateto.midnight().getTime() + time);
                 }
                 else
                   // De donedateto is NIET vandaag. De tijd wordt eind van de dag (23:59).
                   dtdonedateto = new Date(donedateto.setHours(23, 59, 59));
               }

               var dtdonedatefrom = null;
               if (donedatefrom)
               {
                 var donedatefrom_is_today = (donedatefrom.midnight().getTime() == new Date().midnight().getTime());
                 if (donedatefrom_is_today)
                    dtdonedatefrom = new Date(donedatefrom.midnight().getTime()); // Beide datums zijn vandaag. Dan dtdonedatefrom begin van de dag nemen.
                 else if (donedateto_is_today)
                 { // De donedateto is vandaag. Ook voor de van datum de huidige tijd meenemen.
                   var time = new Date().getTime() - new Date().midnight().getTime();
                   dtdonedatefrom = new Date(donedatefrom.midnight().getTime() + time);
                 }
                 else
                   // De inspsoonfrom is NIET vandaag. De tijd wordt begin van de dag (00:00).
                   dtdonedatefrom = new Date(donedatefrom.midnight().getTime());
               }

               var sqlBC = (inspClosed || inspBusy
                           ? "x.ins_deelsrtcontrole_status IN ("
                             + (inspBusy? "2, 3" : "")
                             + (inspClosed && inspBusy? ", " : "")
                             + (inspClosed? "5" : "")
                             + ")"
                           : "");

               // Laatste (niet) succesvol uitgevoerde taak.
               var laatste_not_suc = "(SELECT MAX(id2.ins_deelsrtcontrole_key)"
                                   + "   FROM ins_deelsrtcontrole id2"
                                   + "      , ins_controlemode cm"
                                   + "  WHERE id2.ins_controlemode_key = cm.ins_controlemode_key"
                                   + "    AND cm.ins_controlemode_success = 0"
                                   + "    AND id2.ins_deelsrtcontrole_key = (SELECT MAX(ins_deelsrtcontrole_key)"  // Laatste afgeronde inspectie.
                                   + "                                         FROM ins_deelsrtcontrole id3"
                                   + "                                        WHERE id3.ins_deel_key = x.ins_deel_key"
                                   + "                                          AND id3.ins_srtcontrole_key = x.ins_srtcontrole_key"
                                   + "                                          AND id3.ins_scenario_key = 1"
                                   + "                                          AND id3.ins_deelsrtcontrole_status = 6))";

               // inspecties die nog nooit zijn uitgevoerd/ingepland. Er is nog geen ins_deelsrtcontrole regel aanwezig en dus ook geen plandatum/respijtdatum.
               var inspectie_next_A = " CASE"
                                    + " WHEN x.ctr_ismjob = 1"
                                    + " THEN"  // MJOB en er is nog geen inspectie geweest.
                                    // 1) Er is nog geen inspectie geweest en de startdatum is ingevuld of de registratiedatum ligt in de toekomst.
                                    //    Er geldt dan het volgende:
                                    //    Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
                                    //    Voor Vervanging(2) of Certificering(3):
                                    //    a) Als registratiedatum het verst in de toekomst ligt: Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
                                    //    b) Als de startdatum het verst ligt: Eerste inspectie tonen op de startdatum.
                                    //    De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
                                    // 2) a) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Controle(1).
                                    //       Volgende inspectie is in het freeze jaar.
                                    //    b) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Vervanging(2) of Certificering(3).
                                    //       Nextdate is na het freeze jaar?
                                    //       Ja)  Vorige inspectie ligt na het start jaar en ligt niet in het aanmaak jaar?
                                    //            Ja)  Volgende inspectie is in het freeze jaar.
                                    //            Nee) Volgende inspectie is het jaar van de nextdate.
                                    //       Nee) De laatst ingeplande inspectie (nextdate) is na of in het start jaar?
                                    //            Ja)  Volgende inspectie is in het freeze jaar.
                                    //            Nee) Volgende inspectie is in het jaar "nextdatum + periode".
                                    //    c) Kan hier niet voorkomen omdat er nog geen inspectie heeft plaatsgevonden (deze regels worden namenlijk opgeleverd).
                                    + "   COALESCE(CASE"                               // 1) Eventueel startdatum (ins_srtcontroledl_xcp_startdat) i.g.v. als er nog geen inspectie heeft plaatsgevonden.
                                    + "            WHEN x.ins_srtcontroledl_xcp_startdat IS NOT NULL" // Startdatum is ingevuld en er is nog geen inspectie geweest.
                                    + "            THEN" // Startdatum is ingevuld en ligt in het verleden of de toekomst en er is nog geen inspectie geweest.
                                    + "              CASE"
                                    + "              WHEN EXTRACT(YEAR FROM x.ins_srtcontroledl_xcp_startdat) >= EXTRACT(YEAR FROM x.ins_deel_aanmaak)"
                                    + "              THEN" // Startdatum op of na aanmaakdatum/registratiedatum.
                                    + "                CASE"
                                    + "                WHEN EXTRACT(YEAR FROM x.ins_srtcontroledl_xcp_startdat) < " + mjb_freeze_or_sys_year
                                    + "                THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "                ELSE x.ins_srtcontroledl_xcp_startdat"
                                    + "                END"
                                    + "              ELSE" // Aanmaakdatum/Registratiedatum is na de startdatum.
                                    + "                CASE"
                                    + "                WHEN x.ctr_controle_type = 1"  // Controle(1).
                                    + "                THEN"
                                    + "                  CASE"
                                    + "                  WHEN EXTRACT(YEAR FROM x.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                                    + "                  THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "                  ELSE x.ins_deel_aanmaak" // Registratiedatum.
                                    + "                  END"
                                    + "                ELSE"  // Vervanging(2), Certificering(3).
                                    + "                  CASE"
                                    + "                  WHEN EXTRACT(YEAR FROM ADD_MONTHS(x.ins_deel_aanmaak, 12 * x.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                                    + "                  THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "                  ELSE ADD_MONTHS(x.ins_deel_aanmaak, 12 * x.ins_srtcontrole_periode)" // 1 periode na registratiedatum.
                                    + "                  END"
                                    + "                END"
                                    + "              END"
                                    + "            WHEN EXTRACT(YEAR FROM x.ins_deel_aanmaak) >= EXTRACT(YEAR FROM SYSDATE)" // Alleen de aanmaakdatum/registratiedatum is ingevuld.
                                    + "            THEN" // Aanmaakdatum/Registratiedatum is ingevuld en ligt in de toekomst en er is nog geen inspectie geweest.
                                    + "              CASE"
                                    + "              WHEN x.ctr_controle_type = 1"  // Controle(1).
                                    + "              THEN"
                                    + "                CASE"
                                    + "                WHEN EXTRACT( YEAR FROM x.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                                    + "                THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "                ELSE x.ins_deel_aanmaak"
                                    + "                END"
                                    + "              ELSE"  // Vervanging(2), Certificering(3).
                                    + "                CASE"
                                    + "                WHEN EXTRACT( YEAR FROM ADD_MONTHS(x.ins_deel_aanmaak, 12 * x.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                                    + "                THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "                ELSE ADD_MONTHS(x.ins_deel_aanmaak, 12 * x.ins_srtcontrole_periode)"
                                    + "                END"
                                    + "              END"
                                    + "            ELSE"
                                    + "              NULL"
                                    + "            END"
                                    + "          , CASE"                              // 2) Berekenen jaar. Er is nog geen inspectie geweest.
                                    + "            WHEN x.ctr_controle_type = 1"      // 2a) Controle(1).
                                    + "            THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "            WHEN x.ctr_controle_type != 1"     // 2b) Vervanging(2), Certificering(3).
                                    + "            THEN"
                                    + "              CASE"
                                    + "              WHEN EXTRACT(YEAR FROM ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0)) > " + mjb_freeze_or_sys_year
                                    + "              THEN"                             //    Nextdate is na de freeze datum.
                                    + "                CASE"
                                    + "                WHEN EXTRACT(YEAR FROM ADD_MONTHS(ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0), -1 * 12 * x.ins_srtcontrole_periode)) >= " + mjb_start_year + " AND"
                                    + "                     EXTRACT(YEAR FROM ADD_MONTHS(ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0), -1 * 12 * x.ins_srtcontrole_periode)) != EXTRACT(YEAR FROM x.ins_deel_aanmaak)"
                                    + "                THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')" // Nu en vorige inspectie liggen tussen start en freeze jaar.
                                    + "                ELSE ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0)"
                                    + "                END"
                                    + "              ELSE"                             //    Nextdate is voor of in het freeze jaar.
                                    + "                CASE"
                                    + "                WHEN EXTRACT(YEAR FROM ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0)) >= " + mjb_start_year
                                    + "                THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"              // Nextdate tussen start en freeze jaar.
                                    + "                ELSE ADD_MONTHS(ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0), 12 * x.ins_srtcontrole_periode)"  // Nextdate voor het start jaar.
                                    + "                END"
                                    + "              END"
                                    //+ "            ELSE"                               // 2c) Laatste IS NOT NULL. Er is al een inspectie geweest.
                                    //+ "              NULL"                             // Voor deze deelquery geldt, er is nog geen inspectie geweest. Hier kom je nooit.
                                    + "            END)"
                                    + " ELSE"  // Periodieke taken (NIET MJOB)
                                    // Er geldt al dat er nog geen inspectie is geweest.
                                    + "   COALESCE(CASE"
                                    + "            WHEN x.ins_srtcontroledl_xcp_startdat >= x.ins_deel_aanmaak" // Als startdatum en aanmaakdatum/Registratiedatum hetzelfde dan op die datum beginnen.
                                    + "            THEN x.ins_srtcontroledl_xcp_startdat"
                                    + "            ELSE NULL"
                                    + "            END"
                                    + "          , fac.nextcyclusdate(x.ins_deel_aanmaak"
                                    + "                             , x.ins_srtcontrole_mode"
                                    + "                             , x.inspectie_eenheid"
                                    + "                             , x.ins_srtcontrole_periode"
                                    + "                             , x.ins_srtcontrole_bits"
                                    + "                             , 1"
                                    + "                             , x.ctr_ismjob))" // Periode verder als registratiedatum/aanmaakdatum.
                                    + " END";

               var lastinspect_B = "EXISTS (SELECT 1"
                                 + "          FROM ins_deelsrtcontrole idsc"
                                 + "         WHERE idsc.ins_srtcontrole_key = x.ins_srtcontrole_key"
                                 + "           AND idsc.ins_deelsrtcontrole_status IN (5, 6)"
                                 + "           AND idsc.ins_deel_key = x.ins_deel_key"
                                 + "           AND idsc.ins_scenario_key = 1)";

               // Inspecties die al eens zijn uitgevoerd of inspecties die voor het eerst zijn ingepland(0) of gestart(2) maar nog geen uitgevoerde/afgemelde(6) inspectie hebben.
               var inspectie_next_B = " CASE"
                                    + " WHEN x.ctr_ismjob = 1"
                                    + " THEN"  // MJOB en er is nog geen inspectie geweest.
                                    // Query levert 1) uitgevoerde en 2) voor het eerst zijn ingepland(0) of gestart(2) inspecties op.
                                    // Dus met de startdatum hebben we niets te doen en ook verder niet met inspecties die voor het eerst moeten beginnen.
                                    // Bepaling in welk jaar er een inspectie is gepland.
                                    // 1) In het jaar dat er nog een geaccordeerde/bevroren(2) inspectie actief is.
                                    // 2) In het jaar van de plandatum.
                                    // 3) Laatste inpspectie is NIET succesvol (laatste_not_suc IS NOT NULL).
                                    //    Volgende inspectie is in het freeze jaar.
                                    //    Eventuele startdatum doet er niet meer toe, vandaar dit punt eerder controleren.
                                    // 4) Laatste inspectie is niet NULL. Er is al 1 of meerdere keren geinspecteerd.
                                    //    Ligt de laatst ingeplande inspectie (nextdate) na dit jaar?
                                    //      Ja)  Volgende inspectie is het jaar van de nextdate (in de toekomst).
                                    //      Nee) Volgende inspectie is in het freeze jaar.
                                    + "   CASE"
                                    + "   WHEN x.ins_deelsrtcontrole_status IN (2, 3)"  // 1) Taak is geaccordeerd (gefreezed) of ter uitvoering. Bedrag in huidig (vervangings)jaar tonen.
                                    + "   THEN x.ins_deelsrtcontrole_freezedate"
                                    + "   WHEN x.ins_deelsrtcontrole_status = 0"  // 2) Plandatum.
                                    + "   THEN x.ins_deelsrtcontrole_plandatum"
                                    + "   WHEN " + laatste_not_suc + " IS NOT NULL"          // 3) Laatste inspectie is NIET succesvol en er zijn verder geen geplande, geaccordeerde of succesvol uitgevoerde taak aanwezig.
                                    + "   THEN TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"
                                    + "   ELSE"
                                    + "     CASE"
                                    + "     WHEN EXTRACT(YEAR FROM ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0)) > EXTRACT(YEAR FROM SYSDATE)"
                                    + "     THEN ins.nextcyclusdate(x.ins_deel_key, x.ins_srtcontrole_key, 1, 0)"  // Volgende inspectie is in de toekomst.
                                                                                                                   // Geaccordeerde laatste inspectie wordt in het begin al afgevangen.
                                                                                                                   // en niet hier zoals bij org_nextdate in functie getmjblist_sql.
                                    + "     ELSE TO_DATE('31-12-" + mjb_freeze_or_sys_year + "', 'DD-MM-YYYY')"  // Laatst ingeplande inspectie is nog steeds niet uitgevoerd. Dus opnieuw in het freeze jaar tonen zodat deze daar gefreezed kan worden.
                                    + "     END"
                                    + "   END"
                                    + " ELSE"  // Periodieke taken (NIET MJOB)
                                    + "   CASE"
                                    + "   WHEN NOT " + lastinspect_B // Inspectie die voor het eerst is ingepland(0) of gestart(2) maar nog geen uitgevoerde/afgemelde(6) inspectie heeft.
                                    + "   THEN COALESCE(CASE"
                                    + "                 WHEN x.ins_srtcontroledl_xcp_startdat >= x.ins_deel_aanmaak" // Eerste inspectie is ingepland(0) of gestart(2). Als startdatum en aanmaakdatum/Registratiedatum hetzelfde dan op die datum beginnen.
                                    + "                 THEN x.ins_srtcontroledl_xcp_startdat"
                                    + "                 ELSE NULL"
                                    + "                 END"
                                    + "               , CASE"
                                    + "                 WHEN x.ins_deel_aanmaak > SYSDATE AND x.ctr_controle_type = 1" // Eerste inspectie is ingepland(0) of gestart(2).
                                    + "                 THEN x.ins_deel_aanmaak"
                                    + "                 ELSE NULL"
                                    + "                 END"
                                    + "               , fac.nextcyclusdate(x.ins_deel_aanmaak" // Dan registratiedatum + planning
                                    + "                                  , x.ins_srtcontrole_mode"
                                    + "                                  , x.inspectie_eenheid"
                                    + "                                  , x.ins_srtcontrole_periode"
                                    + "                                  , x.ins_srtcontrole_bits"
                                    + "                                  , 1"
                                    + "                                  , x.ctr_ismjob))"
                                    + "   WHEN x.ins_deelsrtcontrole_status IN (0, 2, 3)"
                                    + "   THEN ins_deelsrtcontrole_datum_org" // In status 0, 2 en 3 (eigenlijk kun je niet diret naar 3) wordt de volgende inspectie in ins_deelsrtcontrole_datum_org direct opgeslagen.
                                    + "   ELSE"
                                    + "     fac.nextcyclusdate(CASE"
                                    + "                        WHEN x.ins_srtcontrole_mode = 0"
                                    + "                        THEN x.ins_deelsrtcontrole_datum_org" // Moment modus (0). Uitgaan van eigenlijke/orginele inspectiedatum.
                                    + "                        ELSE x.ins_deelsrtcontrole_datum"     // Interval modus (1). Uitgaan van werkelijke inspectiedatum.
                                    + "                        END"
                                    + "                      , x.ins_srtcontrole_mode"
                                    + "                      , x.inspectie_eenheid"
                                    + "                      , x.ins_srtcontrole_periode"
                                    + "                      , x.ins_srtcontrole_bits"
                                    + "                      , 1"
                                    + "                      , x.ctr_ismjob)"
                                    + "   END"
                                    + " END";

              // De inspectie_next met berekeningen van de nextcyclusdate (database procedure fac.nextcyclusdate()) zo ver mogelijk naar buiten gehaald,
              // zodat deze berekeningen zo laat mogelijk worden berekend met een zo klein mogelijke verzameling resultaten (RABO#60119).
              // Voor RABO ging het aantal aanroepen van fac.nextcyclusdate() van 635279 naar 1888 aanroepen (nog maar 0,3% van de oorspronkelijke aantal aanroepen).
              // De uitvoertijd ging van 2,5-3 minuten naar ongeveer 40 seconden.
               var sel_inspectie_next = " CASE"
                                      + " WHEN ab = 'A'"
                                      + " THEN (" + inspectie_next_A + ")"
                                      + " ELSE (" + inspectie_next_B + ")"
                                      + " END";

               if (inspDone)
               {
                 if (dtdonedatefrom != null && dtdonedateto != null)
                   sql = "SELECT * FROM (" + sql + ") x WHERE inspectie_date BETWEEN " + dtdonedatefrom.toSQL(true) + " AND " + dtdonedateto.toSQL(true);
                 else if (dtdonedatefrom == null && dtdonedateto != null)
                   sql = "SELECT * FROM (" + sql + ") x WHERE inspectie_date < " + dtdonedateto.toSQL(true);
                 else if (dtdonedatefrom != null && dtdonedateto == null)
                   sql = "SELECT * FROM (" + sql + ") x WHERE inspectie_date BETWEEN " + dtdonedatefrom.toSQL(true) + " AND SYSDATE";
                 else if (dtdonedatefrom == null && dtdonedateto == null)
                   sql = "SELECT * FROM (" + sql + ") x WHERE inspectie_date < SYSDATE";
               }
               else if (inspSoon) // Binnenkort is aangevinkt.
               {
                 if (dtsoonfrom != null && dtsoonto != null) // Binnenkort.
                   sql = "SELECT x.*"
                       + "     , " + sel_inspectie_next + " inspectie_next"
                       + "  FROM (" + sql + ") x"
                       + " WHERE (COALESCE(ins_deelsrtcontrole_plandatum, " + sel_inspectie_next + ")"
                       + "        BETWEEN " + dtsoonfrom.toSQL(true)
                       + "            AND " + dtsoonto.toSQL(true)
                       + (sqlBC != ""
                         ? "   OR " + sqlBC
                         : "") + ")";
                 else if (dtsoonfrom == null && dtsoonto != null) // Te laat + binnenkort.
                   sql = "SELECT x.*"
                       + "     , " + sel_inspectie_next + " inspectie_next"
                       + "  FROM (" + sql + ") x"
                       + " WHERE (COALESCE(ins_deelsrtcontrole_plandatum, " + sel_inspectie_next + ") < " + dtsoonto.toSQL(true)
                       + (sqlBC != ""
                         ? "   OR " + sqlBC
                         : "") + ")";
                 else if (dtsoonfrom != null && dtsoonto == null) // Binnenkort + toekomst.
                   sql = "SELECT x.*"
                       + "     , " + sel_inspectie_next + " inspectie_next"
                       + "  FROM (" + sql + ") x"
                       + " WHERE (COALESCE(ins_deelsrtcontrole_plandatum, " + sel_inspectie_next + ") >= " + dtsoonfrom.toSQL(true)
                       + (sqlBC != ""
                         ? "   OR " + sqlBC
                         : "") + ")";
                 else if (dtsoonfrom == null && dtsoonto == null)
                   sql = "SELECT x.*"
                       + "     , " + sel_inspectie_next + " inspectie_next"
                       + "  FROM (" + sql + ") x"
                       + " WHERE 1 = 1"; // Alles tonen onafhankelijk van sqlBC.
               }
               else if (inspBusy || inspClosed) // Onderhanden (inspBusy), vervolgactie vereist (inspClosed).
                 sql = "SELECT x.*"
                     + "     , " + sel_inspectie_next + " inspectie_next"
                     + "  FROM (" + sql + ") x"
                     + " WHERE " + sqlBC;
               else // Geen checkbox aangevinkt.
                 sql = "SELECT x.*"
                     + "     , " + sel_inspectie_next + " inspectie_next"
                     + "  FROM (" + sql + ") x"
                     + " WHERE 1 = 1"; // Alles tonen.

               if (dienst_key > 0)
               {
                 sql += " AND x.prs_dienst_key = " + dienst_key;
               }

               if (backo2)
               {
                 sql += " AND x.prs_dienst_key IN (SELECT DISTINCT bdl.prs_dienst_key"
                      + "                            FROM prs_bedrijfdienstlocatie bdl"
                      + "                           WHERE bdl.prs_dienst_key = x.prs_dienst_key"
                      + "                             AND bdl.prs_bedrijf_key IN (SELECT cp.prs_bedrijf_key"
                      + "                                                           FROM prs_contactpersoon cp"
                      + "                                                          WHERE cp.prs_perslid_key = " + user_key + "))";
               }

               // Als het bedrijf is meegegeven dan kan deze afhankelijk zijn van de bedrijfdienstlocatie of de contractscope.
               // Afhankelijk van de setting "ins_inspect_service_depend" wordt de juiste afhankelijkheid gebruikt.
               // Als het bedrijf niet is meegegeven moet je gewoon alle taken laten zien en is de setting niet van belang.
               if (cnt_bedrijf_key > 0)
               {
                 if (backo2 || (S("ins_inspect_service_depend") == 0 || S("ins_inspect_service_depend") == 2))
                 { // Voorwaarde voor de bedrijfdienstlocatie.
                   sql_bdl = " AND EXISTS (SELECT dl.prs_bedrijf_key"
                           + "               FROM prs_bedrijf b"
                           + "                  , prs_dienst d"
                           + "                  , prs_bedrijfdienstlocatie dl"
                           + "                  , alg_v_allonroerendgoed og"
                           + "              WHERE b.prs_bedrijf_verwijder IS NULL"
                           + "                AND dl.prs_bedrijf_key = b.prs_bedrijf_key"
                           + "                AND d.prs_dienst_key = dl.prs_dienst_key"
                           + "                AND ((dl.alg_locatie_key IS NULL AND dl.alg_gebouw_key IS NULL)"
                           + "                  OR dl.alg_locatie_key = og.alg_locatie_key"
                           + "                  OR dl.alg_gebouw_key = og.alg_gebouw_key)"
                           + "                AND b.prs_bedrijf_intern IS NULL"
                           + "                AND dl.prs_dienst_key = x.prs_dienst_key"
                           + "                AND og.alg_ruimte_key = x.alg_ruimte_key"
                           + "                AND dl.prs_bedrijf_key = " + cnt_bedrijf_key
                   if (bld_key_arr.length)
                     sql_bdl += "             AND (  dl.alg_gebouw_key IN (" + bld_key_arr.join(",") + ")"
                              + "                 OR dl.alg_locatie_key IN (SELECT alg_locatie_key"
                              + "                                             FROM alg_gebouw"
                              + "                                            WHERE alg_gebouw_key IN (" + bld_key_arr.join(",") + ")))";
                   else if (loc_key_arr.length)
                     sql_bdl += "             AND (  dl.alg_locatie_key IN (" + loc_key_arr.join(",") + ")"
                              + "                 OR dl.alg_gebouw_key IN (SELECT alg_gebouw_key"
                              + "                                            FROM alg_gebouw"
                              + "                                           WHERE alg_locatie_key IN (" + loc_key_arr.join(",") + ")))";
                   sql_bdl += "           )";
                 }

                 if (S("ins_inspect_service_depend") >= 1)
                 { // Voorwaarde voor de contractscope.
                   // alleen bedrijven met een (onderhouds)contract op deze soorten
                   // Scope srtcontract_type = 3 (Ondersteuning/Support): Onderhoud op objectsoorten en/of plaats.
                   // Scope op de plaats is een verfijning van de scope op de gehele objectsoort.
                   // Scope op objectsoorten
                   sql_cs = " AND ((((SELECT COUNT(*)"
                          + "           FROM cnt_contract_object co"
                          + "              , cnt_contract c"
                          + "          WHERE co.cnt_contract_key = c.cnt_contract_key"
                          + "            AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "            AND c.cnt_contract_status IN (0, 1)"            // Alleen actieve en gesloten contracten
                          + "            AND cnt_contract_object_verwijder IS NULL) = 0" // Er zijn geen objectsoorten gedefinieerd
                          + "        OR"
                          + "        x.ins_srtdeel_key IN (SELECT cnt_ins_srtdeel_key"
                          + "                                FROM cnt_contract_object co"
                          + "                                   , cnt_contract c"
                          + "                               WHERE c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                                 AND co.cnt_contract_key = c.cnt_contract_key"
                          + "                                 AND co.cnt_contract_object_verwijder IS NULL"
                          + "                                 AND co.cnt_ins_deel_key IS NULL"
                          + "                                 AND c.cnt_contract_status IN (0, 1)"
                          + "                             )"
                          + "         )"
                          // Scope op plaats
                          + "       AND ((SELECT COUNT(*)"
                          + "               FROM cnt_contract_plaats cp"
                          + "                  , cnt_contract c"
                          + "              WHERE cp.cnt_contract_key = c.cnt_contract_key"
                          + "                AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                AND c.cnt_contract_status IN (0, 1)"
                          + "                AND cnt_contract_plaats_verwijder IS NULL) = 0" // Er zijn geen plaatsen gedefinieerd
                          + "             OR"
                          + "             ins_deel_key IN (SELECT d.ins_deel_key" // Delen die gekoppeld zijn aan een ruimte
                          + "                                FROM ins_v_deelenonderdeel d"
                          + "                                   , alg_v_onrgoed_boom ogb"
                          + "                               WHERE d.ins_alg_ruimte_key = ogb.alg_ruimte_key"
                          + "                                 AND d.ins_alg_ruimte_type = 'R'"
                          + "                                 AND ogb.alg_gebouw_key IN (SELECT DISTINCT g.alg_gebouw_key" // Alle gebouwen van de locaties in de scope
                          + "                                                              FROM cnt_contract_plaats cp"
                          + "                                                                 , alg_gebouw g"
                          + "                                                                 , cnt_contract c"
                          + "                                                             WHERE g.alg_locatie_key = cp.cnt_alg_plaats_key"
                          + "                                                               AND cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                               AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                                                               AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                               AND cp.cnt_alg_plaats_code = 'L'"
                          + "                                                               AND c.cnt_contract_status IN (0, 1)"
                          + "                                                            UNION"
                          + "                                                            SELECT DISTINCT cp.cnt_alg_plaats_key" // Alle gebouwen van de gebouwen in de scope
                          + "                                                              FROM cnt_contract_plaats cp"
                          + "                                                                 , cnt_contract c"
                          + "                                                             WHERE cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                               AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                                                               AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                               AND cp.cnt_alg_plaats_code = 'G'"
                          + "                                                               AND c.cnt_contract_status IN (0, 1)"
                          + "                                                           )"
                          + "                              UNION"
                          + "                              SELECT d.ins_deel_key" // Delen die gekoppeld zijn aan een werkplek
                          + "                                FROM ins_v_deelenonderdeel d"
                          + "                                   , prs_werkplek w"
                          + "                                   , alg_v_onrgoed_boom ogb"
                          + "                               WHERE d.ins_alg_ruimte_key = w.prs_werkplek_key"
                          + "                                 AND w.prs_alg_ruimte_key = ogb.alg_ruimte_key"
                          + "                                 AND d.ins_alg_ruimte_type = 'W'"
                          + "                                 AND ogb.alg_gebouw_key IN (SELECT DISTINCT g.alg_gebouw_key" // Alle gebouwen van de locaties in de scope
                          + "                                                              FROM cnt_contract_plaats cp"
                          + "                                                                 , alg_gebouw g"
                          + "                                                                 , cnt_contract c"
                          + "                                                             WHERE g.alg_locatie_key = cp.cnt_alg_plaats_key"
                          + "                                                               AND cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                               AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                                                               AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                               AND cp.cnt_alg_plaats_code = 'L'"
                          + "                                                               AND c.cnt_contract_status IN (0, 1)"
                          + "                                                            UNION"
                          + "                                                            SELECT DISTINCT cp.cnt_alg_plaats_key" // Alle gebouwen van de gebouwen in de scope
                          + "                                                              FROM cnt_contract_plaats cp"
                          + "                                                                 , cnt_contract c"
                          + "                                                             WHERE cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                               AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                                                               AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                               AND cp.cnt_alg_plaats_code = 'G'"
                          + "                                                               AND c.cnt_contract_status IN (0, 1)"
                          + "                                                           )"
                          + "                             )"
                          + "           )"
                          // Objecten mogen niet individueel in contractscope zitten van een ander bedrijf
                          + "       AND ins_deel_key NOT IN (SELECT co.cnt_ins_deel_key"
                          + "                                  FROM cnt_contract_object co"
                          + "                                     , cnt_contract c"
                          + "                                 WHERE co.cnt_contract_key = c.cnt_contract_key"
                          + "                                   AND co.cnt_ins_deel_key IS NOT NULL"
                          + "                                   AND co.cnt_contract_object_verwijder IS NULL"
                          + "                                   AND c.cnt_prs_bedrijf_key != " + cnt_bedrijf_key
                          + "                                   AND c.cnt_contract_status IN (0, 1)"
                          + "                                   AND c.cnt_contract_looptijd_van <= SYSDATE" // Alleen actuele contracten
                          + "                                   AND SYSDATE <= c.cnt_contract_looptijd_tot)"
                          // Objecten mogen ook niet qua objectsoort in contractscope zitten van een ander bedrijf
                          + "       AND ins_deel_key NOT IN (SELECT d1.ins_deel_key" // Alle objecten via plaatsscope van andere bedrijven die ook dezelfde objectscope hebben (gekoppeld aan een ruimte)
                          + "                                  FROM ins_v_deelenonderdeel d1"
                          + "                                     , alg_v_onrgoed_boom ogb"
                          + "                                 WHERE d1.ins_alg_ruimte_key = ogb.alg_ruimte_key"
                          + "                                   AND d1.ins_alg_ruimte_type = 'R'" // gekoppeld aan een ruimte
                          + "                                   AND x.ins_srtdeel_key = d1.ins_srtdeel_key"
                          + "                                   AND ogb.alg_gebouw_key IN (SELECT DISTINCT g.alg_gebouw_key" // Alle gebouwen via plaatsscope van andere bedrijven die ook dezelfde objectscope hebben
                          + "                                                                FROM cnt_contract_plaats cp"
                          + "                                                                   , alg_gebouw g"
                          + "                                                                   , cnt_contract c"
                          + "                                                                   , cnt_contract_object co"
                          + "                                                               WHERE g.alg_locatie_key = cp.cnt_alg_plaats_key"
                          + "                                                                 AND cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND c.cnt_prs_bedrijf_key != " + cnt_bedrijf_key
                          + "                                                                 AND c.cnt_contract_looptijd_van <= SYSDATE" // Alleen actuele contracten
                          + "                                                                 AND SYSDATE <= c.cnt_contract_looptijd_tot"
                          + "                                                                 AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                                 AND cp.cnt_alg_plaats_code = 'L'"
                          + "                                                                 AND co.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND co.cnt_ins_srtdeel_key = d1.ins_srtdeel_key"
                          + "                                                                 AND c.cnt_contract_status IN (0, 1)"
                          + "                                                               UNION"
                          + "                                                              SELECT DISTINCT cp.cnt_alg_plaats_key"
                          + "                                                                FROM cnt_contract_plaats cp"
                          + "                                                                   , cnt_contract c"
                          + "                                                                   , cnt_contract_object co"
                          + "                                                               WHERE cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND c.cnt_prs_bedrijf_key != " + cnt_bedrijf_key
                          + "                                                                 AND c.cnt_contract_looptijd_van <= SYSDATE" // Alleen actuele contracten
                          + "                                                                 AND SYSDATE <= c.cnt_contract_looptijd_tot"
                          + "                                                                 AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                                 AND cp.cnt_alg_plaats_code = 'G'"
                          + "                                                                 AND co.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND co.cnt_ins_srtdeel_key = d1.ins_srtdeel_key"
                          + "                                                                 AND c.cnt_contract_status IN (0, 1))"
                          + "                                UNION"
                          + "                                SELECT d1.ins_deel_key" // Alle objecten via plaatsscope van andere bedrijven die ook dezelfde objectscope hebben (gekoppeld aan een werkplek)
                          + "                                  FROM ins_v_deelenonderdeel d1"
                          + "                                     , prs_werkplek w"
                          + "                                     , alg_v_onrgoed_boom ogb"
                          + "                                 WHERE d1.ins_alg_ruimte_key = w.prs_werkplek_key"
                          + "                                   AND w.prs_alg_ruimte_key = ogb.alg_ruimte_key"
                          + "                                   AND d1.ins_alg_ruimte_type = 'W'" // gekoppeld aan een werkplek
                          + "                                   AND ogb.alg_gebouw_key IN (SELECT DISTINCT g.alg_gebouw_key" // Alle gebouwen via plaatsscope van andere bedrijven die ook dezelfde objectscope hebben
                          + "                                                                FROM cnt_contract_plaats cp"
                          + "                                                                   , alg_gebouw g"
                          + "                                                                   , cnt_contract c"
                          + "                                                                   , cnt_contract_object co"
                          + "                                                               WHERE g.alg_locatie_key = cp.cnt_alg_plaats_key"
                          + "                                                                 AND cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND c.cnt_prs_bedrijf_key != " + cnt_bedrijf_key
                          + "                                                                 AND c.cnt_contract_looptijd_van <= SYSDATE" // Alleen actuele contracten
                          + "                                                                 AND SYSDATE <= c.cnt_contract_looptijd_tot"
                          + "                                                                 AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                                 AND cp.cnt_alg_plaats_code = 'L'"
                          + "                                                                 AND co.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND co.cnt_ins_srtdeel_key = d1.ins_srtdeel_key"
                          + "                                                                 AND c.cnt_contract_status IN (0, 1)"
                          + "                                                              UNION"
                          + "                                                              SELECT DISTINCT cp.cnt_alg_plaats_key"
                          + "                                                                FROM cnt_contract_plaats cp"
                          + "                                                                   , cnt_contract c"
                          + "                                                                   , cnt_contract_object co"
                          + "                                                               WHERE cp.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND c.cnt_prs_bedrijf_key != " + cnt_bedrijf_key
                          + "                                                                 AND c.cnt_contract_looptijd_van <= SYSDATE" // Alleen actuele contracten
                          + "                                                                 AND SYSDATE <= c.cnt_contract_looptijd_tot"
                          + "                                                                 AND cnt_contract_plaats_verwijder IS NULL"
                          + "                                                                 AND cp.cnt_alg_plaats_code = 'G'"
                          + "                                                                 AND co.cnt_contract_key = c.cnt_contract_key"
                          + "                                                                 AND co.cnt_ins_srtdeel_key = d1.ins_srtdeel_key"
                          + "                                                                 AND c.cnt_contract_status IN (0, 1))"
                          + "                               )"
                          + "       )"
                          // Scope srtcontract_type = 1 (Onderhoud/Maintenance): Onderhoud op objecten.
                          // Scope op de objecten.
                          + "    OR ins_deel_key IN (SELECT co.cnt_ins_deel_key"
                          + "                          FROM cnt_contract_object co"
                          + "                             , cnt_contract c"
                          + "                         WHERE co.cnt_contract_key = c.cnt_contract_key"
                          + "                           AND co.cnt_ins_deel_key IS NOT NULL"
                          + "                           AND co.cnt_contract_object_verwijder IS NULL"
                          + "                           AND c.cnt_prs_bedrijf_key = " + cnt_bedrijf_key
                          + "                           AND c.cnt_contract_status IN (0, 1)"
                          + "                       )"
                          + "      )";
                 }
               }

               // Bij taken die afhankelijk zijn van objectscope wordt het bedrijf niet in het overzicht getoond.
               // Als we bij de taken die geen dienst bij de soort controle (ins_srtcontrole) hebben ingevuld het bedrijf willen tonen dan moeten we naar de objectscope kijken.
               // Als we dit willen doen dan duurt de query langer als 1,5 min en krijg je een timeout op de pagina.
               // Dit kan niet en daarom laten we in dat geval "objectscope" zien bij het bedrijf en zoeken we het bedrijf via die weg niet op.
               var sql_main = "SELECT xx.*"
                            + (inspect
                              ? "     , CASE"
                                + "     WHEN (SELECT COUNT(dl.prs_dienst_key)"
                                + "             FROM prs_bedrijf b"
                                + "                , prs_dienst d"
                                + "                , prs_bedrijfdienstlocatie dl"
                                + "                , alg_v_aanweziglocatie l"
                                + "                , alg_v_aanweziggebouw g"
                                + "                , alg_v_allonroerendgoed og"
                                + "            WHERE b.prs_bedrijf_verwijder IS NULL"
                                + "              AND dl.prs_bedrijf_key = b.prs_bedrijf_key"
                                + "              AND d.prs_dienst_key = dl.prs_dienst_key"
                                + "              AND l.alg_locatie_key(+) = dl.alg_locatie_key"
                                + "              AND g.alg_gebouw_key(+) = dl.alg_gebouw_key"
                                + "              AND (dl.alg_locatie_key = og.alg_locatie_key"
                                + "                OR (dl.alg_locatie_key IS NULL"
                                + "                AND dl.alg_gebouw_key IS NULL)"
                                + "                OR dl.alg_gebouw_key IN (SELECT g2.alg_gebouw_key"
                                + "                                           FROM alg_gebouw g2"
                                + "                                          WHERE g2.alg_gebouw_key = og.alg_gebouw_key"
                                + "                                            AND g2.alg_locatie_key = og.alg_locatie_key))"
                                + "              AND b.prs_bedrijf_intern IS NULL"
                                + "              AND dl.prs_dienst_key = xx.prs_dienst_key"
                                + "              AND og.alg_ruimte_key = xx.alg_ruimte_key"
                                + "          ) = 1"
                                + "     THEN (SELECT b.prs_bedrijf_naam"
                                + "             FROM prs_bedrijf b"
                                + "                , prs_dienst d"
                                + "                , prs_bedrijfdienstlocatie dl"
                                + "                , alg_v_aanweziglocatie l"
                                + "                , alg_v_aanweziggebouw g"
                                + "                , alg_v_allonroerendgoed og"
                                + "            WHERE b.prs_bedrijf_verwijder IS NULL"
                                + "              AND dl.prs_bedrijf_key = b.prs_bedrijf_key"
                                + "              AND d.prs_dienst_key = dl.prs_dienst_key"
                                + "              AND l.alg_locatie_key(+) = dl.alg_locatie_key"
                                + "              AND g.alg_gebouw_key(+) = dl.alg_gebouw_key"
                                + "              AND (dl.alg_locatie_key = og.alg_locatie_key"
                                + "                OR (dl.alg_locatie_key IS NULL"
                                + "                AND dl.alg_gebouw_key IS NULL)"
                                + "                OR dl.alg_gebouw_key IN (SELECT g2.alg_gebouw_key"
                                + "                                           FROM alg_gebouw g2"
                                + "                                          WHERE g2.alg_gebouw_key = og.alg_gebouw_key"
                                + "                                            AND g2.alg_locatie_key = og.alg_locatie_key))"
                                + "              AND b.prs_bedrijf_intern IS NULL"
                                + "              AND dl.prs_dienst_key = xx.prs_dienst_key"
                                + "              AND og.alg_ruimte_key = xx.alg_ruimte_key"
                                + "          )"
                                + "     WHEN (SELECT COUNT(dl.prs_dienst_key)"
                                + "             FROM prs_bedrijf b"
                                + "                , prs_dienst d"
                                + "                , prs_bedrijfdienstlocatie dl"
                                + "                , alg_v_aanweziglocatie l"
                                + "                , alg_v_aanweziggebouw g"
                                + "                , alg_v_allonroerendgoed og"
                                + "            WHERE b.prs_bedrijf_verwijder IS NULL"
                                + "              AND dl.prs_bedrijf_key = b.prs_bedrijf_key"
                                + "              AND d.prs_dienst_key = dl.prs_dienst_key"
                                + "              AND l.alg_locatie_key(+) = dl.alg_locatie_key"
                                + "              AND g.alg_gebouw_key(+) = dl.alg_gebouw_key"
                                + "              AND (dl.alg_locatie_key = og.alg_locatie_key"
                                + "                OR (dl.alg_locatie_key IS NULL"
                                + "                AND dl.alg_gebouw_key IS NULL)"
                                + "                OR dl.alg_gebouw_key IN (SELECT g2.alg_gebouw_key"
                                + "                                           FROM alg_gebouw g2"
                                + "                                          WHERE g2.alg_gebouw_key = og.alg_gebouw_key"
                                + "                                            AND g2.alg_locatie_key = og.alg_locatie_key))"
                                + "              AND b.prs_bedrijf_intern IS NULL"
                                + "              AND dl.prs_dienst_key = xx.prs_dienst_key"
                                + "              AND og.alg_ruimte_key = xx.alg_ruimte_key"
                                + "          ) > 1"
                                + "     THEN " + safe.quoted_sql(L("lcl_prs_bedrijf_m"))
                                + "          || ' ('"
                                + "          || (SELECT COUNT(dl.prs_dienst_key) "
                                + "                FROM prs_bedrijf b"
                                + "                   , prs_dienst d"
                                + "                   , prs_bedrijfdienstlocatie dl"
                                + "                   , alg_v_aanweziglocatie l"
                                + "                   , alg_v_aanweziggebouw g"
                                + "                   , alg_v_allonroerendgoed og"
                                + "               WHERE b.prs_bedrijf_verwijder IS NULL"
                                + "                 AND dl.prs_bedrijf_key = b.prs_bedrijf_key"
                                + "                 AND d.prs_dienst_key = dl.prs_dienst_key"
                                + "                 AND l.alg_locatie_key(+) = dl.alg_locatie_key"
                                + "                 AND g.alg_gebouw_key(+) = dl.alg_gebouw_key"
                                + "                 AND (dl.alg_locatie_key = og.alg_locatie_key"
                                + "                   OR (dl.alg_locatie_key IS NULL"
                                + "                   AND dl.alg_gebouw_key IS NULL)"
                                + "                   OR dl.alg_gebouw_key IN (SELECT g2.alg_gebouw_key"
                                + "                                           FROM alg_gebouw g2"
                                + "                                          WHERE g2.alg_gebouw_key = og.alg_gebouw_key"
                                + "                                            AND g2.alg_locatie_key = og.alg_locatie_key))"
                                + "                 AND b.prs_bedrijf_intern IS NULL"
                                + "                 AND dl.prs_dienst_key = xx.prs_dienst_key"
                                + "                 AND og.alg_ruimte_key = xx.alg_ruimte_key)"
                                + "          || ')'"
                                + "     ELSE " + safe.quoted_sql(L("lcl_ins_unknown"))
                                + "     END prs_bedrijf_naam"
                                + (mobile
                                  ? (insFlexParams && insFlexParams.anyflex
                                    ? insFlexParams.sql
                                    : ", NULL insflex")
                                  : "")
                              : "")
                            + "  FROM (" + sql + "{0}) XX";

               // Als het bedrijf is meegegeven dan kan deze afhankelijk zijn van de bedrijfdienstlocatie of de contractscope.
               // Afhankelijk van de setting "ins_inspect_service_depend" wordt de juiste afhankelijkheid gebruikt.
               if (cnt_bedrijf_key > 0)
               {
                 sql = (S("ins_inspect_service_depend") == 0 || S("ins_inspect_service_depend") == 2
                       ? sql_main.format(sql_bdl)
                       : "")
                     + (S("ins_inspect_service_depend") == 2
                       ? " UNION "
                       : "")
                     + (S("ins_inspect_service_depend") >= 1
                       ? sql_main.format(sql_cs)
                       : "");
                 if (S("ins_inspect_service_depend") == 2)
                   sql = "SELECT * FROM (" + sql + ") XXX"; // Extra SELECT/FROM eromheen anders foutmelding.
               }
               else
               {
                 sql = sql_main.format("");
               }
             }
             else if (groepering == -1)
             {
               sql = "SELECT * FROM (" + sql + ") XX";
             }
             else if (groepering == 1)
             { // Discipline.
               sql = "SELECT ins_discipline_key"
                   + "     , ins_disc_oms"
                   + "     , COUNT(ins_discipline_key) aantal"
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY ins_discipline_key"
                   + "        , ins_disc_oms";
             }
             else if (groepering == 2)
             { // Groep.
               sql = "SELECT ins_srtgroep_key"
                   + "     , ins_disc_oms"
                   + "     , ins_groep_oms"
                   + "     , COUNT(ins_srtgroep_key) aantal"
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY ins_srtgroep_key"
                   + "        , ins_disc_oms"
                   + "        , ins_groep_oms";
             }
             else if (groepering == 3)
             { // Objectsoort.
               sql = "SELECT ins_srtdeel_key"
                   + "     , ins_disc_oms"
                   + "     , ins_groep_oms"
                   + "     , soort"
                   + "     , COUNT(ins_srtdeel_key) aantal"
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY ins_srtdeel_key"
                   + "        , ins_disc_oms"
                   + "        , ins_groep_oms"
                   + "        , soort";
             }
             else if (groepering == 5)
             { // Locatie.
               sql = "SELECT alg_locatie_key"
                   + "     , alg_locatie_omschrijving"
                   + "     , COUNT(CASE WHEN alg_locatie_key IS NULL THEN -1 ELSE alg_locatie_key END) aantal" // Er moet een key zijn anders worden ze niet mee geteld.
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY alg_locatie_key"
                   + "        , alg_locatie_omschrijving";
             }
             else if (groepering == 6)
             { // Gebouw/Terrein.
               sql = "SELECT geb_ter_key"
                   + "     , alg_locatie_omschrijving"
                   + "     , geb_ter_omschrijving"
                   + "     , COUNT(CASE WHEN geb_ter_key IS NULL THEN -1 ELSE geb_ter_key END) aantal" // Er moet een key zijn anders worden ze niet mee geteld.
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY geb_ter_key"
                   + "        , alg_locatie_omschrijving"
                   + "        , geb_ter_omschrijving";
             }
             else if (groepering == 11)
             { // Afdeling.
               sql = "SELECT prs_afdeling_key"
                   + "     , prs_afdeling_naam"
                   + "     , COUNT(CASE WHEN prs_afdeling_key IS NULL THEN -1 ELSE prs_afdeling_key END) aantal" // Er moet een key zijn anders worden ze niet mee geteld.
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY prs_afdeling_key"
                   + "        , prs_afdeling_naam";
             }
             else if (groepering == 12)
             { // Afdeling.
               sql = "SELECT prs_perslid_key_verantw_key"
                   + "     , verantwoordelijke"
                   + "     , COUNT(CASE WHEN prs_perslid_key_verantw_key IS NULL THEN -1 ELSE prs_perslid_key_verantw_key END) aantal" // Er moet een key zijn anders worden ze niet mee geteld.
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY prs_perslid_key_verantw_key"
                   + "        , verantwoordelijke";
             }
             else if (groepering == 13)
             { // Afdeling.
               sql = "SELECT prs_perslid_key_beh"
                   + "     , objectbeheerder"
                   + "     , COUNT(CASE WHEN prs_perslid_key_beh IS NULL THEN -1 ELSE prs_perslid_key_beh END) aantal" // Er moet een key zijn anders worden ze niet mee geteld.
                   + "  FROM (" + sql + ") XX"
                   + " GROUP BY prs_perslid_key_beh"
                   + "        , objectbeheerder";
             }

             if (inspect || groepering == -1)
               sql += " ORDER BY"
                    + (koppel_key? " CASE WHEN xx.ins_deel_key = ins_deelkoppeling_van_key THEN 1 ELSE 0 END," : "")
                    + (outputmode == 2 // excel moet objecten met gelijke kenmerken bij elkaar hebben
                      ? " ins_srtdeel_upper, plaats, soort, ins_deel_omschrijving"
                      : (mobile? " plaats, ins_deel_omschrijving, soort" : (inspect && !inspDone? " inspectie_next," : "") + " ins_deel_omschrijving"
                                + (inspDone? ", inspectie_date" : "")
                                + ", plaats, ins_disc_oms, ins_groep_oms, soort"));
             else
             {
               sql += " ORDER BY 2";
             }

             return sql;
           },

       getmjblist_sql:
           function (params)
           { // Lever de mjbsearchlist sql op.
             var ins_score_enabled = S("ins_score_enabled") == 1;
             var inflatiepct = S("mjb_inflation");
             var inflatiefactor = 1 + (inflatiepct / 100);
             var mjb_start_year = S("mjb_start_year");
             var mjb_freeze_or_sys_year = Math.max(S("mjb_freeze_year"), new Date().getFullYear());
             var keys = params.keys;
             var niveau = params.niveau;
             var scenario = params.scenario;
             var fulldetails = params.fulldetails;
             var show_scenario_oms = params.show_scenario_oms;
             var actsit = params.actsit;
             var showunfin = params.showunfin;
             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 bld_key_arr = params.bld_key_arr;
             var disc_key_arr = params.disc_key_arr;
             var srtgroep_key_arr = params.srtgroep_key_arr;
             var srtdeel_key_arr = params.srtdeel_key_arr;
             var srtgebouw_key_arr = params.srtgebouw_key_arr;
             var verantw_key = params.verantw_key;
             var beheerder_key = params.beheerder_key;
             var groep_str_arr = params.groep_str_arr;
             var categorie_key_arr = params.categorie_key_arr;
             var srtcontrole_key_arr = params.srtcontrole_key_arr;
             var frequentie_arr = params.frequentie_arr;
             var kp_key_arr = params.kp_key_arr;
             var incbtw = params.incbtw;
             var toyear = params.toyear;
             var groupby = params.groupby;
             var moredetail = params.moredetail; // 0,1,2
             var deel = params.deel;
             var fitness_score1_from = params.fitness_score1_from;
             var fitness_score1_through = params.fitness_score1_through;
             var fitness_score1_from_neg = params.fitness_score1_from_neg;
             var fitness_score1_through_neg = params.fitness_score1_through_neg;
             var fitness_score1_from_pos = params.fitness_score1_from_pos;
             var fitness_score1_through_pos = params.fitness_score1_through_pos;
             var priority_score2_from = params.priority_score2_from;
             var priority_score2_through = params.priority_score2_through;
             var mjbMoved = params.mjbMoved;
             var mjbFreezed = params.mjbFreezed;
             var mjbXcped = params.mjbXcped;
             var mjbStatus2 = params.mjbStatus2;
             var mjbStatus3 = params.mjbStatus3;
             var sel_controlemode123 = params.sel_controlemode123;
             var jaren = params.jaren;
             var freeze = params.freeze;
             var unfreeze = params.unfreeze;
             var execute = params.execute;
             var pricechange = params.pricechange;
             var finish = params.finish;
             var addToScenario = params.addToScenario;
             var getsumtypes = params.getsumtypes;
             var deelscore1 = params.deelscore1;
             var deelscore2 = params.deelscore2;
             var mjb_show_srt_with_tasks = S("mjb_show_srt_with_tasks") == 1;
             var algFlexParams = params.algFlexParams;
             var insFlexParams = params.insFlexParams;

             // De datum (jaar) van de *eerstvolgende* onderhoudsbeurt volgt uit:
             //   Datum laatste (/laatste geplande) inspectie
             //         of anders: ins_deel_aanmaak
             //   waarbij verondersteld wordt dat inspecties in het verleden wel zijn uitgevoerd

             function getSglComponenten(modus)
             { // SQL van objecten met:
               // Modus 1) de aankomende inspecties in het huidige jaar en in de toekomst.
               //          - Bij goedgekeurd (voor het freezjaar): de nextdate inspectie of de ingeplande inspectie en verdere inspecties in de toekomst.
               //          - Bij afgekeurd (voor het freezjaar): direct weer in het freeze jaar en verdere inspecties in de toekomst. (Let op dat afgekeurde de eerste inspectie wel of niet is)
               //          - Bij gefreezed zonder ingeplande inspectie: de gefreezede inspectie en verdere inspecties in de toekomst.
               //          - Bij gefreezed met ingeplande inspectie: de ingeplande inspectie en verdere inspecties in de toekomst.
               //       2) de goedgekeurde en afgekeurde inspecties in het freeze-jaar en ervoor.
               //       3) de gefreezed en ter uitvoering staande inspectie (???in het jaar voor het freezejaar???) indien er ook een inspectie gepland is in de toekomst
               //          (er zijn dan twee lopende inspectie records aanwezig).

               // Bepaling in welk jaar er een inspectie is gepland.
               // 1) In het jaar dat er nog een geaccordeerde/bevroren(2) inspectie actief is.
               // 2) In het jaar van de plandatum.
               // 3) Laatste inpspectie is NIET succesvol (laatste_not_suc IS NOT NULL).
               //    De NIET succesvolle taak is in het freeze jaar
               //    Ja)  Volgende inspectie is in het jaar na het freeze jaar.
               //    Nee) Volgende inspectie is in het freeze jaar.
               // 4) Er is nog geen inspectie geweest en de startdatum is ingevuld of de registratiedatum ligt in de toekomst.
               //    Er geldt dan het volgende:
               //    Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
               //    Voor Vervanging(2) of Certificering(3):
               //    a) Als registratiedatum het verst in de toekomst ligt: Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
               //    b) Als de startdatum het verst ligt: Eerste inspectie tonen op de startdatum.
               //    De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
               // 5) a) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Controle(1).
               //       Volgende inspectie is in het freeze jaar.
               //    b) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Vervanging(2) of Certificering(3).
               //       Nextdate is na het freeze jaar?
               //       Ja)  Vorige inspectie ligt na het start jaar en ligt niet in het aanmaak jaar?
               //            Ja)  Volgende inspectie is in het freeze jaar.
               //            Nee) Volgende inspectie is het jaar van de nextdate.
               //       Nee) De laatst ingeplande inspectie (nextdate) is na of in het start jaar?
               //            Ja)  Volgende inspectie is in het freeze jaar.
               //            Nee) Volgende inspectie is in het jaar "nextdatum + periode".
               //    c) Laatste inspectie is niet NULL. Er is al 1 of meerdere keren geinspecteerd.
               //       Ligt de laatst ingeplande inspectie (nextdate) na dit jaar?
               //         Ja)  Volgende inspectie is het jaar van de nextdate (in de toekomst).
               //         Nee) Volgende inspectie is in het freeze jaar.
               // LET OP: c.laatste_acc_suc: geeft de ins_deelsrtcontrole_datum terug van de laatste geaccordeerde of succesvol uitgevoerde taak.
               //         laatste_not_suc: Als de laatste uitgevoerde taak NIET succesvoll is geeft deze de ins_deelsrtcontrole_datum terug van deze taak.
               // P.S.: De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
               var sql_vervangingsjaar = (modus == 1
                  ? " EXTRACT (YEAR FROM COALESCE(CASE "                              // 1) Taak is geaccordeerd (gefreezed) of ter uitvoering. Bedrag in huidig (vervangings)jaar tonen.
                    + "                           WHEN COALESCE(c.ins_deelsrtcontrole_status, e.ins_deelsrtcontrole_status) IN (2, 3) AND (COALESCE(c.isPlanned, e.isPlanned) = 0 OR COALESCE(c.isPlanned, e.isPlanned) IS NULL)"
                    + "                           THEN c.ins_deelsrtcontrole_freezedate"
                    + "                           ELSE NULL"
                    + "                           END"
                    + "                         , CASE" // 2) Plandatum.
                    + "                           WHEN COALESCE(c.plandatum, e.plandatum) IS NOT NULL"
                    + "                           THEN"
                    + "                             CASE"
                    + "                             WHEN EXTRACT(YEAR FROM COALESCE(c.plandatum, e.plandatum)) < " + mjb_freeze_or_sys_year
                    + "                             THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                             ELSE COALESCE(c.plandatum, e.plandatum)"
                    + "                             END"
                    + "                           ELSE NULL"
                    + "                           END"
                    + "                         , CASE"                               // 3) Laatste inspectie is NIET succesvol en er zijn verder geen geplande, geaccordeerde of succesvol uitgevoerde taak aanwezig.
                    + "                           WHEN e.laatste_not_suc IS NOT NULL AND c.laatste_acc_suc IS NULL"
                    + "                           THEN"
                    + "                             CASE"
                    + "                             WHEN EXTRACT(YEAR FROM e.laatste_jaar) = " + mjb_freeze_or_sys_year
                    + "                             THEN TO_DATE('" + (mjb_freeze_or_sys_year + 1) + "', 'YYYY')"
                    + "                             ELSE TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                           END"
                    + "                           ELSE NULL"
                    + "                           END"
                    + "                         , CASE"                               // 4) Eventueel startdatum (ins_srtcontroledl_xcp_startdat) i.g.v. als er nog geen inspectie heeft plaatsgevonden.
                    + "                           WHEN c.laatste_acc_suc IS NULL AND"         //    Als er al een inspectie is geweest, is de startdatum niet meer van belang.
                    + "                                e.ins_srtcontroledl_xcp_startdat IS NOT NULL" // Startdatum is ingevuld en er is nog geen inspectie geweest.
                    + "                           THEN" // Startdatum is ingevuld en ligt in het verleden of de toekomst en er is nog geen inspectie geweest.
                    + "                             CASE"
                    + "                             WHEN EXTRACT(YEAR FROM e.ins_srtcontroledl_xcp_startdat) >= EXTRACT(YEAR FROM e.ins_deel_aanmaak)"
                    + "                             THEN" // Startdatum op of na aanmaakdatum/registratiedatum.
                    + "                               CASE"
                    + "                               WHEN EXTRACT(YEAR FROM e.ins_srtcontroledl_xcp_startdat) < " + mjb_freeze_or_sys_year
                    + "                               THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                               ELSE e.ins_srtcontroledl_xcp_startdat"
                    + "                               END"
                    + "                             ELSE" // Aanmaakdatum/Registratiedatum is na de startdatum.
                    + "                               CASE"
                    + "                               WHEN e.ctr_controle_type = 1"  // Controle(1).
                    + "                               THEN"
                    + "                                 CASE"
                    + "                                 WHEN EXTRACT(YEAR FROM e.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                    + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                                 ELSE e.ins_deel_aanmaak" // Registratiedatum.
                    + "                                 END"
                    + "                               ELSE"  // Vervanging(2), Certificering(3).
                    + "                                 CASE"
                    + "                                 WHEN EXTRACT(YEAR FROM ADD_MONTHS(e.ins_deel_aanmaak, 12 * e.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                    + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                                 ELSE ADD_MONTHS(e.ins_deel_aanmaak, 12 * e.ins_srtcontrole_periode)" // 1 periode na registratiedatum.
                    + "                                 END"
                    + "                               END"
                    + "                             END"
                    + "                           WHEN c.laatste_acc_suc IS NULL AND"
                    + "                                EXTRACT(YEAR FROM e.ins_deel_aanmaak) >= EXTRACT(YEAR FROM SYSDATE)" // Alleen de aanmaakdatum/registratiedatum is ingevuld.
                    + "                           THEN" // Aanmaakdatum/Registratiedatum is ingevuld en ligt in de toekomst en er is nog geen inspectie geweest.
                    + "                             CASE"
                    + "                             WHEN e.ctr_controle_type = 1"  // Controle(1).
                    + "                             THEN"
                    + "                               CASE"
                    + "                               WHEN EXTRACT( YEAR FROM e.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                    + "                               THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                               ELSE e.ins_deel_aanmaak"
                    + "                               END"
                    + "                             ELSE"  // Vervanging(2), Certificering(3).
                    + "                               CASE"
                    + "                               WHEN EXTRACT( YEAR FROM ADD_MONTHS(e.ins_deel_aanmaak, 12 * e.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                    + "                               THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                    + "                               ELSE ADD_MONTHS(e.ins_deel_aanmaak, 12 * e.ins_srtcontrole_periode)"
                    + "                               END"
                    + "                             END"
                    + "                           ELSE NULL"
                    + "                           END"
                    + "                         , CASE"                               // 5) Berekenen jaar.
                    + "                           WHEN c.laatste_acc_suc IS NULL AND e.ctr_controle_type = 1"  // Controle(1).
                    + "                           THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')" // 5a)
                    + "                           WHEN c.laatste_acc_suc IS NULL AND e.ctr_controle_type != 1" // Vervanging(2), Certificering(3).
                    + "                           THEN"                               // 5b) Er is nog geen inspectie geweest
                    + "                             CASE"
                    + "                             WHEN EXTRACT(YEAR FROM e.nextdate) > " + mjb_freeze_or_sys_year
                    + "                             THEN"                             // Nextdate is na de freeze datum.
                    + "                               CASE"
                    + "                               WHEN EXTRACT(YEAR FROM ADD_MONTHS(e.nextdate, -1 * 12 * e.ins_srtcontrole_periode)) >= " + mjb_start_year + " AND"
                    + "                                    EXTRACT(YEAR FROM ADD_MONTHS(e.nextdate, -1 * 12 * e.ins_srtcontrole_periode)) != EXTRACT(YEAR FROM e.ins_deel_aanmaak)"
                    + "                               THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')" // Nu en vorige inspectie liggen tussen start en freeze jaar.
                    + "                               ELSE e.nextdate"
                    + "                               END"
                    + "                             ELSE"                             // Nextdate is voor of in het freeze jaar.
                    + "                               CASE"
                    + "                               WHEN EXTRACT(YEAR FROM e.nextdate) >= " + mjb_start_year
                    + "                               THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"       // Nextdate tussen start en freeze jaar.
                    + "                               ELSE ADD_MONTHS(e.nextdate, 12 * e.ins_srtcontrole_periode)"  // Nextdate voor het start jaar.
                    + "                               END"
                    + "                             END"
                    + "                           ELSE"                               // 5c) Laatste IS NOT NULL. Er is al een inspectie geweest.
                    + "                             CASE"
                    + "                             WHEN EXTRACT(YEAR FROM e.nextdate) > EXTRACT(YEAR FROM SYSDATE)"
                    + "                             THEN e.nextdate"                  // Volgende inspectie is in de toekomst.
                                                                                      // Geaccordeerde laatste inspectie wordt in het begin al afgevangen.
                                                                                      // en niet hier zoals bij org_nextdate.
                    + "                             ELSE TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"  // Laatst ingeplande inspectie is nog steeds niet uitgevoerd. Dus opnieuw in het freeze jaar tonen zodat deze daar gefreezed kan worden.
                    + "                             END"
                    + "                           END))"
                  : (modus == 2
                    ? " EXTRACT(YEAR FROM c.ins_deelsrtcontrole_datum)"
                    : " EXTRACT(YEAR FROM c.ins_deelsrtcontrole_freezedate)")) + " vervangingsjaar";

               var sql_componenten =
                    " SELECT e.ins_deel_key"
                  + "      , e.ins_srtcontroledl_xcp_key"
                  + "      , e.ins_srtcontrole_key"
                  + "      , e.ins_srtcontrole_level"
                  + "      , e.ins_srtcontrole_groep"
                  + "      , e.ins_srtcontrole_omschrijving"
                  + (modus == 1
                    ? "    , e.ins_srtcontrole_info"
                      + "  , e.ins_srtcontrole_kosten"
                      + "  , e.ins_srtcontrole_kosten2"
                      + "  , e.ins_srtcontrole_kosten3"
                      + "  , e.ins_srtcontrole_materiaal"
                      + "  , e.ins_srtcontrole_percentage"
                      + "  , e.ins_srtdeel_omschrijving"
                    : "")
                  + "      , e.ins_srtcontrole_periode"
                  + "      , e.ins_srtcontrole_eenheid"
                  + "      , e.ins_srtcontrole_opmerking"
                  + "      , " + sql_vervangingsjaar
                  + "      , e.nextdate"
                  + "      , c.laatste_acc_suc"
                  + "      , e.laatste_not_suc"
                  + "      , e.laatste_jaar"
                  + "      , c.ins_deelsrtcontrole_datum"
                  + (modus != 1
                    ? "    , c.ins_deelsrtcontrole_freezecost bedrag"
                      + "  , 1 hierlevel"
                    : "")
                  + "      , e.ins_deel_aantal"
                  + "      , e.ins_srtdeel_eenheid"
                  + "      , e.ins_srtcontrole_eind"
                  + "      , e.ins_srtcontrole_afbouwtijd"
                  + "      , e.prs_kostenplaats_key"
                  + "      , e.fin_btwtabelwaarde_key"
                  + "      , e.ins_srtcontroledl_xcp_startdat"
                  + "      , e.ins_srtcontroledl_xcp_prio"
                  + "      , e.ins_srtcontroledl_xcp_eind"
                  + "      , e.ctr_controle_type"
                  + "      , e.ctr_discipline_key"
                  + "      , e.ins_scenario_key"
                  + "      , e.hasscenario2"
                  + "      , e.scenario_oms"
                  + "      , e.scenario_aantal"
                  // Alleen een c record als er al een geplande, geaccordeerde of succesvol uitgevoerde inspectie is.
                  // Alleen een e record als er in de aangegeven periode een inpectie gepland is.
                  // Dus bij lege regels wordt daarom de COALESCE genomen.
                  + "      , COALESCE(c.ins_deelsrtcontrole_freezedate, e.ins_deelsrtcontrole_freezedate) ins_deelsrtcontrole_freezedate"
                  + "      , COALESCE(c.ins_deelsrtcontrole_freezecost, e.ins_deelsrtcontrole_freezecost) ins_deelsrtcontrole_freezecost"
                  + "      , COALESCE(c.ins_deelsrtcontrole_status, e.ins_deelsrtcontrole_status) ins_deelsrtcontrole_status"
                  + "      , COALESCE(c.ins_deelsrtcontrole_datum_org, e.ins_deelsrtcontrole_datum_org) ins_deelsrtcontrole_datum_org" // Als er nog geen afgeronde inspectie is, dan heeft c geen record en is c.ins_deelsrtcontrole_datum_org NULL.
                  + "      , COALESCE(c.plandatum, e.plandatum) plandatum" // Als er nog geen inspectie is, dan heeft c geen record en is c.plandatum NULL.
                  + "      , COALESCE(c.isPlanned, e.isPlanned) isPlanned"
                  + "      , CASE"
                  + "        WHEN c.hascontroles IS NULL"
                  + "        THEN 0"
                  + "        ELSE c.hascontroles"
                  + "        END hascontroles"
                  + "      , succes"
                  + "   FROM (SELECT el.ins_deel_key"
                  + "              , el.ins_srtcontroledl_xcp_key"
                  + "              , el.ins_srtcontrole_omschrijving"
                  + (modus == 1
                    ? "              , el.ins_srtcontrole_info"
                      + "            , el.ins_srtcontrole_kosten"
                      + "            , el.ins_srtcontrole_kosten2"
                      + "            , el.ins_srtcontrole_kosten3"
                      + "            , el.ins_srtcontrole_materiaal"
                      + "            , el.ins_srtcontrole_percentage"
                      + "            , (SELECT ins_srtdeel_omschrijving FROM ins_srtdeel where ins_srtdeel_key = el.ins_srtdeel_key) ins_srtdeel_omschrijving"
                    : "")
                  + "              , el.ins_deel_aanmaak"
                  + "              , el.ins_srtcontrole_periode"
                  + "              , el.ins_srtcontrole_eenheid"
                  + "              , el.ins_srtcontrole_opmerking"
                  + "              , el.ins_srtcontrole_key"
                  + "              , el.ins_srtcontrole_level"
                  + "              , el.ins_srtcontrole_groep"
                  + "              , el.ins_deel_aantal"
                  + "              , el.ins_srtdeel_eenheid"
                  + "              , el.ins_srtcontrole_eind"
                  + "              , el.ins_srtcontrole_afbouwtijd"
                  + "              , el.prs_kostenplaats_key"
                  + "              , el.fin_btwtabelwaarde_key"
                  + "              , (SELECT MAX(ins_deelsrtcontrole_freezedate)" // Laatste freezedate.
                  + "                   FROM ins_deelsrtcontrole id2"
                  + "                  WHERE id2.ins_deel_key = el.ins_deel_key"
                  + "                    AND id2.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                    AND id2.ins_scenario_key = 1"
                  + "                    AND id2.ins_deelsrtcontrole_status = 6) ins_deelsrtcontrole_freezedate"
                  + "              , (SELECT id2.ins_deelsrtcontrole_freezecost" // Laatste freezecost.
                  + "                   FROM ins_deelsrtcontrole id2"
                  + "                  WHERE id2.ins_deelsrtcontrole_key = (SELECT MAX(ins_deelsrtcontrole_key)"
                  + "                                                         FROM ins_deelsrtcontrole id3"
                  + "                                                        WHERE id3.ins_deel_key = el.ins_deel_key"
                  + "                                                          AND id3.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                                                          AND id3.ins_scenario_key = 1"
                  + "                                                          AND id3.ins_deelsrtcontrole_status = 6)) ins_deelsrtcontrole_freezecost"
                  // Deze ins_deelsrtcontrole_status wordt later alleen gebruikt indien er geen uitgevoerde taak is.
                  // Status is dus NULL of de status van een lopende inspectie (0, 2, 3 of 5).
                  + "              , CASE"
                  + "                WHEN (SELECT MAX(ins_deelsrtcontrole_key)"
                  + "                        FROM ins_deelsrtcontrole id2"
                  + "                       WHERE id2.ins_deel_key = el.ins_deel_key"
                  + "                         AND id2.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                         AND id2.ins_scenario_key = 1"
                  + "                         AND id2.ins_deelsrtcontrole_status < 6) IS NOT NULL"
                  + "                THEN (SELECT ins_deelsrtcontrole_status"
                  + "                        FROM ins_deelsrtcontrole id2"
                  + "                       WHERE id2.ins_deelsrtcontrole_key = (SELECT MAX(ins_deelsrtcontrole_key)"
                  + "                                                              FROM ins_deelsrtcontrole id3"
                  + "                                                             WHERE id3.ins_deel_key = el.ins_deel_key"
                  + "                                                               AND id3.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                                                               AND id3.ins_scenario_key = 1"
                  + "                                                               AND id3.ins_deelsrtcontrole_status < 6))"
                  + "                ELSE null" // Status van het laatste uitgevoerde taak.
                  + "                END ins_deelsrtcontrole_status"
                  + "              , CASE"
                  + "                WHEN (SELECT idsc.ins_deelsrtcontrole_key"
                  + "                        FROM ins_deelsrtcontrole idsc"
                  + "                       WHERE idsc.ins_deel_key = el.ins_deel_key"
                  + "                        AND idsc.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                        AND idsc.ins_deelsrtcontrole_status IN (0)"
                  + "                        AND idsc.ins_scenario_key = el.ins_scenario_key) IS NOT NULL"
                  + "                THEN 1"
                  + "                ELSE null"
                  + "                END isPlanned"
                  + "              , (SELECT MAX( dsc1.ins_deelsrtcontrole_datum_org)"
                  + "                   FROM ins_deelsrtcontrole dsc1"
                  + "                  WHERE dsc1.ins_deel_key = el.ins_deel_key"
                  + "                    AND dsc1.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                    AND dsc1.ins_scenario_key = el.ins_scenario_key) ins_deelsrtcontrole_datum_org"
                  + "              , (SELECT MAX(dsc1.ins_deelsrtcontrole_plandatum)"
                  + "                   FROM ins_deelsrtcontrole dsc1"
                  + "                  WHERE dsc1.ins_deel_key = el.ins_deel_key"
                  + "                    AND dsc1.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                    AND dsc1.ins_scenario_key = el.ins_scenario_key"
                  + "                    AND dsc1.ins_deelsrtcontrole_status < 5) plandatum"
                  // Laatste (niet) succesvol uitgevoerde taak.
                  + "              , (SELECT MAX(id2.ins_deelsrtcontrole_key)"
                  + "                   FROM ins_deelsrtcontrole id2"
                  + "                      , ins_controlemode cm"
                  + "                  WHERE id2.ins_controlemode_key = cm.ins_controlemode_key"
                  + "                    AND cm.ins_controlemode_success = 0"
                  + "                    AND id2.ins_deelsrtcontrole_key = (SELECT MAX(ins_deelsrtcontrole_key)"  // Laatste afgeronde inspectie.
                  + "                                                         FROM ins_deelsrtcontrole id3"
                  + "                                                        WHERE id3.ins_deel_key = el.ins_deel_key"
                  + "                                                          AND id3.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                                                          AND id3.ins_scenario_key = 1"
                  + "                                                          AND id3.ins_deelsrtcontrole_status = 6)"
                  + "                ) laatste_not_suc"
                  + "              , (SELECT MAX(id3.ins_deelsrtcontrole_datum)"
                  + "                   FROM ins_deelsrtcontrole id3"
                  + "                  WHERE id3.ins_deel_key = el.ins_deel_key"
                  + "                    AND id3.ins_srtcontrole_key = el.ins_srtcontrole_key"
                  + "                    AND id3.ins_scenario_key = 1"
                  + "                    AND id3.ins_deelsrtcontrole_status = 6) laatste_jaar"
                  + "              , el.ins_srtcontroledl_xcp_startdat"
                  + "              , el.ins_srtcontroledl_xcp_prio"
                  + "              , el.ins_srtcontroledl_xcp_eind"
                  + "              , el.ctr_controle_type"
                  + "              , el.ctr_discipline_key"
                  + "              , ins.nextcyclusdate(el.ins_deel_key, el.ins_srtcontrole_key, el.ins_scenario_key, 0) nextdate"
                  + "              , el.ins_scenario_key"
                  + (scenario > 1
                    ? "            , COALESCE(CASE"
                      + "                     WHEN EXISTS (SELECT 1" // Heeft de periodieke taak ook de meegegeven scenario "scenario".
                      + "                                    FROM ins_srtcontroledl_xcp xcp2"
                      + "                                   WHERE xcp2.ins_deel_key = el.ins_deel_key"
                      + "                                     AND xcp2.ins_srtcontrole_key = el.ins_srtcontrole_key"
                      + "                                     AND xcp2.ins_scenario_key = " + scenario + ")"
                      + "                     THEN 1"
                      + "                     ELSE NULL"
                      + "                     END"
                      + "                   , 0)"
                    : "            , 0") + " hasscenario2"
                  + ((fulldetails && scenario == 1) || show_scenario_oms
                    ? "            , (SELECT LISTAGG(isc.ins_scenario_omschrijving, ', ') WITHIN GROUP (ORDER BY isc.ins_scenario_omschrijving)"
                      + "               FROM ins_srtcontroledl_xcp xcp"
                      + "                  , ins_scenario isc"
                      + "              WHERE xcp.ins_scenario_key = isc.ins_scenario_key "
                      + "                AND xcp.ins_srtcontrole_key = el.ins_srtcontrole_key"
                      + "                AND isc.ins_scenario_key <> 1"  // actuele situatie niet meenemen
                      + "                AND xcp.ins_deel_key = el.ins_deel_key)"
                    : "            , 'dummy'") + " scenario_oms"
                  + ((fulldetails && scenario == 1) || show_scenario_oms
                    ? "            , (SELECT COUNT(isc.ins_scenario_omschrijving)"
                      + "               FROM ins_srtcontroledl_xcp xcp"
                      + "                  , ins_scenario isc"
                      + "              WHERE xcp.ins_scenario_key = isc.ins_scenario_key"
                      + "                AND xcp.ins_srtcontrole_key = el.ins_srtcontrole_key"
                      + "                AND isc.ins_scenario_key <> 1"  // actuele situatie niet meetellen
                      + "                AND xcp.ins_deel_key = el.ins_deel_key)"
                    : "            , -1") + " scenario_aantal"
                  + "           FROM ins_v_defined_inspect_xcp el"
                  + "          WHERE el.ins_srtcontrole_periode > 0"
                  + (scenario == 1
                    ? "          AND ins_scenario_key = 1"
                    : (actsit
                         ? ""
                         : "     AND ins_scenario_key = " + scenario))
                  + "            AND el.ctr_ismjob = 1"
                  // Je moet read CTRUSE/CTRSEN rechten hebben op de CTR disciplines om de taken te kunnen zien.
                  + "            AND el.ctr_discipline_key IN (SELECT w.ins_discipline_key"
                  + "                                            FROM fac_v_webgebruiker w"
                  + "                                               , fac_functie f"
                  + "                                           WHERE w.fac_functie_key = f.fac_functie_key "
                  + "                                             AND f.fac_functie_code IN (" + (scenario == 1? "'WEB_CTRUSE'" : (actsit? "'WEB_CTRUSE', 'WEB_CTRSEN'" : "'WEB_CTRSEN'")) + ")"
                  + "                                             AND w.fac_gebruiker_prs_level_read < 9"
                  + "                                             AND w.fac_gebruiker_alg_level_read < 9"
                  + "                                             AND w.prs_perslid_key = " + user_key
                  + "                                             AND w.ins_discipline_key = el.ctr_discipline_key)"
                  // Vroeg filteren is *heel* goed voor performance
                  + (reg_key_arr && reg_key_arr.length && !dist_key_arr.length  // bij fijner filter is dit overbodig
                    ? "          AND el.ins_alg_locatie_key IN (SELECT alg_locatie_key FROM alg_locatie l, alg_district d WHERE l.alg_district_key = d.alg_district_key AND d.alg_regio_key IN (" + reg_key_arr.join(",") + "))"
                    : "")
                  + (dist_key_arr.length && !loc_key_arr.length  // bij fijner filter is dit overbodig
                    ? "          AND el.ins_alg_locatie_key IN (SELECT alg_locatie_key FROM alg_locatie WHERE alg_district_key IN (" + dist_key_arr.join(",") + "))"
                    : "")
                  + (loc_key_arr.length
                    ? "          AND el.ins_alg_locatie_key IN (" + loc_key_arr.join(",") + ")"
                    : "")
                  + (bld_key_arr.length // elders in dit bestand wordt scherper gefilterd, deze is voor de performance
                    ? "          AND el.ins_alg_locatie_key IN (SELECT alg_locatie_key FROM alg_gebouw WHERE alg_gebouw_key IN (" + bld_key_arr.join(",") + ")"
                      + "                                       UNION"
                      + "                                       SELECT alg_locatie_key FROM alg_terreinsector WHERE alg_terreinsector_key IN (" + bld_key_arr.join(",") + "))"
                    : "")
                  + (disc_key_arr.length
                    ? "          AND el.ins_discipline_key IN (" + disc_key_arr.join(",") + ")"
                    : "")
                  + (srtgroep_key_arr.length
                    ? "          AND el.ins_srtgroep_key IN (" + srtgroep_key_arr.join(",") + ")"
                    : "")
                  + (srtdeel_key_arr.length
                    ? "          AND el.ins_srtdeel_key IN (" + srtdeel_key_arr.join(",") + ")"
                    : "")
                  + (srtgebouw_key_arr.length // elders in dit bestand wordt scherper gefilterd, deze is voor de performance
                    ? "          AND el.ins_alg_locatie_key IN (SELECT alg_locatie_key FROM alg_gebouw WHERE alg_srtgebouw_key IN (" + srtgebouw_key_arr.join(",") + "))"
                    : "")
                  + (groep_str_arr.length > 0
                    ? "          AND UPPER(ins_srtcontrole_groep) IN (" + safe.quoted_sql_join(groep_str_arr, true) + ")"
                    : "")
                  + (categorie_key_arr.length > 0
                    ? "          AND el.ctr_discipline_key IN (" + categorie_key_arr.join(",") + ")"
                    : "")
                  + (srtcontrole_key_arr.length > 0
                    ? "          AND el.ins_srtcontrole_key IN (" + srtcontrole_key_arr.join(",") + ")"
                    : "")
                  + (frequentie_arr.length > 0
                    ? "          AND el.ins_srtcontrole_periode IN (" + frequentie_arr.join(",") + ")"
                    : "")
                  + (kp_key_arr.length
                    ? "          AND el.prs_kostenplaats_key IN (" + kp_key_arr.join(",") +")"
                    : "")
                  + "        ) e"
                  // Laatste geplande, geaccordeerde of succesvol uitgevoerde taak.
                  + "        LEFT OUTER JOIN"
                  + "        (SELECT dsc.ins_srtcontrole_key"
                  + "              , dsc.ins_deel_key"
                  + "              , dsc.ins_scenario_key"
                  // Mode 1: Freeze gegevens van het laatste succesvol uitgevoerde, geplande of bevroren/geaccordeerde record (laatste succesvol uitgevoerde, geplande of bevroren/geaccordeerde taak).
                  //         Alleen geplande, geaccordeerde en de succesvol uitgevoerde taken/inspecties tellen mee in de bepaling van volgende taken/inspecties.
                  // Mode 2:
                  // Mode 3: Freeze gegevens van laatste WEL of NIET succesvolle afgeronde/uitgevoerde taak.
                  //         Om uiteindelijk 1 regel over te houden, moet deze waarde voor alle regels hetzelfde zijn.
                  //         Daarom is het bij modus 2 nodig om de lopende freeze gegevens op te halen, indien er een lopende taak is.
                  //         Later kan dan de juiste waarde genomen worden, zodat toch alle regels samen genomen kunnen worden tot 1 regel.
                  + "              , dsc.ins_deelsrtcontrole_freezedate" // Wordt niet helemaal doorgeven naar de eerste SELECT (cv). In de eerste SELECT is alleen de laatste freezedate (max) nodig.
                  + "              , dsc.ins_deelsrtcontrole_freezecost"
                  + "              , CASE"
                  // Eerst kijken of er een lopende reservering is.
                  + "                WHEN (SELECT MAX(ins_deelsrtcontrole_key)"
                  + "                        FROM ins_deelsrtcontrole id2"
                  + "                       WHERE id2.ins_deel_key = dsc.ins_deel_key"
                  + "                         AND id2.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                         AND id2.ins_scenario_key = 1"
                  + "                         AND id2.ins_deelsrtcontrole_status < 6) IS NOT NULL"
                  + "                THEN (SELECT ins_deelsrtcontrole_status"
                  + "                        FROM ins_deelsrtcontrole id2"
                  + "                       WHERE id2.ins_deelsrtcontrole_key = (SELECT MAX(ins_deelsrtcontrole_key)"
                  + "                                                              FROM ins_deelsrtcontrole id3"
                  + "                                                             WHERE id3.ins_deel_key = dsc.ins_deel_key"
                  + "                                                               AND id3.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                                                               AND id3.ins_scenario_key = 1"
                  + "                                                               AND id3.ins_deelsrtcontrole_status < 6))"
                  // Nu kijken naar een succesvolle inspectie.
                  + "                WHEN dsc.ins_controlemode_key IS NOT NULL AND"
                  + "                     (SELECT cm.ins_controlemode_success"
                  + "                        FROM ins_controlemode cm"
                  + "                       WHERE cm.ins_controlemode_key = dsc.ins_controlemode_key) = 0"
                  + "                THEN  CASE"
                  + "                      WHEN (SELECT COUNT(ins_deelsrtcontrole_datum)"
                  + "                              FROM ins_deelsrtcontrole id2"
                  + "                                 , ins_controlemode cm"
                  + "                             WHERE id2.ins_controlemode_key = cm.ins_controlemode_key"
                  + "                               AND id2.ins_deel_key = dsc.ins_deel_key"
                  + "                               AND id2.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                               AND id2.ins_scenario_key = 1"
                  + "                               AND cm.ins_controlemode_success = 1) > 0"
                  + "                      THEN 6"
                  + "                      ELSE null"
                  + "                      END"
                  + "                ELSE dsc.ins_deelsrtcontrole_status" // Status van het laatste uitgevoerde taak.
                  + "                END ins_deelsrtcontrole_status"
                  + "              , CASE"
                  + "                WHEN (SELECT idsc.ins_deelsrtcontrole_key"
                  + "                        FROM ins_deelsrtcontrole idsc"
                  + "                       WHERE idsc.ins_deel_key = dsc.ins_deel_key"
                  + "                        AND idsc.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                        AND idsc.ins_deelsrtcontrole_status IN (0)"
                  + "                        AND idsc.ins_scenario_key = dsc.ins_scenario_key) IS NOT NULL"
                  + "                THEN 1"
                  + "                ELSE null"
                  + "                END isPlanned"
                  + "              , (SELECT MAX( dsc1.ins_deelsrtcontrole_datum_org)"
                  + "                   FROM ins_deelsrtcontrole dsc1"
                  + "                  WHERE dsc1.ins_deel_key = dsc.ins_deel_key"
                  + "                    AND dsc1.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                    AND dsc1.ins_scenario_key = dsc.ins_scenario_key) ins_deelsrtcontrole_datum_org"
                  + "              , (SELECT MAX(dsc1.ins_deelsrtcontrole_plandatum)"
                  + "                   FROM ins_deelsrtcontrole dsc1"
                  + "                  WHERE dsc1.ins_deel_key = dsc.ins_deel_key"
                  + "                    AND dsc1.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                    AND dsc1.ins_scenario_key = dsc.ins_scenario_key"
                  + "                    AND dsc1.ins_deelsrtcontrole_status < 5) plandatum"
                  // Laatste geaccordeerde of succesvol uitgevoerde taak. (Geplande taken niet meenemen voor bepaling originele inspectiedatum en vervangingsjaar).
                  + "            , (SELECT MAX(ins_deelsrtcontrole_key)"
                  + "                 FROM ins_deelsrtcontrole id2"
                  + "                    , ins_controlemode cm"
                  + "                WHERE id2.ins_controlemode_key = cm.ins_controlemode_key(+)"
                  + "                  AND id2.ins_deel_key = dsc.ins_deel_key"
                  + "                  AND id2.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                  AND id2.ins_scenario_key = 1"
                  + "                  AND (cm.ins_controlemode_success = 1 OR (id2.ins_deelsrtcontrole_status > 1 AND id2.ins_deelsrtcontrole_status < 6))"
                  + "              ) laatste_acc_suc"
                  + "            , (SELECT MAX(ins_deelsrtcontrole_datum)"
                  + "                 FROM ins_deelsrtcontrole id2"
                  + "                WHERE id2.ins_deel_key = dsc.ins_deel_key"
                  + "                  AND id2.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                  AND id2.ins_scenario_key = 1)"
                  + "                  ins_deelsrtcontrole_datum"
                  + "              , CASE"
                  + "                WHEN (SELECT COUNT(sdc.ins_deelsrtcontrole_key)"
                  + "                        FROM ins_deelsrtcontrole sdc"
                  + "                           , ins_controlemode cm"
                  + "                       WHERE sdc.ins_controlemode_key = cm.ins_controlemode_key"
                  + "                         AND sdc.ins_deel_key = dsc.ins_deel_key"
                  + "                         AND sdc.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                         AND sdc.ins_deelsrtcontrole_status = 6"
                  + "                         AND sdc.ins_scenario_key = 1"
                  + "                         AND cm.ins_controlemode_success = 1) > 0"  // Alleen succesvol uitgevoerde taken/inspecties tellen mee.
                  + "                THEN 1"
                  + "                ELSE 0"
                  + "                END hascontroles"
                  + "              , (SELECT cm.ins_controlemode_success"
                  + "                   FROM ins_controlemode cm"
                  + "                  WHERE cm.ins_controlemode_key = dsc.ins_controlemode_key) succes"
                  + "           FROM ins_deelsrtcontrole dsc"
                  + "          WHERE ins_deelsrtcontrole_key = (SELECT MAX(id2.ins_deelsrtcontrole_key)" // Laatste record.
                  + "                                             FROM ins_deelsrtcontrole id2"
                  + "                                                , ins_controlemode cm"
                  + "                                            WHERE id2.ins_controlemode_key = cm.ins_controlemode_key(+)" // Van COALESCE(geaccordeerde(2), voltooide(6)) inspectie de volgende inspectie bereken (dus ik kan (+) hier gebruiken).
                  + "                                              AND id2.ins_deel_key = dsc.ins_deel_key"
                  + "                                              AND id2.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                  + "                                              AND id2.ins_scenario_key = dsc.ins_scenario_key"
                  // Alleen geplande, geaccordeerde en de succesvol uitgevoerde taken/inspecties tellen mee in de bepaling van volgende taken/inspecties.
                  + (modus == 1
                    // Laatste succesvol uitgevoerde, geplande, bevroren/geaccordeerde of ter uitvoering staande taak (laatste record) waarmee de volgende taak wordt berekend/bepaald.
                    ? "                                            AND (cm.ins_controlemode_success = 1"
                      + "                                            OR id2.ins_deelsrtcontrole_status IN (2, 3)"
                      + "                                            OR id2.ins_deelsrtcontrole_status IN"
                      + "                                                      (CASE"
                      + "                                                       WHEN (SELECT COUNT(dsc1.ins_deelsrtcontrole_key)"
                      + "                                                               FROM ins_deelsrtcontrole dsc1"
                      + "                                                              WHERE dsc1.ins_deel_key = dsc.ins_deel_key"
                      + "                                                                AND dsc1.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                      + "                                                                AND dsc1.ins_scenario_key = dsc.ins_scenario_key"
                      + "                                                                AND dsc1.ins_deelsrtcontrole_status > 0) > 0"
                      + "                                                       THEN -1"
                      + "                                                       ELSE 0"  // De ingeplande inspectie is het eerste record.
                      + "                                                       END)"
                      + "                                              ))"
                    : (modus == 2
                      // Afgeronde taken/inspecties wel of niet succesvol in de jaren voor het freeze jaar.
                      ? "                                          AND id2.ins_deelsrtcontrole_status = 6)"
                      // Geaccordeerde/bevroren taken/inspecties in de jaren voor het freeze jaar.
                      // modus 3.
                      : "                                          AND id2.ins_deelsrtcontrole_status IN (2, 3))"))
                  + (modus == 3
                    // Er is naast een geaccordeerde/bevroren inspectie ook nog een ingeplande inspectie.
                    ? "          AND EXISTS (SELECT id2.ins_deelsrtcontrole_key" // Er mag maar 1 ingeplande inspectie zijn.
                      + "                      FROM ins_deelsrtcontrole id2"
                      + "                         , ins_controlemode cm"
                      + "                     WHERE id2.ins_controlemode_key = cm.ins_controlemode_key(+)"
                      + "                       AND id2.ins_deel_key = dsc.ins_deel_key"
                      + "                       AND id2.ins_srtcontrole_key = dsc.ins_srtcontrole_key"
                      + "                       AND id2.ins_scenario_key = dsc.ins_scenario_key"
                      + "                       AND id2.ins_deelsrtcontrole_status = 0)"
                    : "")
                  + "         GROUP BY dsc.ins_srtcontrole_key"
                  + "                , dsc.ins_deel_key"
                  + "                , dsc.ins_scenario_key"
                  + "                , dsc.ins_deelsrtcontrole_freezedate"
                  + "                , dsc.ins_deelsrtcontrole_freezecost"
                  + "                , dsc.ins_deelsrtcontrole_status"
                  + "                , dsc.ins_controlemode_key) c"
                  + "        ON e.ins_deel_key = c.ins_deel_key"
                  + "            AND e.ins_srtcontrole_key = c.ins_srtcontrole_key"
                  + "            AND e.ins_scenario_key = c.ins_scenario_key";

               return sql_componenten;
             }

             function getSglYearcostSelect(modus)
             { // Select parameters voor de sql van de jaarkosten (sql_yearcost) van objecten met:
               // Modus 1) hun aankomende inspecties.
               //       2) hun goedgekeurde en afgekeurde inspecties.

               var ins_xcp_active_cost = S("ins_xcp_active_cost");
               var costarray = [];
               if (ins_xcp_active_cost & 1) costarray.push("COALESCE(comp.ins_srtcontrole_kosten, 0)");
               if (ins_xcp_active_cost & 2) costarray.push("COALESCE(comp.ins_srtcontrole_kosten2, 0)");
               if (ins_xcp_active_cost & 4) costarray.push("COALESCE(comp.ins_srtcontrole_kosten3, 0)");
               if (ins_xcp_active_cost & 8) costarray.push("COALESCE(comp.ins_srtcontrole_materiaal, 0)");
               var sqlCost = "0 *";
               if (costarray.length > 0)
                 sqlCost = "(" + costarray.join(" + ") + ") *";

               var sqlbtw = (incbtw
                            ? "          (1 + COALESCE((SELECT fbtw.fin_btwtabelwaarde_perc"
                              + "                           FROM fin_btwtabelwaarde fbtw"
                              + "                          WHERE fbtw.fin_btwtabelwaarde_key = comp.fin_btwtabelwaarde_key) / 100"
                              + "                      , 0)) "
                            : "1")

               var sql_yearcost_select =
                      "SELECT comp.ins_deel_key"
                    + "     , comp.ins_srtcontroledl_xcp_key"
                    + "     , comp.ins_srtcontrole_key"
                    + "     , comp.ins_srtcontrole_level"
                    + "     , comp.ins_srtcontrole_groep"
                    + "     , comp.ins_srtcontrole_omschrijving"
                    + "     , comp.vervangingsjaar"
                    + "     , comp.nextdate"
                    + "     , comp.laatste_acc_suc"
                    + "     , comp.laatste_not_suc"
                    + "     , comp.ins_deelsrtcontrole_datum_org"
                    + "     , comp.plandatum"
                    + "     , comp.ins_srtcontrole_periode"
                    + "     , comp.ins_srtcontrole_eenheid"
                    + "     , comp.ins_srtcontrole_opmerking"
                    + (modus == 1
                      ? "   , CASE"
                        + "   WHEN EXTRACT(YEAR FROM comp.ins_deelsrtcontrole_freezedate) = comp.vervangingsjaar AND"
                        + "        comp.ins_deelsrtcontrole_status IN (2, 3)"
                        + "   THEN COALESCE(comp.ins_deelsrtcontrole_freezecost * "
                        +                   sqlbtw
                        + "               , 0)"
                        + "   ELSE COALESCE(comp.ins_deel_aantal * "
                        +                   sqlCost
                        + "                 (COALESCE(comp.ins_srtcontrole_percentage, 100) / 100) * "
                        +                    sqlbtw + " * "
                        + "                 POWER(" + inflatiefactor + " , comp.vervangingsjaar - EXTRACT(YEAR FROM SYSDATE))"
                        + "               , 0)"
                        + "   END bedrag"
                        + " , hierlevel"
                      : "   , (comp.ins_deelsrtcontrole_freezecost * "
                        +      sqlbtw + ") bedrag"
                        + " , 1 hierlevel")
                    + "     , comp.ins_deel_aantal"
                    + "     , comp.ins_srtdeel_eenheid"
                    + "     , comp.ins_srtcontrole_eind"
                    + "     , comp.ins_srtcontrole_afbouwtijd"
                    + "     , comp.prs_kostenplaats_key"
                    + "     , comp.fin_btwtabelwaarde_key"
                    + "     , comp.ins_srtcontroledl_xcp_startdat"
                    + "     , comp.ins_srtcontroledl_xcp_prio"
                    + "     , comp.ins_srtcontroledl_xcp_eind"
                    + "     , comp.ctr_controle_type"
                    + "     , comp.ctr_discipline_key"
                    + "     , comp.ins_scenario_key"
                    + "     , comp.hasscenario2"
                    + "     , comp.scenario_oms"
                    + "     , comp.scenario_aantal"
                    + "     , comp.ins_deelsrtcontrole_freezedate"
                    + "     , comp.ins_deelsrtcontrole_freezecost"
                    + "     , comp.ins_deelsrtcontrole_status"
                    + "     , CASE"
                    + "       WHEN comp.isPlanned = 1"
                    + "       THEN 1"
                    + "       ELSE 0"  // null waarden krijgen de waarde 0.
                    + "       END isPlanned"
                    + "     , comp.hascontroles"
                    + (modus == 2
                      ? "   , comp.succes"
                      : "   , 0") + " completed"
                    + (modus == 2
                      ? "   , CASE WHEN comp.succes = 1 THEN 0 ELSE 1 END"
                      : "   , 0") + " rejected";

               return sql_yearcost_select;
             }


             // Bepalen SQL van objecten met:
             // Modus 1) de aankomende inspecties in het huidige jaar en in de toekomst + geaccordeerde taken in voorgaande jaren (meestal alleen vorig jaar).
             //       2) de goedgekeurde en afgekeurde inspecties in het jaar voor het freezejaar.
             //       3) de geaccordeerde/bevroren en ter uitvoering staande inspecties in het jaar voor het freezejaar indien er ook een inspectie gepland is in de toekomst
             //          (er zijn dan twee lopende inspecties records aanwezig).
             var sql_componenten1 = getSglComponenten(1);
             var sql_yearcost_select1 = getSglYearcostSelect(1);
             var sql_componenten2 = getSglComponenten(2);
             var sql_yearcost_select2 = getSglYearcostSelect(2);
             var sql_componenten3 = getSglComponenten(3);
             var sql_yearcost_select3 = getSglYearcostSelect(3);

             var sql_withcomps = "WITH comps (ins_deel_key"  // Recursive WITH statement om het volgende vervangingsjaar te vinden (m.vervangingsjaar + m.ins_srtcontrole_periode).
                               + "         ,  ins_srtcontroledl_xcp_key"
                               + "         ,  ins_srtcontrole_key"
                               + "         ,  ins_srtcontrole_level"
                               + "         ,  ins_srtcontrole_groep"
                               + "         ,  ins_srtcontrole_omschrijving"
                               + "         ,  ins_srtcontrole_kosten"
                               + "         ,  ins_srtcontrole_kosten2"
                               + "         ,  ins_srtcontrole_kosten3"
                               + "         ,  ins_srtcontrole_materiaal"
                               + "         ,  ins_srtcontrole_periode"
                               + "         ,  ins_srtcontrole_eenheid"
                               + "         ,  ins_srtcontrole_percentage"
                               + "         ,  ins_srtcontrole_opmerking"
                               + "         ,  vervangingsjaar"
                               + "         ,  nextdate"
                               + "         ,  laatste_acc_suc"
                               + "         ,  laatste_not_suc"
                               + "         ,  laatste_jaar"
                               + "         ,  ins_deelsrtcontrole_datum_org"
                               + "         ,  plandatum"
                               + "         ,  hierlevel"
                               + "         ,  ins_deel_aantal"
                               + "         ,  ins_srtdeel_eenheid"
                               + "         ,  ins_srtcontrole_eind"
                               + "         ,  ins_srtcontrole_afbouwtijd"
                               + "         ,  prs_kostenplaats_key"
                               + "         ,  fin_btwtabelwaarde_key"
                               + "         ,  ins_srtcontroledl_xcp_startdat"
                               + "         ,  ins_srtcontroledl_xcp_prio"
                               + "         ,  ins_srtcontroledl_xcp_eind"
                               + "         ,  ctr_controle_type"
                               + "         ,  ctr_discipline_key"
                               + "         ,  ins_scenario_key"
                               + "         ,  hasscenario2"
                               + "         ,  scenario_oms"
                               + "         ,  scenario_aantal"
                               + "         ,  ins_deelsrtcontrole_freezedate"
                               + "         ,  ins_deelsrtcontrole_freezecost"
                               + "         ,  ins_deelsrtcontrole_status"
                               + "         ,  isPlanned"
                               + "         ,  hascontroles)";

             var sql_yearcost =
                    sql_yearcost_select1
                  + "  FROM (" + sql_withcomps
                  + "        AS (SELECT ins_deel_key"
                  + "                 , ins_srtcontroledl_xcp_key"
                  + "                 , ins_srtcontrole_key"
                  + "                 , ins_srtcontrole_level"
                  + "                 , ins_srtcontrole_groep"
                  + "                 , ins_srtcontrole_omschrijving"
                  + "                 , ins_srtcontrole_kosten"
                  + "                 , ins_srtcontrole_kosten2"
                  + "                 , ins_srtcontrole_kosten3"
                  + "                 , ins_srtcontrole_materiaal"
                  + "                 , ins_srtcontrole_periode"
                  + "                 , ins_srtcontrole_eenheid"
                  + "                 , ins_srtcontrole_percentage"
                  + "                 , ins_srtcontrole_opmerking"
                  + "                 , vervangingsjaar"
                  + "                 , nextdate"
                  + "                 , laatste_acc_suc"
                  + "                 , laatste_not_suc"
                  + "                 , laatste_jaar"
                  + "                 , ins_deelsrtcontrole_datum_org"
                  + "                 , plandatum"
                  + "                 , 1 hierlevel"
                  + "                 , ins_deel_aantal"
                  + "                 , ins_srtdeel_eenheid"
                  + "                 , ins_srtcontrole_eind"
                  + "                 , ins_srtcontrole_afbouwtijd"
                  + "                 , prs_kostenplaats_key"
                  + "                 , fin_btwtabelwaarde_key"
                  + "                 , ins_srtcontroledl_xcp_startdat"
                  + "                 , ins_srtcontroledl_xcp_prio"
                  + "                 , ins_srtcontroledl_xcp_eind"
                  + "                 , ctr_controle_type"
                  + "                 , ctr_discipline_key"
                  + "                 , ins_scenario_key"
                  + "                 , hasscenario2"
                  + "                 , scenario_oms"
                  + "                 , scenario_aantal"
                  + "                 , ins_deelsrtcontrole_freezedate"
                  + "                 , ins_deelsrtcontrole_freezecost"
                  + "                 , ins_deelsrtcontrole_status"
                  + "                 , isPlanned"
                  + "                 , hascontroles"
                  + "              FROM (" + sql_componenten1 + ")"
                  + "             WHERE vervangingsjaar IS NOT NULL"
                  + (!showunfin             // Toekomstige taken zijn niet relevant voor lopende taken.
                    ? "          UNION ALL" // Latere jaren
                      + "        SELECT m.ins_deel_key"
                      + "             , m.ins_srtcontroledl_xcp_key"
                      + "             , m.ins_srtcontrole_key"
                      + "             , m.ins_srtcontrole_level"
                      + "             , m.ins_srtcontrole_groep"
                      + "             , m.ins_srtcontrole_omschrijving"
                      + "             , m.ins_srtcontrole_kosten"
                      + "             , m.ins_srtcontrole_kosten2"
                      + "             , m.ins_srtcontrole_kosten3"
                      + "             , m.ins_srtcontrole_materiaal"
                      + "             , m.ins_srtcontrole_periode"
                      + "             , m.ins_srtcontrole_eenheid"
                      + "             , m.ins_srtcontrole_percentage"
                      + "             , m.ins_srtcontrole_opmerking"
                      + "             , m.vervangingsjaar + m.ins_srtcontrole_periode"
                      + "             , m.nextdate"
                      + "             , m.laatste_acc_suc"
                      + "             , m.laatste_not_suc"
                      + "             , m.laatste_jaar"
                      + "             , m.ins_deelsrtcontrole_datum_org"
                      + "             , m.plandatum"
                      + "             , m.hierlevel + 1"
                      + "             , m.ins_deel_aantal"
                      + "             , m.ins_srtdeel_eenheid"
                      + "             , m.ins_srtcontrole_eind"
                      + "             , m.ins_srtcontrole_afbouwtijd"
                      + "             , m.prs_kostenplaats_key"
                      + "             , m.fin_btwtabelwaarde_key"
                      + "             , m.ins_srtcontroledl_xcp_startdat"
                      + "             , m.ins_srtcontroledl_xcp_prio"
                      + "             , m.ins_srtcontroledl_xcp_eind"
                      + "             , m.ctr_controle_type"
                      + "             , m.ctr_discipline_key"
                      + "             , m.ins_scenario_key"
                      + "             , m.hasscenario2"
                      + "             , m.scenario_oms"
                      + "             , m.scenario_aantal"
                      + "             , m.ins_deelsrtcontrole_freezedate"
                      + "             , m.ins_deelsrtcontrole_freezecost"
                      + "             , m.ins_deelsrtcontrole_status"
                      + "             , m.isPlanned"
                      + "             , CASE"
                      + "               WHEN (SELECT COUNT(sdc.ins_deelsrtcontrole_key)"
                      + "                       FROM ins_deelsrtcontrole sdc"
                      + "                          , ins_controlemode cm"
                      + "                      WHERE sdc.ins_controlemode_key = cm.ins_controlemode_key"
                      + "                        AND sdc.ins_deel_key = m.ins_deel_key"
                      + "                        AND sdc.ins_srtcontrole_key = m.ins_srtcontrole_key"
                      + "                        AND sdc.ins_deelsrtcontrole_status = 6"
                      + "                        AND sdc.ins_scenario_key = 1"
                      + "                        AND cm.ins_controlemode_success = 1) > 0"
                      + "               THEN 1"
                      + "               ELSE 0"
                      + "               END hascontroles"
                      + "          FROM comps m"
                      + "         WHERE (m.vervangingsjaar + m.ins_srtcontrole_periode <= " + toyear + ")"
                    : "")
                  + "          )"
                  + "        SELECT *"
                  + "          FROM comps"
                  + "       ) comp"
                  + " WHERE (vervangingsjaar >= EXTRACT(YEAR FROM SYSDATE)"
                  // Ik wil ook de lege regels zien van taken die in voorgaande jaren (meestal alleen vorig jaar) geaccordeerd staan.
                  // Dan moet ik nog deze OR toevoegen.
                  // Als het vinkje van lege regels tonen niet is gezet dan worden deze regels niet getoond (weggefilterd).
                  + "    OR (vervangingsjaar < EXTRACT(YEAR FROM SYSDATE) AND comp.ins_deelsrtcontrole_status IN (2, 3)"
                  + ((new Date()).getFullYear() > mjb_freeze_or_sys_year
                    ? "      AND EXTRACT(YEAR FROM comp.ins_deelsrtcontrole_freezedate) = " + mjb_freeze_or_sys_year
                    : "")
                  + "       )"
                  + "    OR (vervangingsjaar < EXTRACT(YEAR FROM SYSDATE) AND comp.ins_deelsrtcontrole_status = 0)"
                  + "       )"
                  + (!showunfin             // Afgeronde taken (succesvol of niet succesvol) zijn niet relevant voor lopende taken.
                    ? " UNION "
                      + sql_yearcost_select2 // Inspecties die wel of niet succesvol zijn afgerond.
                      + "  FROM (" + sql_componenten2 + ") comp"
                      + " WHERE comp.vervangingsjaar IS NOT NULL"
                    : "")
                  + " UNION "
                  + sql_yearcost_select3 // Geaccordeerde/bevroren inspectie in het jaar voor het freezejaar indien er ook al een ingeplande inspectie in de toekomst is (Twee lopende inspectie records).
                  + "  FROM (" + sql_componenten3 + ") comp"
                  + " WHERE comp.vervangingsjaar IS NOT NULL";

             var keyColumn = "";
             switch (groupby)
             {
               case 1:  keyColumn = (moredetail == 1? "isd.ins_srtdeel_key" : "d.alg_district_key");
                        break;
               case 2:  keyColumn = (moredetail == 1? "isd.ins_srtdeel_key" : "l.alg_locatie_key");
                        break;
               case 3:  keyColumn = (moredetail == 1? "isd.ins_srtdeel_key" : "g.alg_gebouw_key");
                        break;
               case 4:  keyColumn = (moredetail == 2? "g.alg_gebouw_key" : "dl.ins_discipline_key");
                        break;
               case 5:  keyColumn = (moredetail == 2? "g.alg_gebouw_key" : "isg.ins_srtgroep_key");
                        break;
               case 6:  keyColumn = (moredetail == 2? "g.alg_gebouw_key" : "isd.ins_srtdeel_key");
                        break;
               case 7:
               case 9:  keyColumn = "dl.ins_deel_key";
                        break;
               //case 8: // melding komt hier niet voor. (wel bij mld_search_list.asp)
             }

             var sql_cost_verval = "SELECT d.alg_district_key"
                                 + "     , d.alg_district_omschrijving"
                                 + "     , l.alg_locatie_code"
                                 + "     , l.alg_locatie_omschrijving"
                                 + "     , l.alg_locatie_key"
                                 + "     , g.alg_gebouw_code"
                                 + "     , g.alg_gebouw_naam"
                                 + "     , g.alg_gebouw_key"
                                 + "     , g.prs_perslid_key_verantw"
                                 + "     , " + lcl.xsql('sg.alg_srtgebouw_omschrijving', 'sg.alg_srtgebouw_key')
                                 + "     , t.alg_terreinsector_code"
                                 + "     , t.alg_terreinsector_naam"
                                 + "     , t.alg_terreinsector_key"
                                 + "     , onrg.alg_ruimte_key"
                                 + "     , onrg.alg_ruimte_nr"
                                 + "     , onrg.alg_ruimte_omschrijving"
                                 + "     , dl.ins_deel_omschrijving"
                                 + "     , dl.ins_deel_mjb_score1"
                                 + "     , isd.ins_srtdeel_mjb_grensscore1"
                                 + "     , dl.ins_deel_mjb_score2"
                                 + "     , l.alg_locatie_mjb_score1"
                                 + "     , g.alg_gebouw_mjb_score1"
                                 + "     , cy.ins_deel_aantal"
                                 + "     , cy.ins_srtdeel_eenheid"
                                 + "     , dl.ins_deel_opmerking"
                                 + "     , dd.ins_discipline_omschrijving"
                                 + "     , dd.ins_discipline_key"
                                 + "     , isg.ins_srtgroep_omschrijving"
                                 + "     , isd.ins_srtdeel_omschrijving"
                                 + "     , cy.ins_srtcontrole_omschrijving"
                                 + "     , cy.ins_deel_key"
                                 + "     , " + keyColumn + " keyColumn"
                                 + "     , cy.ins_srtcontroledl_xcp_key"
                                 + "     , cy.ins_srtcontrole_key"
                                 + "     , cy.ins_srtcontrole_periode"
                                 + "     , cy.ins_srtcontrole_eenheid"
                                 + "     , cy.ins_srtcontrole_opmerking"
                                 + "     , cy.ins_srtcontrole_level"
                                 + "     , cy.ins_srtcontrole_groep"
                                 + "     , COALESCE(g.alg_gebouw_vervaldatum, t.alg_terreinsector_vervaldatum)"
                                 + "     , dl.ins_deel_vervaldatum"
                                 + "     , cy.ins_srtcontroledl_xcp_startdat"
                                 + "     , cy.ins_srtcontroledl_xcp_prio"
                                 + "     , cy.ins_srtcontroledl_xcp_eind"
                                 + "     , cy.ins_srtcontrole_eind"
                                 // De startdatum is MAX(startdatum, aanmaakdatum/registratiedatum) en heeft altijd een waarde (ins_deel_aanmaak is altijd gevuld).
                                 + "     , EXTRACT(YEAR FROM GREATEST(COALESCE(cy.ins_srtcontroledl_xcp_startdat"
                                 + "                                         , dl.ins_deel_aanmaak)"
                                 + "                                , COALESCE(dl.ins_deel_aanmaak"
                                 + "                                         , cy.ins_srtcontroledl_xcp_startdat))"
                                 + "              ) startjaar"
                                 // Aanmaakdatum is altijd aanwezig.
                                 + "     , CASE"
                                 + "       WHEN cy.ins_srtcontroledl_xcp_startdat IS NULL AND dl.ins_deel_aanmaak IS NOT NULL"
                                 + "       THEN 'A'"      // Aanmaakdatum/Registratiedatum
                                 + "       WHEN cy.ins_srtcontroledl_xcp_startdat IS NOT NULL"
                                 + "       THEN"
                                 + "           CASE"
                                 + "           WHEN EXTRACT(YEAR FROM cy.ins_srtcontroledl_xcp_startdat) >= EXTRACT(YEAR FROM dl.ins_deel_aanmaak)"
                                 + "           THEN 'S'"  // Startdatum
                                 + "           ELSE 'A'"  // Aanmaakdatum/Registratiedatum
                                 + "           END"
                                 + "       ELSE NULL"
                                 + "       END starttype"
                                 + "     , EXTRACT(YEAR FROM LEAST(COALESCE(COALESCE(g.alg_gebouw_vervaldatum, t.alg_terreinsector_vervaldatum)"
                                 + "                                      , dl.ins_deel_vervaldatum"
                                 + "                                      , COALESCE(cy.ins_srtcontroledl_xcp_eind, cy.ins_srtcontrole_eind))"
                                 + "                             , COALESCE(COALESCE(cy.ins_srtcontroledl_xcp_eind, cy.ins_srtcontrole_eind)"
                                 + "                                      , COALESCE(g.alg_gebouw_vervaldatum, t.alg_terreinsector_vervaldatum)"
                                 + "                                      , dl.ins_deel_vervaldatum)"
                                 + "                             , COALESCE(dl.ins_deel_vervaldatum"
                                 + "                                       , COALESCE(cy.ins_srtcontroledl_xcp_eind, cy.ins_srtcontrole_eind)"
                                 + "                                       , COALESCE(g.alg_gebouw_vervaldatum, t.alg_terreinsector_vervaldatum)))"
                                 + "              ) vervaljaar"
                                 + "     , vervangingsjaar"
                                 + "     , nextdate"
                                 + "     , laatste_acc_suc"
                                 + "     , laatste_not_suc"
                                 + "     , dl.ins_deel_aanmaak"
                                 + "     , EXTRACT(YEAR FROM plandatum) planjaar"
                                 + "     , ins_deelsrtcontrole_datum_org"
                                 + "     , plandatum"
                                 + "     , ins_srtcontrole_afbouwtijd afbouwtijd"
                                 + "     , cy.prs_kostenplaats_key"
                                 + "     , bedrag"
                                 + "     , cy.ctr_controle_type"
                                 + "     , cy.ctr_discipline_key"
                                 + "     , cy.ins_scenario_key"
                                 + "     , cy.hasscenario2"
                                 + "     , cy.scenario_oms"
                                 + "     , cy.scenario_aantal"
                                 + "     , (SELECT MAX(id2.ins_deelsrtcontrole_freezedate)"
                                 + "          FROM ins_deelsrtcontrole id2"
                                 + "         WHERE id2.ins_deel_key = cy.ins_deel_key"
                                 + "           AND id2.ins_srtcontrole_key = cy.ins_srtcontrole_key"
                                 + "           AND id2.ins_scenario_key = 1) idsc_freezedate_max" // Laatste freezedate om geaccordeerde taken te kunnen filteren.
                                 + "     , cy.ins_deelsrtcontrole_freezedate"
                                 + "     , cy.ins_deelsrtcontrole_status"
                                 + "     , cy.isPlanned"
                                 + "     , cy.hascontroles"
                                 + "     , cy.completed"
                                 + "     , cy.rejected"
                                 + (algFlexParams && algFlexParams.anyflex
                                   ?       algFlexParams.sql
                                   : "")
                                 + (insFlexParams && insFlexParams.anyflex
                                   ?       insFlexParams.sql
                                   : "")
                                 + "  FROM (" + sql_yearcost + ") cy"
                                 + "     , ins_v_deelenonderdeel dl" // I.v.m. ORA-03113 fout: ins_v_aanwezigdeel vervangen door ins_deel en verder uitgeschreven (FSN#51212).
                                 + "     , ins_srtdeel isd"
                                 + "     , ins_srtgroep isg"
                                 + "     , ins_discipline dd"
                                 + "     , alg_district d"
                                 + "     , alg_locatie l"
                                 + "     , alg_v_allonrgoed_gegevens onrg"
                                 + "     , alg_gebouw g"
                                 + "     , alg_srtgebouw sg"
                                 + "     , alg_terreinsector t"
                                 + " WHERE cy.ins_deel_key = dl.ins_deel_key"
                                 + "   AND dl.ins_deel_verwijder IS NULL"
                                 + "   AND dl.ins_srtdeel_key = isd.ins_srtdeel_key"
                                 + "   AND isd.ins_srtgroep_key = isg.ins_srtgroep_key"
                                 + "   AND isg.ins_discipline_key = dd.ins_discipline_key"
                                 + "   AND d.alg_district_key = l.alg_district_key"
                                 + "   AND onrg.alg_locatie_key = l.alg_locatie_key"
                                 + "   AND onrg.alg_gebouw_key = g.alg_gebouw_key(+)"
                                 + "   AND g.alg_srtgebouw_key = sg.alg_srtgebouw_key(+)"
                                 + "   AND onrg.alg_terreinsector_key = t.alg_terreinsector_key(+)"
                                 + "   AND ((dl.ins_alg_ruimte_key = onrg.alg_ruimte_key AND dl.ins_alg_ruimte_type = 'R')"
                                 + "     OR (dl.ins_alg_ruimte_key = onrg.alg_terreinsector_key AND dl.ins_alg_ruimte_type = 'T'))"
                                 + "   AND dl.ins_alg_ruimte_type = onrg.alg_type"
                                 + "   AND dl.ins_alg_ruimte_key = COALESCE(onrg.alg_ruimte_key, onrg.alg_terreinsector_key)"
                                 + (beheerder_key > 0
                                   ? "          AND dl.prs_perslid_key_beh = " + beheerder_key
                                   : "")
                                 + (verantw_key > 0
                                   ? "          AND (  (   onrg.alg_gebouw_key = g.alg_gebouw_key "
                                              + "      AND (  g.prs_perslid_key_verantw  = " + verantw_key
                                              + "          OR g.prs_perslid_key_verantw2 = " + verantw_key
                                              + "          )"
                                              + "      )"
                                              + "   OR (   onrg.alg_terreinsector_key = t.alg_terreinsector_key"
                                              + "      AND (  t.prs_perslid_key_verantw  = " + verantw_key
                                              + "          OR t.prs_perslid_key_verantw2 = " + verantw_key
                                              + "          )"
                                              + "      )"
                                              + "   )"
                                   : "");

             if (keys != null && keys.length > 0 && niveau != null && niveau > 0 && (pricechange || freeze || unfreeze || execute || finish || addToScenario))
             {
               switch (niveau)
               {
                 case 1:  sql_cost_verval += (moredetail == 1
                                           ? " AND isd.ins_srtdeel_key IN (" + keys.join(",") + ")"
                                           : " AND d.alg_district_key IN (" + keys.join(",") + ")");
                          break;
                 case 2:  sql_cost_verval += (moredetail == 1
                                           ? " AND isd.ins_srtdeel_key IN (" + keys.join(",") + ")"
                                           : " AND g.alg_locatie_key IN (" + keys.join(",") + ")");
                          break;
                 case 3:  sql_cost_verval += (moredetail == 1
                                           ? " AND isd.ins_srtdeel_key IN (" + keys.join(",") + ")"
                                           : " AND g.alg_gebouw_key IN (" + keys.join(",") + ")");
                          break;
                 case 4:  sql_cost_verval += (moredetail == 2
                                           ? " AND g.alg_gebouw_key IN (" + keys.join(",") + ")"
                                           : " AND dl.ins_discipline_key IN (" + keys.join(",") + ")");
                          break;
                 case 5:  sql_cost_verval += (moredetail == 2
                                           ? " AND g.alg_gebouw_key IN (" + keys.join(",") + ")"
                                           : " AND isg.ins_srtgroep_key IN (" + keys.join(",") + ")");
                          break;
                 case 6:  sql_cost_verval += (moredetail == 2
                                           ? " AND g.alg_gebouw_key IN (" + keys.join(",") + ")"
                                           : " AND isd.ins_srtdeel_key IN (" + keys.join(",") + ")");
                          break;
                 case 7:  sql_cost_verval += " AND dl.ins_deel_key IN (" + keys.join(",") + ")";
                          break;
               }
             }

             if (deel)
               sql_cost_verval += " AND dl.ins_deel_upper LIKE " + safe.quoted_sql_wild("%" + deel + "%");

             if (bld_key_arr && bld_key_arr.length)
                sql_cost_verval += " AND (g.alg_gebouw_key IN (" + bld_key_arr.join(",") + ") OR t.alg_terreinsector_key IN (" + bld_key_arr.join(",") + "))";

             if (srtgebouw_key_arr && srtgebouw_key_arr.length)
                sql_cost_verval += " AND g.alg_srtgebouw_key IN (" + srtgebouw_key_arr.join(",") + ")";

             // Eerste inspectie datum bepalen zonder na de plandatum te kijken (orginele inspectie datum).
             // 1) Eerst controleren of laatste inpspectie NIET succesvol (laatste_not_suc IS NOT NULL) is geweest.
             //    De volgende inspectie is dan in het freeze jaar.
             // 2) Er is nog geen inspectie geweest en de startdatum is ingevuld.
             //    Er geldt dan het volgende:
             //    Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
             //    Voor Vervanging(2) of Certificering(3):
             //    a) Als registratiedatum het verst in de toekomst ligt: Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
             //    b) Als de startdatum het verst in de toekomst ligt: Eerste inspectie tonen op de startdatum.
             //    De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
             // 3) Er is nog geen inspectie geweest en alleen de aanmaakdatum/Registratiedatum ligt in het huidige jaar of in de toekomst.
             //    Voor Controle(1):
             //    a) Als registratiedatum < freeze jaar dan eerste inspectie tonen in het freeze jaar
             //    b) Anders inspectie tonen in het registratiejaar.
             //    Voor Vervanging(2) of Certificering(3):
             //    a) Als (registratiedatum + periode) < freeze jaar dan eerste inspectie tonen in het freeze jaar
             //    b) Anders inspectie tonen in het (registratiejaar + periode)
             // 4) Er is nog geen inspectie geweest en de startdatum is niet ingevuld en registratiedatum ligt in het verleden. Berekenen jaar.
             //    a) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Controle(1).
             //       Volgende inspectie is in het freeze jaar.
             //    b) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Vervanging(2) of Certificering(3).
             //       Nextdate is na het freeze jaar?
             //       Ja)  Vorige inspectie ligt na het start jaar en ligt niet in het aanmaak jaar?
             //            Ja)  Volgende inspectie is in het freeze jaar.
             //            Nee) Volgende inspectie is het jaar van de nextdate.
             //       Nee) De laatst ingeplande inspectie (nextdate) is na of in het start jaar?
             //            Ja)  Volgende inspectie is in het freeze jaar.
             //            Nee) Volgende inspectie is in het jaar "nextdatum + periode".
             //    c) Laatste inspectie is niet NULL. Er is al 1 of meerdere keren geinspecteerd.
             //       Ligt de laatst ingeplande inspectie (nextdate) na dit jaar?
             //         Ja)  Volgende inspectie is het jaar van de nextdate (in de toekomst).
             //         Nee) Volgende inspectie is in het freeze jaar.
             // LET OP: c.laatste_acc_suc: geeft de ins_deelsrtcontrole_datum terug van de laatste geaccordeerde of succesvol uitgevoerde taak.
             //         laatste_not_suc: Als de laatste uitgevoerde taak NIET succesvoll is geeft deze de ins_deelsrtcontrole_datum terug van deze taak.
             // P.S.: De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
             var sql_org_nextdate =
                  " EXTRACT (YEAR FROM COALESCE(CASE"
                + "                             WHEN cv.laatste_not_suc IS NOT NULL"  // 1) Laatste inspectie is NIET succesvol. De volgende inspectie direct in het freeze jaar.
                + "                             THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                + "                             WHEN cv.laatste_acc_suc IS NULL AND"          // 2) Startdatum is ingevuld en er is nog geen inspectie geweest.
                + "                                  cv.ins_srtcontroledl_xcp_startdat IS NOT NULL"
                + "                             THEN" // 2) Startdatum is ingevuld en ligt in het verleden of de toekomst en er is nog geen inspectie geweest.
                + "                               CASE"
                + "                               WHEN EXTRACT(YEAR FROM cv.ins_srtcontroledl_xcp_startdat) >= EXTRACT(YEAR FROM cv.ins_deel_aanmaak)"
                + "                               THEN" // 2a) Startdatum op of na aanmaakdatum/registratiedatum.
                + "                                 CASE"
                + "                                 WHEN EXTRACT(YEAR FROM cv.ins_srtcontroledl_xcp_startdat) < " + mjb_freeze_or_sys_year
                + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                + "                                 ELSE cv.ins_srtcontroledl_xcp_startdat"
                + "                                 END"
                + "                               ELSE" // 2b) Aanmaakdatum/Registratiedatum is na de startdatum.
                + "                                 CASE"
                + "                                 WHEN cv.ctr_controle_type = 1"  // Controle(1).
                + "                                 THEN"
                + "                                   CASE"
                + "                                   WHEN EXTRACT(YEAR FROM cv.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                + "                                   THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                + "                                   ELSE cv.ins_deel_aanmaak" // Registratiedatum.
                + "                                   END"
                + "                                 ELSE"  // Vervanging(2), Certificering(3).
                + "                                   CASE"
                + "                                   WHEN EXTRACT(YEAR FROM ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                + "                                   THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                + "                                   ELSE ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)" // 1 periode na registratiedatum.
                + "                                   END"
                + "                                 END"
                + "                               END"
                + "                             WHEN cv.laatste_acc_suc IS NULL AND"
                + "                                  EXTRACT(YEAR FROM cv.ins_deel_aanmaak) >= EXTRACT(YEAR FROM SYSDATE)" // Alleen de aanmaakdatum/registratiedatum is ingevuld.
                + "                             THEN" // 3) Aanmaakdatum/Registratiedatum is ingevuld en ligt in de toekomst en er is nog geen inspectie geweest.
                + "                               CASE"
                + "                               WHEN cv.ctr_controle_type = 1"  // Controle(1).
                + "                               THEN"
                + "                                 CASE"
                + "                                 WHEN EXTRACT( YEAR FROM cv.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                + "                                 ELSE cv.ins_deel_aanmaak"
                + "                                 END"
                + "                               ELSE"  // Vervanging(2), Certificering(3).
                + "                                 CASE"
                + "                                 WHEN EXTRACT( YEAR FROM ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                + "                                 ELSE ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)"
                + "                                 END"
                + "                               END"
                + "                             ELSE NULL"
                + "                             END"
                + "                           , CASE"                                // 4) Berekenen jaar.
                + "                             WHEN cv.laatste_acc_suc IS NULL AND cv.ctr_controle_type = 1"  // Controle(1).
                + "                             THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')" // 4a)
                + "                             WHEN cv.laatste_acc_suc IS NULL AND cv.ctr_controle_type != 1" // Vervanging(2), Certificering(3).
                + "                             THEN"                   // 4b) Er is nog geen inspectie geweest
                + "                               CASE"
                + "                               WHEN EXTRACT(YEAR FROM cv.nextdate) > " + mjb_freeze_or_sys_year
                + "                               THEN"                 // Nextdate is na de freeze datum.
                + "                                 CASE"
                + "                                 WHEN EXTRACT(YEAR FROM ADD_MONTHS(cv.nextdate, -1 * 12 * cv.ins_srtcontrole_periode)) >= " + mjb_start_year + " AND"
                + "                                      EXTRACT(YEAR FROM ADD_MONTHS(cv.nextdate, -1 * 12 * cv.ins_srtcontrole_periode)) != EXTRACT(YEAR FROM cv.ins_deel_aanmaak)"
                + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')" // Nu en berekende vorige inspectie liggen tussen start en freeze jaar.
                + "                                 ELSE cv.nextdate"
                + "                                 END"
                + "                               ELSE"                 // Nextdate is voor of in het freeze jaar.
                + "                                 CASE"
                + "                                 WHEN EXTRACT(YEAR FROM cv.nextdate) >= " + mjb_start_year
                + "                                 THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"         // Nextdate tussen start en freeze jaar.
                + "                                 ELSE ADD_MONTHS(cv.nextdate, 12 * cv.ins_srtcontrole_periode)"  // Nextdate voor het start jaar.
                + "                                 END"
                + "                               END"
                + "                             ELSE"                   // 4c) Laatste IS NOT NULL. Er is al een inspectie geweest.
                + "                               CASE"
                + "                               WHEN EXTRACT(YEAR FROM cv.nextdate) > EXTRACT(YEAR FROM SYSDATE)"
                + "                               THEN"
                + "                                 CASE"
                + "                                 WHEN"               // Als er een geaccordeerde inspectie is, dan de volgende vanaf het jaar van de geaccordeerde inspectie berekenen.
                + "                                   (SELECT idsc2.ins_deelsrtcontrole_status"
                + "                                      FROM ins_deelsrtcontrole idsc2"
                + "                                     WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                + "                                       AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                + "                                       AND idsc2.ins_scenario_key = cv.ins_scenario_key"
                + "                                       AND idsc2.ins_deelsrtcontrole_status IN (2, 3)) IS NOT NULL"
                + "                                 THEN"
                + "                                   ADD_MONTHS((SELECT idsc2.ins_deelsrtcontrole_freezedate"
                + "                                                 FROM ins_deelsrtcontrole idsc2"
                + "                                                WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                + "                                                  AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                + "                                                  AND idsc2.ins_scenario_key = cv.ins_scenario_key"
                + "                                                  AND idsc2.ins_deelsrtcontrole_status IN (2, 3)), 12 * cv.ins_srtcontrole_periode)"
                + "                                 ELSE"
                + "                                   cv.nextdate"       // Volgende inspectie is in de toekomst.
                + "                                 END"
                + "                               ELSE TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"           // Laatst ingeplande inspectie is nog steeds niet uitgevoerd. Dus opnieuw in het freeze jaar tonen zodat deze daar gefreezed kan worden.
                + "                               END"
                + "                             END)) org_nextdate";

             var sql_melding = "SELECT mo.mld_melding_key"
                             + "  FROM mld_melding_object mo"
                             + " WHERE mo.ins_deelsrtcontrole_key = COALESCE((SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                             + "                                                FROM ins_deelsrtcontrole idsc2"
                             + "                                               WHERE idsc2.ins_deel_key = CV.ins_deel_key"
                             + "                                                 AND idsc2.ins_srtcontrole_key = CV.ins_srtcontrole_key"
                             + "                                                 AND (idsc2.ins_scenario_key = CV.ins_scenario_key))"
                             + "                                           , -1)";

             var sql_cost = "SELECT cv.alg_district_key"
                          + "     , cv.alg_district_omschrijving"
                          + "     , cv.alg_locatie_code"
                          + "     , cv.alg_locatie_omschrijving"
                          + "     , cv.alg_locatie_key"
                          + "     , cv.alg_gebouw_code"
                          + "     , cv.alg_gebouw_naam"
                          + "     , cv.alg_gebouw_key"
                          + "     , (SELECT " + S("prs_pers_string")
                            + "        FROM prs_perslid p"
                            + "       WHERE prs_perslid_key = cv.prs_perslid_key_verantw) gebouwverantwoordelijke"
                          + "     , CV.alg_srtgebouw_omschrijving"
                          + "     , cv.alg_terreinsector_code"
                          + "     , cv.alg_terreinsector_naam"
                          + "     , cv.alg_terreinsector_key"
                          + "     , cv.alg_ruimte_key"
                          + "     , cv.alg_ruimte_nr"
                          + "     , cv.alg_ruimte_omschrijving"
                          + "     , cv.ins_deel_omschrijving"
                          + "     , cv.ins_deel_mjb_score1"
                          + "     , cv.ins_deel_mjb_score2"
                          + "     , cv.ins_srtdeel_mjb_grensscore1"
                          + "     , cv.alg_locatie_mjb_score1"
                          + "     , cv.alg_gebouw_mjb_score1"
                          + "     , cv.ins_deel_aantal"
                          + "     , cv.ins_srtdeel_eenheid"
                          + "     , cv.ins_deel_opmerking"
                          + "     , cv.ins_discipline_omschrijving"
                          + "     , cv.ins_discipline_key"
                          + "     , cv.ins_srtgroep_omschrijving"
                          + "     , cv.ins_srtdeel_omschrijving"
                          + "     , cv.ins_srtcontrole_omschrijving"
                          + "     , cv.ins_deel_key"
                          + "     , (SELECT COUNT(mo.mld_melding_key)"
                          + "         FROM mld_melding_object mo"
                          + "        WHERE mo.ins_deel_key = cv.ins_deel_key"
                          + "          AND mo.mld_melding_object_aanmaak > SYSDATE - 365) meldingshistorie"
                          + "     , cv.keyColumn"
                          + "     , cv.ins_srtcontroledl_xcp_key"
                          + "     , cv.ins_srtcontrole_key"
                          + "     , cv.ins_srtcontrole_periode"
                          + "     , cv.ins_srtcontrole_eenheid"
                          + "     , cv.ins_srtcontrole_opmerking"
                          + "     , cv.ins_srtcontrole_level"
                          + "     , cv.ins_srtcontrole_groep"
                          + "     , cv.startjaar"
                          + "     , cv.starttype"
                          + "     , cv.vervaljaar"
                          + "     , cv.vervangingsjaar"
                          // De org_nextdate (sql_org_nextdate) met berekeningen van de nextcyclusdate (database procedure fac.nextcyclusdate()) zo ver mogelijk naar buiten gehaald,
                          // zodat deze berekeningen zo laat mogelijk worden berekend met een zo klein mogelijke verzameling resultaten (RABO#60119).
                          // Helaas kan dat niet met vervangingsjaar. Het aantal aanroepen van fac.nextcyclusdate() ging met een derde omlaag en de uitvoertijd van de query ging hierdoor met bijna een kwart omlaag.
                          + (fulldetails
                            ? "   , " + sql_org_nextdate // Eerstaankomende inspectie: 1-ste dit jaar of in de toekomst.
                            : "   , NULL org_nextdate")
                          + "     , cv.ins_deelsrtcontrole_datum_org"
                          + "     , cv.planjaar"
                          + "     , cv.afbouwtijd"
                          + "     , cv.ins_srtcontroledl_xcp_startdat startdatum"
                          + "     , cv.ins_srtcontroledl_xcp_prio"
                          + "     , (SELECT " + S("prs_kpn_string")
                          + "          FROM prs_kostenplaats k"
                          + "         WHERE k.prs_kostenplaats_key = CV.prs_kostenplaats_key) kostenplaats"
                          + "     , cv.isPlanned"
                          + "     , cv.idsc_freezedate_max"
                          + "     , COALESCE((SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                          + "                   FROM ins_deelsrtcontrole idsc2"
                          + "                  WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                          + "                    AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                    AND (idsc2.ins_scenario_key = cv.ins_scenario_key))"
                          + "              , -1) ins_deelsrtcontrole_key"
                          + "     , (SELECT MAX(ins_deelsrtcontrole_plan_opm)"
                          + "        FROM ins_deelsrtcontrole idpo"
                          + "        WHERE idpo.INS_DEELSRTCONTROLE_KEY = COALESCE((SELECT MAX(idsc3.ins_deelsrtcontrole_key)"
                          + "                                                         FROM ins_deelsrtcontrole idsc3"
                          + "                                                        WHERE idsc3.ins_deel_key = cv.ins_deel_key"
                          + "                                                          AND idsc3.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                                                          AND (idsc3.ins_scenario_key = cv.ins_scenario_key))"
                          + "                                                       , -1)"
                          + "       ) ins_deelsrtcontrole_plan_opm"
                          + "     , cv.bedrag AS orgbedrag"
                          // Als er een andere inspectie is met een lagere ins_srtcontrole_level in hetzelfde jaar dan springt ons bedrag op 0
                          // Dit gebeurt o.a. ook als: 1) het object vervallen is of
                          //                           2) de startdatum of de registratiedatum in de toekomst ligt.
                          //
                          // Als de registratiedatum in de toekomst ligt en de startdatum eventueel ook dan geldt het volgende.
                          // Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
                          // Voor Vervanging(2) of Certificering(3):
                          // a) Als registratiedatum het verst in de toekomst ligt: Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
                          // b) Als de startdatum het verst ligt: Eerste inspectie tonen op de startdatum.
                          + "     , CASE WHEN MIN(cv.ins_srtcontrole_level) KEEP (DENSE_RANK FIRST ORDER BY cv.ins_srtcontrole_level) "
                          + "                 OVER (PARTITION BY cv.ins_deel_key, cv.vervangingsjaar, cv.ins_scenario_key) < cv.ins_srtcontrole_level"
                          + "               OR"
                          // Vanaf vervaljaar-afbouwtijd het bedrag op 0 zetten (geen bedrag tonen)
                          + "                 (cv.vervaljaar IS NOT NULL AND (cv.vervaljaar - COALESCE(cv.afbouwtijd, 0)) < cv.vervangingsjaar)"
                          + "               OR"
                          // MGE: Volgens mij zijn onderstaande OR voorwaarden niet meer van toepassing omdat in die jaren al een stoplichtje wordt getoond
                          //      en ook niet meer naar toegesleept kan worden. Klopt dit??
                          // Voor het startjaar het bedrag altijd op 0 zetten (geen bedrag tonen).
                          + "                 (cv.startjaar > cv.vervangingsjaar)"
                          + "               OR"
                          // Als registratiedatum het verst in de toekomst ligt en voor Vervanging en Certificering is de eerste inspecte 1 periode verder.
                          // De jaren daarvoor dus 0 opleveren.
                          + "                 ((CV.startjaar + ins_srtcontrole_periode) > cv.vervangingsjaar AND"
                          + "                  cv.starttype = 'A' AND ctr_controle_type != 1 AND"
                          + "                  ((cv.planjaar IS NULL) OR (cv.planjaar IS NOT NULL AND cv.planjaar > cv.vervangingsjaar)) AND"
                          // Geldt alleen als er nog geen geaccordeerde, ter uitvoering staande of verwerkte inspectie is geweest.
                          // Er kan namelijk een inspectie verschoven zijn voor de startdatum bij Vervanging(2) en Certificering(3).
                          // De eerste is bij Vervanging(2) en Certificering(3) standaard gepland op startdatum + periode.
                          + "                  NOT EXISTS (SELECT idsc.ins_deelsrtcontrole_key"
                          + "                                FROM ins_deelsrtcontrole idsc"
                          + "                               WHERE idsc.ins_deel_key = cv.ins_deel_key"
                          + "                                 AND idsc.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                                 AND idsc.ins_scenario_key = cv.ins_scenario_key"
                          + "                                 AND idsc.ins_deelsrtcontrole_status IN (2, 3, 6)"
                          + "                                 AND EXTRACT(YEAR FROM idsc.ins_deelsrtcontrole_freezedate) <= cv.vervangingsjaar))"
                          + "            THEN 0 "
                          + "            ELSE cv.bedrag "
                          + "             END bedrag"
                          + "     , cv.ctr_controle_type"
                          + "     , cv.ctr_discipline_key"
                          + "     , (SELECT ins_discipline_omschrijving"
                            + "        FROM ins_tab_discipline"
                            + "       WHERE ins_discipline_key = CV.ctr_discipline_key) taakcategorie"
                          + "     , cv.ins_scenario_key"
                          + "     , cv.hasscenario2"
                          + "     , cv.scenario_oms"
                          + "     , cv.scenario_aantal"
                          + "     , cv.ins_deelsrtcontrole_status"
                          + "     , cv.hascontroles"
                          + "     , cv.completed"
                          + "     , cv.rejected"
                          + "     , (SELECT COUNT(idsc.ins_deel_key)"
                          + "          FROM ins_deelsrtcontrole idsc"
                          + "         WHERE idsc.ins_deel_key = cv.ins_deel_key"
                          + "           AND idsc.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "           AND idsc.ins_scenario_key = 1"
                          + "           AND idsc.ins_deelsrtcontrole_status = 2"
                          + "           AND EXTRACT(YEAR FROM idsc.ins_deelsrtcontrole_freezedate) = CV.vervangingsjaar) freezed"
                          + "     , (SELECT COUNT(idsc.ins_deel_key)"
                          + "          FROM ins_deelsrtcontrole idsc"
                          + "         WHERE idsc.ins_deel_key = cv.ins_deel_key"
                          + "           AND idsc.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "           AND idsc.ins_scenario_key = 1"
                          + "           AND idsc.ins_deelsrtcontrole_status = 3"
                          + "           AND EXTRACT(YEAR FROM idsc.ins_deelsrtcontrole_freezedate) = CV.vervangingsjaar) execute"
                          + "     , (SELECT idsc.ins_deelsrtcontrole_key"
                          + "          FROM ins_deelsrtcontrole idsc"
                          + "         WHERE idsc.ins_deel_key = cv.ins_deel_key"
                          + "           AND idsc.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "           AND idsc.ins_scenario_key  = 1"
                          + "           AND idsc.ins_deelsrtcontrole_status IN (2" + (finish? ", 3" : "") +  ")) idsc_freezed"
                          + "     , CASE"
                          + "       WHEN ((SELECT COUNT(idsc.ins_deel_key)"
                          + "                FROM ins_deelsrtcontrole idsc"
                          + "               WHERE idsc.ins_deel_key = CV.ins_deel_key"
                          + "                 AND idsc.ins_srtcontrole_key = CV.ins_srtcontrole_key"
                          + "                 AND idsc.ins_deelsrtcontrole_status = 2"
                          + "                 AND EXTRACT(YEAR FROM idsc.ins_deelsrtcontrole_freezedate) = CV.vervangingsjaar) = 0)"
                          + "        AND CV.vervangingsjaar = " + mjb_freeze_or_sys_year
                          + "       THEN 1"
                          + "       ELSE 0"
                          + "       END tobefreezed"
                          + (fulldetails
                            ? "   , 1 aantaltaken"
                            : "   , SUM(1) OVER() AS aantaltaken"
                              + " , 1 aantaltaken_withoutempty")
                          // Bepaling in welk jaar er een inspectie is gepland.
                          // 1) In het jaar dat er nog een geaccordeerde/bevroren(2) inspectie actief is.
                          // 2) In het jaar van de plandatum.
                          // 3) Er is nog geen inspectie geweest en de startdatum is ingevuld.
                          //    Er geldt dan het volgende:
                          //    Voor Controle(1): Eerste inspectie tonen op MAX(startdatum, registratiedatum) van het object.
                          //    Voor Vervanging(2) of Certificering(3):
                          //    a) Als registratiedatum het verst in de toekomst ligt: Eerste inspectie tonen op 1 periode verder dan de registratiedatum.
                          //    b) Als de startdatum het verst in de toekomst ligt: Eerste inspectie tonen op de startdatum.
                          //    De aanmaakdatum/Registratiedatum is altijd ingevuld en als er al een inspectie is geweest, zijn de startdatum en registratiedatum niet meer van belang.
                          // 4) Er is nog geen inspectie geweest en alleen de aanmaakdatum/Registratiedatum ligt in het huidige jaar of in de toekomst.
                          //    Voor Controle(1):
                          //    a) Als registratiedatum < freeze jaar dan eerste inspectie tonen in het freeze jaar
                          //    b) Anders inspectie tonen in het registratiejaar.
                          //    Voor Vervanging(2) of Certificering(3):
                          //    a) Als (registratiedatum + periode) < freeze jaar dan eerste inspectie tonen in het freeze jaar
                          //    b) Anders inspectie tonen in het (registratiejaar + periode)
                          // 5) Er is nog geen inspectie geweest en de startdatum is niet ingevuld en registratiedatum ligt in het verleden. Berekenen jaar.
                          //    a) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Controle(1).
                          //       Volgende inspectie is in het freeze jaar.
                          //    b) Laatste inspectie is NULL (eerste inspectie moet nog komen) en het is een Vervanging(2) of Certificering(3).
                          //       Nextdate is na het freeze jaar?
                          //       Ja)  Vorige inspectie ligt na het start jaar en ligt niet in het aanmaak jaar?
                          //            Ja)  Volgende inspectie is in het freeze jaar.
                          //            Nee) Volgende inspectie is het jaar van de nextdate.
                          //       Nee) De laatst ingeplande inspectie (nextdate) is na of in het start jaar?
                          //            Ja)  Volgende inspectie is in het freeze jaar.
                          //            Nee) Volgende inspectie is in het jaar "nextdatum + periode".
                          //    c) Laatste inspectie is niet NULL. Er is al 1 of meerdere keren geinspecteerd.
                          //       Ligt de laatst ingeplande inspectie (nextdate) na dit jaar?
                          //         Ja)  Volgende inspectie is het jaar van de nextdate (in de toekomst).
                          //         Nee) Volgende inspectie is in het freeze jaar.
                          + "     , CASE"
                          + "       WHEN"
                          + "         EXTRACT(YEAR FROM "
                          + "           COALESCE(CASE"                   // Taak is geaccordeerd (gefreezed) of ter uitvoering. Freeze jaar is het huidige (vervangings)jaar.
                          + "                    WHEN cv.ins_deelsrtcontrole_status IN (2, 3)"
                          + "                    THEN cv.idsc_freezedate_max" // Max nemen om dubbele regels te voorkomen.
                          + "                    ELSE NULL"
                          + "                    END"
                          + "                  , CASE" // 2) Plandatum.
                          + "                    WHEN cv.plandatum IS NOT NULL"
                          + "                    THEN"
                          + "                      CASE"
                          + "                      WHEN EXTRACT(YEAR FROM cv.plandatum) < " + mjb_freeze_or_sys_year
                          + "                      THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                          + "                      ELSE cv.plandatum"
                          + "                      END"
                          + "                    ELSE NULL"
                          + "                    END"
                          + "                  , CASE"
                          + "                    WHEN (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                          + "                            FROM ins_deelsrtcontrole idsc2"
                          + "                           WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                          + "                             AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                             AND idsc2.ins_scenario_key = 1) IS NULL AND"
                          + "                         cv.ins_srtcontroledl_xcp_startdat IS NOT NULL"
                          + "                    THEN" // 3) Startdatum is ingevuld en ligt in het verleden of de toekomst en er is nog geen inspectie geweest.
                          + "                      CASE"
                          + "                      WHEN EXTRACT(YEAR FROM cv.ins_srtcontroledl_xcp_startdat) >= EXTRACT(YEAR FROM cv.ins_deel_aanmaak)"
                          + "                      THEN" // 3a) Startdatum op of na aanmaakdatum/registratiedatum.
                          + "                        CASE"
                          + "                        WHEN EXTRACT(YEAR FROM cv.ins_srtcontroledl_xcp_startdat) < " + mjb_freeze_or_sys_year
                          + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                          + "                        ELSE cv.ins_srtcontroledl_xcp_startdat"
                          + "                        END"
                          + "                      ELSE" // 3b) Aanmaakdatum/Registratiedatum is na de startdatum.
                          + "                        CASE"
                          + "                        WHEN cv.ctr_controle_type = 1"  // Controle(1).
                          + "                        THEN"
                          + "                          CASE"
                          + "                          WHEN EXTRACT(YEAR FROM cv.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                          + "                          THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                          + "                          ELSE cv.ins_deel_aanmaak" // Registratiedatum.
                          + "                          END"
                          + "                        ELSE"  // Vervanging(2), Certificering(3).
                          + "                          CASE"
                          + "                          WHEN EXTRACT(YEAR FROM ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                          + "                          THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                          + "                          ELSE ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)" // 1 periode na registratiedatum.
                          + "                          END"
                          + "                        END"
                          + "                      END"
                          + "                    ELSE NULL"
                          + "                    END"
                          + "                  , CASE"
                          + "                    WHEN (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                          + "                            FROM ins_deelsrtcontrole idsc2"
                          + "                           WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                          + "                             AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                             AND idsc2.ins_scenario_key = 1) IS NULL AND"
                          + "                         EXTRACT(YEAR FROM cv.ins_deel_aanmaak) >= EXTRACT(YEAR FROM SYSDATE)" // Alleen de aanmaakdatum/registratiedatum is ingevuld.
                          + "                    THEN" // 4) Aanmaakdatum/Registratiedatum is ingevuld en ligt in de toekomst en er is nog geen inspectie geweest.
                          + "                      CASE"
                          + "                      WHEN cv.ctr_controle_type = 1"  // Controle(1).
                          + "                      THEN"
                          + "                        CASE"
                          + "                        WHEN EXTRACT( YEAR FROM cv.ins_deel_aanmaak) < " + mjb_freeze_or_sys_year
                          + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                          + "                        ELSE cv.ins_deel_aanmaak"
                          + "                        END"
                          + "                      ELSE"  // Vervanging(2), Certificering(3).
                          + "                        CASE"
                          + "                        WHEN EXTRACT( YEAR FROM ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)) < " + mjb_freeze_or_sys_year
                          + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"
                          + "                        ELSE ADD_MONTHS(cv.ins_deel_aanmaak, 12 * cv.ins_srtcontrole_periode)"
                          + "                        END"
                          + "                      END"
                          + "                    ELSE NULL"
                          + "                    END"
                          + "                  , CASE"                                // 5) Berekenen jaar.
                          + "                    WHEN (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                          + "                                 FROM ins_deelsrtcontrole idsc2"
                          + "                                WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                          + "                                  AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                                  AND idsc2.ins_scenario_key = 1) IS NULL AND cv.ctr_controle_type = 1"  // Controle(1).
                          + "                    THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')" // 5a)
                          + "                    WHEN (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                          + "                                 FROM ins_deelsrtcontrole idsc2"
                          + "                                WHERE idsc2.ins_deel_key = cv.ins_deel_key"
                          + "                                  AND idsc2.ins_srtcontrole_key = cv.ins_srtcontrole_key"
                          + "                                  AND idsc2.ins_scenario_key = 1) IS NULL AND cv.ctr_controle_type != 1" // Vervanging(2), Certificering(3).
                          + "                    THEN"                   // 5b) Er is nog geen inspectie geweest
                          + "                      CASE"
                          + "                      WHEN EXTRACT(YEAR FROM cv.nextdate) > " + mjb_freeze_or_sys_year
                          + "                      THEN"                 // Nextdate is na de freeze datum.
                          + "                        CASE"
                          + "                        WHEN EXTRACT(YEAR FROM ADD_MONTHS(cv.nextdate, -1 * 12 * cv.ins_srtcontrole_periode)) >= " + mjb_start_year + " AND"
                          + "                             EXTRACT(YEAR FROM ADD_MONTHS(cv.nextdate, -1 * 12 * cv.ins_srtcontrole_periode)) != EXTRACT(YEAR FROM cv.ins_deel_aanmaak)"
                          + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"               // Vorige inspectie ligt tussen start en freeze jaar (Nu ligt er ook tussen).
                          + "                        ELSE cv.nextdate"
                          + "                        END"
                          + "                      ELSE"                 // Nextdate is voor of in het freeze jaar.
                          + "                        CASE"
                          + "                        WHEN EXTRACT(YEAR FROM cv.nextdate) >= " + mjb_start_year
                          + "                        THEN TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"               // Nextdate tussen start en freeze jaar.
                          + "                        ELSE ADD_MONTHS(cv.nextdate, 12 * cv.ins_srtcontrole_periode)"        // Nextdate voor het start jaar.
                          + "                        END"
                          + "                      END"
                          + "                    ELSE"                   // 5c) Laatste IS NOT NULL. Er is al een inspectie geweest.
                          + "                      CASE"
                          + "                      WHEN EXTRACT(YEAR FROM cv.nextdate) > EXTRACT(YEAR FROM SYSDATE)"
                          + "                      THEN cv.nextdate"                                                       // Volgende inspectie is in de toekomst.
                                                                                                                           // Geaccordeerde laatste inspectie wordt in het begin al afgevangen.
                                                                                                                           // en niet hier zoals bij org_nextdate in functie getmjblist_sql.
                          + "                      ELSE TO_DATE('" + mjb_freeze_or_sys_year + "', 'YYYY')"                 // Laatst ingeplande inspectie is nog steeds niet uitgevoerd. Dus opnieuw in het freeze jaar tonen zodat deze daar gefreezed kan worden.
                          + "                      END"
                          + "                    END)) = " + mjb_freeze_or_sys_year
                          + "       THEN 1"
                          + "       ELSE 0"
                          + "       END isFreezeYear"
                          + "     , CV.laatste_not_suc"
                          + (execute
                            ? "   , (" + sql_melding + ") melding"
                              + " , (SELECT sd.ins_srtdiscipline_prefix"
                              + "      FROM mld_melding m"
                              + "         , mld_stdmelding s"
                              + "         , mld_discipline md"
                              + "         , ins_srtdiscipline sd"
                              + "     WHERE m.mld_stdmelding_key = s.mld_stdmelding_key"
                              + "       AND s.mld_ins_discipline_key = md.ins_discipline_key"
                              + "       AND md.ins_srtdiscipline_key = sd.ins_srtdiscipline_key"
                              + "       AND m.mld_melding_key = (" + sql_melding + ")) prefix"
                            : "")
                          + (algFlexParams && algFlexParams.anyflex
                            ? "   , CV.algflex"
                            : "")
                          + (insFlexParams && insFlexParams.anyflex
                            ? "   , CV.insflex"
                            : "")
                          + "  FROM (" + sql_cost_verval + ") cv"
                          // Taken die VOOR het eerste jaar dat getoond wordt vervallen zijn moeten NIET getoond worden.
                          // Taken die IN   het eerste jaar dat getoond wordt vervallen zijn moeten WEL  getoond worden.
                          + " WHERE (vervaljaar IS NULL OR vervaljaar >= " + jaren[0] + ")"
                          + (showunfin
                            ? " AND cv.ins_deelsrtcontrole_status != 6"          // De inspectie moet niet voltooid zijn.
                            : "");

             if (execute)
               sql_cost += " AND cv.ins_deelsrtcontrole_status IN ("
                         + (mjbStatus2? "2" : "")
                         + (mjbStatus2 && mjbStatus3? ", " : "")
                         + (mjbStatus3? "3" : "")
                         + ")";        // Alleen geaccordeerde en ter uitvoering staande inspecties tonen.


             var sqlArray = [];
             var sql_cost_where = "";
             if (mjbMoved) // Aangepast.
             {
               sqlArray.push("isPlanned = 1");
             }
             if (mjbFreezed) // In behandeling (Bevroren).
             {
               sqlArray.push("idsc_freezedate_max IS NOT NULL AND ins_deelsrtcontrole_status IN (2, 3)");
             }
             if (mjbXcped) // Aangepast.
             {
               sqlArray.push("ins_srtcontroledl_xcp_key IS NOT NULL AND ins_scenario_key = 1");
             }

             if (sqlArray.length)
               sql_cost_where = " WHERE ((" + sqlArray.join(") OR (") + "))";

             if (!fulldetails)
             {
               var fields = [];
               if (groupby == 1 || groupby == 2 || groupby == 3 || moredetail == 2)
               {
                 fields.push("alg_district_omschrijving");
                 if (groupby == 2 || groupby == 3 || moredetail == 2)
                 {
                   if (groupby == 2 && ins_score_enabled)
                     fields.push("alg_locatie_mjb_score1");
                   fields.push("alg_locatie_key");
                   fields.push("alg_locatie_code");
                   fields.push("alg_locatie_omschrijving");
                   if (groupby == 3 || moredetail == 2)
                   {
                     fields.push("alg_gebouw_key");
                     fields.push("alg_gebouw_code");
                     fields.push("alg_gebouw_naam");
                     if (ins_score_enabled)
                       fields.push("alg_gebouw_mjb_score1");
                     fields.push("alg_terreinsector_key");
                     fields.push("alg_terreinsector_code");
                     fields.push("alg_terreinsector_naam");
                   }
                 }
               }
               if ((groupby >= 4 && groupby <= 7) || moredetail == 1)
                 fields.push("ins_discipline_omschrijving");
               if ((groupby >= 5 && groupby <= 7) || moredetail == 1)
                 fields.push("ins_srtgroep_omschrijving");
               if (groupby == 6 || groupby == 7 || moredetail == 1)
                 fields.push("ins_srtdeel_omschrijving");
               if (groupby == 7)
               {
                 fields.push("ins_deel_omschrijving");
                 fields.push("alg_ruimte_key");
                 fields.push("alg_ruimte_nr");
                 fields.push("alg_ruimte_omschrijving");
               }
               if (groupby == 7 || groupby == 9) // bij omschrijving hoort ook aantal met eenheid.
               {
                 fields.push("ins_deel_aantal");
                 fields.push("ins_srtdeel_eenheid");
                 if (ins_score_enabled)
                 {
                   fields.push("ins_deel_mjb_score1");
                   fields.push("ins_srtdeel_mjb_grensscore1");
                   fields.push("ins_deel_mjb_score2");
                 }
               }

               sql_cost = "SELECT " + fields.join(", ")
                        + "     , keyColumn"
                        + (keyColumn == "dl.ins_deel_key"
                          ? "   , ins_deel_opmerking"
                          : "")
                        + "     , vervangingsjaar"
                        + "     , SUM(ROUND(bedrag, 0)) bedrag"       // Bedragen per regel afronden op hele euro s. Dit gebeurt ook bij Groepering "Taak" zodat de bedragen bij beiden dan gelijk zijn.
                        + "     , SUM(ROUND(orgbedrag, 0)) orgbedrag" // Bedragen per regel afronden op hele euro s. Dit gebeurt ook bij Groepering "Taak" zodat de bedragen bij beiden dan gelijk zijn.
                        + "     , hasscenario2"
                        + "     , ins_scenario_key"
                        + "     , SUM(freezed) AS freezed"
                        + "     , SUM(tobefreezed) tobefreezed"
                        + "     , aantaltaken"
                        + "     , SUM(aantaltaken_withoutempty) aantaltaken_withoutempty"
                        + (show_scenario_oms ? ", scenario_oms, scenario_aantal" : "")
                        + "  FROM (" + sql_cost + ")"
                        + sql_cost_where
                        + " GROUP BY " + fields.join(", ")
                        + "         , keyColumn"
                        + (keyColumn == "dl.ins_deel_key"
                          ? "     , ins_deel_opmerking"
                          : "")
                        + "        , vervangingsjaar"
                        + "        , hasscenario2"
                        + "        , ins_scenario_key"
                        + "        , aantaltaken"
                        + (show_scenario_oms ? ", scenario_oms, scenario_aantal" : "");
             }

             var sql = "SELECT *"
                     + "  FROM ("
                     + sql_cost
                     + "       ) PIVOT (SUM(bedrag)"
                     + "              , SUM(orgbedrag) AS orgbedrag"
                     + (fulldetails
                       ? "            , SUM(completed) AS completed"
                         + "          , SUM(rejected) AS rejected"
                         + "          , SUM(execute) AS execute"
                       : "            , SUM(aantaltaken_withoutempty) aantaltaken_withoutempty")
                     + "              , SUM(freezed) AS freezed"
                     + "              , SUM(tobefreezed) AS tobefreezed"
                     + "                FOR vervangingsjaar IN (" + jaren.join(",") + ") )";

             if (scenario > 1)
             {
               if (!actsit)
                 sql += " WHERE ins_scenario_key IN (" + scenario + ") AND hasscenario2 = 1";
               else
                 sql += " WHERE ins_scenario_key IN (" + scenario + ") OR (hasscenario2 = 0 AND ins_scenario_key = 1)";
             }
             else
             {
               // actsit hier geen invloed.
               sql += " WHERE ins_scenario_key = 1";
             }

             if (ins_score_enabled)
             {
               // Conditie score.
               // Niet gemeten objecten doen wel mee in dit filter. Deze objecten worden dus niet getoond als er een waarde is ingevuld.
               var mjb_score = "";
               if (groupby == 2)
                 mjb_score = "alg_locatie_mjb_score1";
               else if (groupby == 3)
                 mjb_score = "alg_gebouw_mjb_score1";
               else if (groupby == 7 || groupby == 9)
                 mjb_score = "ins_deel_mjb_score1";

               if (mjb_score != "" && fitness_score1_from > 0)
                 sql += " AND " + mjb_score + " >= " + fitness_score1_from;
               if (mjb_score != "" && fitness_score1_through > 0)
                 sql += " AND " + mjb_score + " <= " + fitness_score1_through;

               if (groupby == 7 || groupby == 9)
               {
                 // Negatieve afwijking (=dus slechter) van de conditiescore (ins_deel_mjb_score1) in hele getallen t.o.v. de norm (ins_srtdeel_mjb_grensscore1) .
                 // Wanneer een element NIET is gemeten (conditiemeting is niet geweest) dan is ins_deel_score1 LEEG,
                 // Dan doet het elelement niet mee in het filter "afwijking". Want er is dan per defintie geen afwijking, omdat dit niet bekend is.
                 var fitness_score1_neg = [];
                 if (fitness_score1_from_neg > 0 || fitness_score1_through_neg > 0)
                 {
                   if (fitness_score1_from_neg > 0)
                     fitness_score1_neg.push("ins_deel_mjb_score1 >= (ins_srtdeel_mjb_grensscore1 + " + fitness_score1_from_neg + ")");
                   if (fitness_score1_through_neg > 0)
                   {
                     fitness_score1_neg.push("ins_deel_mjb_score1 <= (ins_srtdeel_mjb_grensscore1 + " + fitness_score1_through_neg + ")");
                     if (fitness_score1_from_neg == -1)
                       fitness_score1_neg.push("ins_deel_mjb_score1 > ins_srtdeel_mjb_grensscore1");
                   }
                   sql += "AND (" + fitness_score1_neg.join(" AND ") + ")"
                 }

                 // Positieve afwijking (=dus beter) van de conditiescore (ins_deel_mjb_score1) in hele getallen t.o.v. de norm (ins_srtdeel_mjb_grensscore1) .
                 // Wanneer een element NIET is gemeten (conditiemeting is niet geweest) dan is ins_deel_score1 LEEG,
                 // Dan doet het elelement niet mee in het filter "afwijking". Want er is dan per defintie geen afwijking, omdat dit niet bekend is.
                 var fitness_score1_pos = [];
                 if (fitness_score1_from_pos > 0 || fitness_score1_through_pos > 0)
                 {
                   if (fitness_score1_from_pos > 0)
                     fitness_score1_pos.push("ins_deel_mjb_score1 <= (ins_srtdeel_mjb_grensscore1 - " + fitness_score1_from_pos + ")");
                   if (fitness_score1_through_pos > 0)
                   {
                     fitness_score1_pos.push("ins_deel_mjb_score1 >= (ins_srtdeel_mjb_grensscore1 - " + fitness_score1_through_pos + ")");
                     if (fitness_score1_from_pos == -1)
                       fitness_score1_pos.push("ins_deel_mjb_score1 < ins_srtdeel_mjb_grensscore1");
                   }
                   sql += "AND (" + fitness_score1_pos.join(" AND ") + ")"
                 }

                 // Prioriteitsscore.
                 // Niet gemeten objecten doen wel mee in dit filter. Deze objecten worden dus niet getoond als er een waarde is ingevuld.
                 if (priority_score2_from > 0)
                   sql += " AND ins_deel_mjb_score2 >= " + priority_score2_from;
                 if (priority_score2_through > 0)
                   sql += " AND ins_deel_mjb_score2 <= " + priority_score2_through;
               }
             }

             if (fulldetails && sqlArray.length)
               sql += " AND ((" + sqlArray.join(") OR (") + "))";

             switch (groupby)
             {
               case 1: sql += " ORDER BY alg_district_omschrijving";
                       break;
               case 2: sql += " ORDER BY alg_district_omschrijving"
                            + "        , alg_locatie_code"
                            + "        , alg_locatie_omschrijving";
                       break;
               case 3: sql += " ORDER BY alg_district_omschrijving"
                            + "        , alg_locatie_omschrijving"  // eigenlijk S(alg_loc_string)
                            + "        , alg_gebouw_code"
                            + "        , alg_gebouw_naam";
                       break;
               case 4: sql += " ORDER BY ins_discipline_omschrijving";
                       break;
               case 5: sql += " ORDER BY ins_discipline_omschrijving"
                            + "        , ins_srtgroep_omschrijving";
                       break;
               case 6: sql += " ORDER BY ins_discipline_omschrijving"
                            + "        , ins_srtgroep_omschrijving"
                            + "        , ins_srtdeel_omschrijving";
                       break;
               case 7: sql += " ORDER BY ins_discipline_omschrijving"
                            + "        , ins_srtgroep_omschrijving"
                            + "        , ins_srtdeel_omschrijving"
                            + "        , ins_deel_omschrijving";
                       break;
               case 9: sql += " ORDER BY alg_district_omschrijving"
                            + "        , ins_srtcontrole_omschrijving"
                            + "        , alg_locatie_code"
                            + "        , alg_gebouw_code"
                            + "        , alg_gebouw_naam"
                            + (mjb_show_srt_with_tasks
                              ? "      , ins_discipline_omschrijving"
                                + "    , ins_srtgroep_omschrijving"
                                + "    , ins_srtdeel_omschrijving"
                              : "")
                            + "        , ins_deel_omschrijving"
                            + "        , alg_ruimte_nr";
                       break;
             }

             // Bulkactie accorderen (freeze), uitvoeren (execute) of voltooien/afronden (finish).
             // Ik moet nog de juiste insert waarden ophalen voor alle objecten die de sql oplevert.
             if (niveau >= 1 && niveau <= 7 && (pricechange || freeze || unfreeze || execute || finish))
             { // Prijswijziging (pricechange), Accorderen (Freeze), Uitvoeren (Execute) of Voltooien/Afronden (Finish).
               if (pricechange)
               {
                 var mjblist_sql_select = "SELECT xcp.ins_deel_key"
                                        + "     , xcp.ins_srtcontrole_key"
                                        + "     , COALESCE(xcp.ins_srtcontroledl_xcp_key, -1) ins_srtcontroledl_xcp_key";
                 for (var j = 0; j < jaren.length; j++)
                 {
                   mjblist_sql_select += ", result.\"" + jaren[j] + "\"";
                 }
               }
               else if (freeze || unfreeze)
               {
                 var mjblist_sql_select = "SELECT xcp.ins_deel_key"
                                        + "     , xcp.ins_srtcontrole_key"
                                        + "     , CASE"
                                        + "       WHEN result.ins_deelsrtcontrole_status IS NOT NULL"
                                        + "       THEN (SELECT ins.nextcyclusdate (xcp.ins_deel_key, xcp.ins_srtcontrole_key, 1, 1) FROM DUAL)"
                                        + "       ELSE NULL"
                                        + "       END nextdate"
                                        + "     , result.ins_deelsrtcontrole_status"
                                        + "     , result.\"" + mjb_freeze_or_sys_year + "\" freeze_bedrag"
                                        + "     , CASE"
                                        + "       WHEN result.\"" + mjb_freeze_or_sys_year + "\" = 0 AND result.\"" + mjb_freeze_or_sys_year + "_ORGBEDRAG\" IS NOT NULL AND result.\"" + mjb_freeze_or_sys_year + "_ORGBEDRAG\" > 0"
                                        + "       THEN " + safe.quoted_sql(L("lcl_mjb_performed_high"))
                                        + "       ELSE ''"
                                        + "       END opm_has_higherprio" // Opmerking als het een hogere prio heeft (has_higherprio)
                                        + "     , isd.ins_srtdeel_omschrijving"
                                        + "     , xcp.ins_srtcontrole_omschrijving"
                                        + "     , xcp.ins_srtcontrole_info";
               }
               else if (execute)
               {
                 var mjblist_sql_select = "SELECT xcp.ins_deel_key"
                                        + "     , xcp.ins_srtcontrole_key"
                                        + "     , result.ins_deelsrtcontrole_key"
                                        + "     , result.ctr_discipline_key";
               }
               else // finish
               {
                 if (getsumtypes)
                 {
                   var mjblist_sql_select = "SELECT SUM(CASE"
                                          + "           WHEN xcp.ctr_controle_type = 1"
                                          + "           THEN 1"
                                          + "           ELSE 0"
                                          + "           END) sumtype1"
                                          + "     , SUM(CASE"
                                          + "           WHEN xcp.ctr_controle_type = 2"
                                          + "           THEN 1"
                                          + "           ELSE 0"
                                          + "           END) sumtype2"
                                          + "     , SUM(CASE"
                                          + "           WHEN xcp.ctr_controle_type = 3"
                                          + "           THEN 1"
                                          + "           ELSE 0"
                                          + "           END) sumtype3";
                 }
                 else
                 {
                   var mjblist_sql_select = "SELECT xcp.ins_deel_key"
                                          + "     , xcp.ins_srtcontrole_key"
                                          + "     , result.ctr_controle_type"
                                          + "     , CASE"
                                          + "       WHEN (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                          + "               FROM ins_deelsrtcontrole idsc2"
                                          + "              WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                          + "                 AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                          + "                 AND idsc2.ins_scenario_key = xcp.ins_scenario_key"
                                          + "                 AND idsc2.ins_deelsrtcontrole_status = 6) IS NOT NULL" // Er is al een inspectie geweest.
                                          + "       THEN (SELECT ins.nextcyclusdate (xcp.ins_deel_key, xcp.ins_srtcontrole_key, 1, 1) FROM DUAL)"
                                          + "       ELSE SYSDATE"                                                    // Er is nog geen inspectie geweest. De org date wordt nu.
                                          + "       END nextdate"
                                          + "     , (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                          + "        FROM ins_deelsrtcontrole idsc2"
                                          + "       WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                          + "         AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                          + "         AND idsc2.ins_scenario_key = xcp.ins_scenario_key) ins_deelsrtcontrole_key"
                                          + "     , (SELECT cm.ins_controlemode_oms"
                                          + "          FROM ins_controlemode cm"
                                          + "         WHERE cm.ins_controlemode_key IN (" + sel_controlemode123.join(",") + ")"
                                          + "           AND cm.ins_srtcontrole_type = result.ctr_controle_type) cm_oms"
                                          + "     , (SELECT cd.ins_discipline_omschrijving"
                                          + "          FROM ctr_discipline cd"
                                          + "         WHERE cd.ins_discipline_key = xcp.ctr_discipline_key) ctr_disc_oms"
                                          + "     , (SELECT idsc2.ins_deelsrtcontrole_opmerking"
                                          + "          FROM ins_deelsrtcontrole idsc2"
                                          + "         WHERE ins_deelsrtcontrole_key = (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                          + "                                            FROM ins_deelsrtcontrole idsc2"
                                          + "                                           WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                          + "                                             AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                          + "                                             AND idsc2.ins_scenario_key = xcp.ins_scenario_key)) ins_deelsrtcontrole_opmerking";
                 }
               }


               var mjblist_sql = mjblist_sql_select
                               + "  FROM ins_v_defined_inspect_xcp xcp"
                               + "     , ins_v_deelenonderdeel dl" // I.v.m. ORA-03113 fout: ins_v_aanwezigdeel vervangen door ins_deel en verder uitgeschreven (FSN#51212).
                               + "     , ins_srtdeel isd"
                               + "     , ins_srtgroep isg"
                               + "     , ins_discipline dd"
                               + "     , alg_district d"
                               + "     , alg_locatie l"
                               + "     , alg_gebouw g"
                               + "     , alg_verdieping v"
                               + "     , alg_ruimte r"
                               + "     , (" + sql + ") result"
                               + " WHERE xcp.ins_deel_key = dl.ins_deel_key"
                               + "   AND dl.ins_deel_verwijder IS NULL"
                               + "   AND dl.ins_srtdeel_key = isd.ins_srtdeel_key"
                               + "   AND isd.ins_srtgroep_key = isg.ins_srtgroep_key"
                               + "   AND isg.ins_discipline_key = dd.ins_discipline_key"
                               + "   AND dl.ins_alg_ruimte_key = r.alg_ruimte_key"
                               + "   AND r.alg_verdieping_key = v.alg_verdieping_key"
                               + "   AND v.alg_gebouw_key = g.alg_gebouw_key"
                               + "   AND g.alg_locatie_key = l.alg_locatie_key"
                               + "   AND d.alg_district_key = l.alg_district_key"
                               + "   AND xcp.ins_deel_key = result.ins_deel_key"
                               + "   AND xcp.ins_srtcontrole_key = result.ins_srtcontrole_key"
                               // Inspectie mag niet op dezelfde dag plaatsvinden
                               // Als er nog geen inspectie is geweest neem dan gisteren (sysdate - 1).
                               + "   AND COALESCE((SELECT TRUNC(idsc2.ins_deelsrtcontrole_datum)"
                               + "                   FROM ins_deelsrtcontrole idsc2"
                               + "                   WHERE ins_deelsrtcontrole_key = (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                               + "                                                      FROM ins_deelsrtcontrole idsc2"
                               + "                                                     WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                               + "                                                       AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                               + "                                                       AND idsc2.ins_scenario_key = xcp.ins_scenario_key"
                               + "                                                       AND idsc2.ins_deelsrtcontrole_status = 6)), (TRUNC(SYSDATE-1))) != TRUNC(SYSDATE)";

               // Autorisatie controleren i.p.v. canInspStartReq (Accorderen (Freeze)) en canInspFinishReq (Voltooien/Afronden (Finish)):
               // 0) De canDoNextAction voorwaarde is voor MJOB (interval modus(1)) als volgt:
               //    Interval mode(1): Freeze: Inspectie kan niet geaccordeerd(gestart(2)) worden als de vorige inspectie nog geaccordeerd(gestart(2)) is.
               //                      Finish: Inspectie kan voltooid/afgerond(6) worden als (alleen) de laatste inspectie geaccordeer(gestart(2)) is.
               //                              Daar zorgt de freeze actie en punt 2) ook wel voor.
               // 1) Alleen voor Accorderen (Freeze): niet vervallen.
               // 2) Freeze: status <= 0 of status == 6
               //    Unfreeze: status == 2
               //    Finish: status == 2 of 3
               // 3) actief object
               // 4) hasCTRFOFWrite (freez) of hasCTRUSEWrite (finish) rechten.
               // 5) Freeze, Unfreeze: bij instelling "Actieve acties" het vinkje "Starten" aangevinkt.
               //    Finish:           bij instelling "Actieve acties" het vinkje "Afronden" aangevinkt.
               // 6) geen scenario (scenario_key is 1)
               // 7) ismjob
               // 8) isFreezeYear
               // 9) readuse rechten.
               //
               // 0) MJOB dus interval mode(1).

               if (freeze || unfreeze || finish)
                 mjblist_sql += (freeze
                                ? " AND result.idsc_freezed IS NULL"                                                            // 0) Freeze: Vorige inspectie is niet geaccordeerd(gestart(2)).
                                : " AND result.idsc_freezed = result.ins_deelsrtcontrole_key")                                  //    Unfreeze, Finish: Laatste inspectie is geaccordeerd(gestart(2) of bij Finish ook nog in uitvoering(3)).
                              + (freeze
                                ? " AND (xcp.ins_srtcontroledl_xcp_eind IS NULL OR xcp.ins_srtcontroledl_xcp_eind >= SYSDATE)"  // 1) Freeze: Niet vervallen.
                                : "")                                                                                           //    Unfreeze, Finish: Maakt niet uit.
                              + (freeze
                                ? " AND (EXISTS"                                                                                // 2) Freeze: Geen controles of laatste controle status 0 of 6.
                                  + "           (SELECT idsc1.ins_deelsrtcontrole_status"
                                  + "              FROM ins_deelsrtcontrole idsc1"
                                  + "             WHERE idsc1.ins_deelsrtcontrole_key = (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                  + "                                                      FROM ins_deelsrtcontrole idsc2"
                                  + "                                                     WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                  + "                                                       AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                  + "                                                       AND idsc2.ins_scenario_key = xcp.ins_scenario_key)"
                                  + "               AND (idsc1.ins_deelsrtcontrole_status = 0"
                                  + "                 OR (idsc1.ins_deelsrtcontrole_status = 6 AND EXTRACT(YEAR FROM idsc1.ins_deelsrtcontrole_freezedate) != EXTRACT(YEAR FROM SYSDATE)))"
                                  // Accorderen mag niet als er nog een lopende inspectie voltooid dient te worden.
                                  + "               AND NOT EXISTS (SELECT idsc2.ins_deelsrtcontrole_key"
                                  + "                                 FROM ins_deelsrtcontrole idsc2"
                                  + "                                WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                  + "                                  AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                  + "                                  AND idsc2.ins_scenario_key = xcp.ins_scenario_key"
                                  + "                                  AND idsc2.ins_deelsrtcontrole_status IN (2, 3, 5))"
                                  + "           )"
                                  + " OR NOT EXISTS"
                                  + "               (SELECT idsc2.ins_deelsrtcontrole_key"
                                  + "                  FROM ins_deelsrtcontrole idsc2"
                                  + "                 WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                  + "                   AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                  + "                   AND idsc2.ins_scenario_key = xcp.ins_scenario_key))"
                                : " AND EXISTS"                                                                                 //    Unfreeze: Laatste controle status 2.
                                  + "          (SELECT idsc1.ins_deelsrtcontrole_status"                                        //    Finish:   Laatste controle status 2 of 3.
                                  + "             FROM ins_deelsrtcontrole idsc1"
                                  + "            WHERE idsc1.ins_deelsrtcontrole_key = (SELECT MAX(idsc2.ins_deelsrtcontrole_key)"
                                  + "                                                     FROM ins_deelsrtcontrole idsc2"
                                  + "                                                    WHERE idsc2.ins_deel_key = xcp.ins_deel_key"
                                  + "                                                      AND idsc2.ins_srtcontrole_key = xcp.ins_srtcontrole_key"
                                  + "                                                      AND idsc2.ins_scenario_key = xcp.ins_scenario_key)"
                                  + "              AND idsc1.ins_deelsrtcontrole_status IN (2" + (finish? ", 3" : "") + ")"
                                  + "              AND EXTRACT(YEAR FROM idsc1.ins_deelsrtcontrole_freezedate) <= " + mjb_freeze_or_sys_year
                                  + "          )");

               if (pricechange)
                 mjblist_sql += " AND (xcp.ins_srtcontroledl_xcp_eind IS NULL OR xcp.ins_srtcontroledl_xcp_eind >= SYSDATE)";   // 1) Prijswijziging: Niet vervallen.

               mjblist_sql += "   AND ins_deel_actief = 1"                                                                      // 3) Actief object.
                            + "   AND xcp.ctr_discipline_key IN (SELECT w.ins_discipline_key"                                   // 4) hasCTRFOFWrite rechten (freeze)
                            + "                                    FROM fac_v_webgebruiker w"                                   //    hasCTRUSEWrite rechten (finish)
                            + "                                       , fac_functie f"
                            + "                                   WHERE w.fac_functie_key = f.fac_functie_key"
                            + "                                     AND f.fac_functie_code = '" + (freeze? "WEB_CTRFOF" : "WEB_CTRUSE") + "'"
                            + "                                     AND w.fac_gebruiker_prs_level_write < 9"
                            + "                                     AND w.fac_gebruiker_alg_level_write < 9"
                            + "                                     AND w.prs_perslid_key = " + user_key + ")";

               if (freeze || unfreeze || finish)
                 mjblist_sql += (freeze || unfreeze
                                ? " AND BITAND(xcp.ins_srtcontrole_options, 2) = 2"                                             // 5) Freeze, Unfreeze: Het vinkje "Starten" aangevinkt.
                                : " AND BITAND(xcp.ins_srtcontrole_options, 8) = 8");                                           //    Finish: Het vinkje "Afronden" aangevinkt.

               if (pricechange)
                 mjblist_sql += " AND (BITAND(xcp.ins_srtcontrole_options, 1) = 1  OR "                                          // 5) Prijswijziging: een vinkje aangevinkt.
                              + "      BITAND(xcp.ins_srtcontrole_options, 2) = 2  OR "
                              + "      BITAND(xcp.ins_srtcontrole_options, 4) = 4  OR "
                              + "      BITAND(xcp.ins_srtcontrole_options, 8) = 8)";

               mjblist_sql += "   AND xcp.ins_scenario_key = 1"                                                                 // 6) Geen scenario.
                            + "   AND xcp.ctr_ismjob = 1"                                                                       // 7) ismjob.
                            + (freeze
                              ? " AND result.\"" + mjb_freeze_or_sys_year + "\" IS NOT NULL"                                    // 8) isFreezeYear, bedrag in mjb_freeze_year is niet NULL.
                              : "");

               sql = discxalg3d(mjblist_sql,                                                                                    // 9) 3D-readuse rechten.
                                "dd.ins_discipline_key",
                                "d.alg_regio_key",
                                "d.alg_district_key",
                                "l.alg_locatie_key",
                                "g.alg_gebouw_key",
                                "v.alg_verdieping_key",
                                "r.alg_ruimte_key",
                                "WEB_INSUSE",  //autfunction,
                                "",
                                false); // forwrite => read

               sql += " ORDER BY xcp.ins_deel_key"
                    + "        , xcp.ins_srtcontrole_key";
             }
             else if (showunfin || execute)
             {
               var sql = "SELECT *"
                       + "  FROM (" + sql + ") result"
                       + " WHERE result.\"" + mjb_freeze_or_sys_year + "\" IS NOT NULL"; // Er moeten bedragen in het jaar zijn vermeld.

               for (var j = 0; j < jaren.length; j++)
               {
                 if (jaren[j] < mjb_freeze_or_sys_year)
                   sql += " OR result.\"" + jaren[j] + "\" IS NOT NULL";        // Of er is een bedrag in de jaren/het jaar voor het freeze jaar.
               }
             }
             return sql;
           },

       saveXcp:
           function (ins_key, srtcontrole_key, params)
           {
             var xcp_key = params.xcp_key;
             var eenheid = params.eenheid;
             var periode = params.periode;
             var kp_key = params.kp_key;
             var aantal = params.aantal;
             var aanteh = params.aanteh;
             var kosten1 = params.kosten1;
             var kosten2 = params.kosten2;
             var kosten3 = params.kosten3;
             var uren = params.uren;
             var materiaal = params.materiaal;
             var perc = params.perc;
             var groep = params.groep;
             var startdatum = params.startdatum;
             var vervaldatum = params.vervaldatum;
             var opmerk = params.opmerk;
             var bits = params.bits;
             var isScenario = params.isScenario;
             var scen_key = params.scen_key; // Doorvoeren scenario.
             var commit = params.commit; // Doorvoeren scenario.

             // Ophalen standaard waarden.
             var sql = "SELECT d.ins_deel_aantal"
                     + "     , sd.ins_srtdeel_eenheid"
                     + "     , isc.ins_srtcontrole_eenheid"
                     + "     , isc.ins_srtcontrole_periode"
                     + "     , isc.prs_kostenplaats_key"
                     + "     , isc.ins_srtcontrole_bits"
                     + "     , isc.ins_srtcontrole_kosten"
                     + "     , isc.ins_srtcontrole_kosten2"
                     + "     , isc.ins_srtcontrole_kosten3"
                     + "     , isc.ins_srtcontrole_uren"
                     + "     , isc.ins_srtcontrole_materiaal"
                     + "     , isc.ins_srtcontrole_percentage"
                     + "     , ins_srtcontrole_groep"
                     + "     , isc.ins_srtcontrole_eind"
                     + "     , isc.ins_srtcontrole_opmerking"
                     + "     , isc.ctr_discipline_key"
                     + "     , isc.ins_srtcontrole_omschrijving"
                     + "     , cd.ins_discipline_omschrijving"
                     + "     , (SELECT xcp1.ins_srtcontroledl_xcp_key"
                     + "          FROM ins_srtcontroledl_xcp xcp1"
                     + "         WHERE xcp1.ins_deel_key = d.ins_deel_key"
                     + "           AND xcp1.ins_srtcontrole_key = isc.ins_srtcontrole_key"
                     + "           AND xcp1.ins_scenario_key = isc.ins_scenario_key) ins_srtcontroledl_xcp_key"
                     + "  FROM ins_srtcontrole isc"
                     + "     , ins_deel d"
                     + "     , ins_srtdeel sd"
                     + "     , ctr_v_aanwezigdiscipline cd"
                     + " WHERE sd.ins_srtdeel_key = d.ins_srtdeel_key"
                     + "   AND (isc.ins_srtcontrole_niveau = 'S'"
                     + "    AND isc.ins_srtinstallatie_key = d.ins_srtdeel_key"
                     + "     OR isc.ins_srtcontrole_niveau = 'G'"
                     + "    AND isc.ins_srtinstallatie_key = sd.ins_srtgroep_key"
                     + "     OR isc.ins_srtcontrole_niveau = 'D'"
                     + "    AND isc.ins_srtinstallatie_key = d.ins_discipline_key)"
                     + "   AND isc.ctr_discipline_key = cd.ins_discipline_key"
                     + "   AND isc.ins_scenario_key = 1"
                     + "   AND d.ins_deel_key = " + ins_key
                     + "   AND isc.ins_srtcontrole_key = " + srtcontrole_key;
             var oRs = Oracle.Execute(sql);
             lcl.set_dialect(oRs("ctr_discipline_key").Value, "CTR_DISCIPLINE_KEY");

             var aantal_std = oRs("ins_deel_aantal").Value;
             var aanteh_std = oRs("ins_srtdeel_eenheid").Value;
             var eenheid_std = oRs("ins_srtcontrole_eenheid").Value;
             var periode_std = oRs("ins_srtcontrole_periode").Value;
             var kp_key_std = oRs("prs_kostenplaats_key").Value;
             var bits_std = oRs("ins_srtcontrole_bits").Value;
             var kosten1_std = oRs("ins_srtcontrole_kosten").Value;
             var kosten2_std = oRs("ins_srtcontrole_kosten2").Value;
             var kosten3_std = oRs("ins_srtcontrole_kosten3").Value;
             var uren_std = oRs("ins_srtcontrole_uren").Value;
             var materiaal_std = oRs("ins_srtcontrole_materiaal").Value;
             var perc_std = oRs("ins_srtcontrole_percentage").Value;
             var groep_std = oRs("ins_srtcontrole_groep").Value;
             var opmerk_std = oRs("ins_srtcontrole_opmerking").Value;
             var srtcontrole_oms = oRs("ins_srtcontrole_omschrijving").Value;
             var ctrdisc_oms = oRs("ins_discipline_omschrijving").Value;

             var vervaldatum_std = oRs("ins_srtcontrole_eind").Value != null? new Date(oRs("ins_srtcontrole_eind").Value) : null;
             var xcp_key_std = oRs("ins_srtcontroledl_xcp_key").Value || -1;
             oRs.Close();

             // Als de nieuwe waarden gelijk is aan de standaard waarden dan deze niet opslaan.
             var datumdiffer = vervaldatum != null && (vervaldatum? vervaldatum.getTime() : null) != (vervaldatum_std? vervaldatum_std.getTime() : null)
             var paramsdiffer = ((eenheid != -1 && (eenheid != eenheid_std || (periode != null && periode != periode_std) || (bits != null && bits != bits_std))) ||
                                 (kp_key != -1 && kp_key != kp_key_std) ||
                                 (aantal != null && aantal != aantal_std) ||
                                 (aanteh != "" && aanteh != aanteh_std) ||
                                 (kosten1 != null && kosten1 != kosten1_std) ||
                                 (kosten2 != null && kosten2 != kosten2_std) ||
                                 (kosten3 != null && kosten3 != kosten3_std) ||
                                 (uren != null && uren != uren_std) ||
                                 (materiaal != null && materiaal != materiaal_std) ||
                                 (perc != null && perc != perc_std) ||
                                 (groep != "" && groep != groep_std) ||
                                 (opmerk != "" && opmerk != opmerk_std) ||
                                 datumdiffer || startdatum != null);
             var deactivate = periode_std == 0 && (periode == null || periode == 0); // Beide periodes zijn 0. Controle wordt inactief. Uitzonderings regel kan weg in ins_srtcontroledl_xcp.
                                                                                     // Bij prijswijzigingen zie de taken met periode 0 niet in het mjob overzicht. Dan kun de kosten dus ook niet aanpassen.

             if (isScenario || (paramsdiffer && !deactivate))
             { // parameters wijken af van de standaard of er is een startdatum ingevuld.
               var result = { success: true, srtcontroledl_xcp_key: (commit? xcp_key_std : xcp_key) };

               // De velden opslaan (scenario key blijft hetzelfde dus hoeft niet opgeslagen te worden).
               var fields =  [ { dbs: "ins_deel_key",                   typ: "key",      val: ins_key },
                               { dbs: "ins_srtcontrole_key",            typ: "key",      val: srtcontrole_key },
                               { dbs: "ins_srtcontroledl_xcp_eenheid",  typ: "number",   val: (eenheid == -1 || eenheid == eenheid_std || eenheid < 0? null : eenheid),
                                                                                       track: (ins_key > 0? L("lcl_ins_controle_eenheid")  + " " + L("lcl_ins_controle").toLowerCase() : null) }, // Waarde gelijk aan standaard niet opslaan.
                               { dbs: "ins_srtcontroledl_xcp_periode",  typ: "float",    val: (periode == null || periode == periode_std? null : periode),
                                                                                       track: (ins_key > 0? L("lcl_ins_controle_period") : null) }, // Waarde gelijk aan standaard niet opslaan.
                               { dbs: "prs_kostenplaats_key",           typ: "key",      val: (kp_key == -1 || kp_key == kp_key_std? null : kp_key),
                                                                                       track: (ins_key > 0? L("lcl_ins_controle_eenheid")  + " " + L("lcl_ins_controle").toLowerCase() : null),
                                                                                       foreign: "prs_kostenplaats" }, // Waarde gelijk aan standaard niet opslaan.
                               { dbs: "ins_srtcontroledl_xcp_bits",     typ: "number",   val: (bits == null || bits == bits_std? null : bits),
                                                                                       track: (ins_key > 0? L("ins_srtcontrole_bits") : null) }, // Waarde gelijk aan standaard niet opslaan.
                               { dbs: "ins_srtcontroledl_xcp_uren",     typ: "float",    val: (uren == null || uren == uren_std? null : uren),
                                                                                       track: (ins_key > 0? L("ins_srtcontrole_uren") : null) },
                               { dbs: "ins_srtcontroledl_xcp_perc",     typ: "float",    val: (perc == null || perc == perc_std? null : perc),
                                                                                       track: (ins_key > 0? L("ins_srtcontrole_percentage") : null) },
                               { dbs: "ins_srtcontroledl_xcp_groep",    typ: "varchar",  val: (groep == "" || groep == groep_std? null : groep),
                                                                                       track: (ins_key > 0? L("lcl_ins_controle_groep") : null) },
                               { dbs: "ins_srtcontroledl_xcp_opmerk",   typ: "varchar",  val: (opmerk == "" || opmerk == opmerk_std? null : opmerk),
                                                                                       track: (ins_key > 0? L("ins_srtcontrole_opmerking") : null) },
                               { dbs: "ins_srtcontroledl_xcp_startdat", typ: "datetime", val: startdatum,
                                                                                       track: (ins_key > 0? L("lcl_ins_startdatum") : null) },
                               { dbs: "ins_srtcontroledl_xcp_eind",     typ: "datetime", val: (datumdiffer? vervaldatum : null),
                                                                                       track: (ins_key > 0? L("lcl_ins_vervaldatum") : null) },
                               { dbs: "ins_srtcontroledl_xcp_aantal",   typ: "float",    val: (aantal == null || aantal == aantal_std? null : aantal),
                                                                                       track: (ins_key > 0? L("lcl_amount") : null) },
                               { dbs: "ins_srtcontroledl_xcp_aanteh",   typ: "varchar",  val: (aanteh == "" || aanteh == aanteh_std? null : aanteh),
                                                                                       track: (ins_key > 0? L("ins_srtcontrole_eenheid") + " " + L("lcl_amount").toLowerCase() : null) }
                             ];

               var ins_xcp_active_cost = S("ins_xcp_active_cost");
               if (ins_xcp_active_cost & 1)
                 fields.push({ dbs: "ins_srtcontroledl_xcp_kosten",  typ: "float",    val: (kosten1 == null || kosten1 == kosten1_std? null : kosten1),
                                                                                      track: (ins_key > 0? L("ins_srtcontrole_kosten") + " (" + (S("currency_pref")).replace(/^\s+|\s+$/gm,'') + ")" : null) });
               if (ins_xcp_active_cost & 2)
                 fields.push({ dbs: "ins_srtcontroledl_xcp_kosten2", typ: "float",    val: (kosten2 == null || kosten2 == kosten2_std? null : kosten2),
                                                                                      track: (ins_key > 0? L("ins_srtcontrole_kosten2") + " (" + S("currency_pref").replace(/^\s+|\s+$/gm,'') + ")" : null) });
               if (ins_xcp_active_cost & 4)
                 fields.push({ dbs: "ins_srtcontroledl_xcp_kosten3", typ: "float",    val: (kosten3 == null || kosten3 == kosten3_std? null : kosten3),
                                                                                      track: (ins_key > 0? L("ins_srtcontrole_kosten3") + " (" + S("currency_pref").replace(/^\s+|\s+$/gm,'') + ")" : null) });
               if (ins_xcp_active_cost & 8)
                 fields.push({ dbs: "ins_srtcontroledl_xcp_materia", typ: "float",    val: (materiaal == null || materiaal == materiaal_std? null : materiaal),
                                                                                      track: (ins_key > 0? L("ins_srtcontrole_materiaal") + " (" + S("currency_pref").replace(/^\s+|\s+$/gm,'') + ")" : null) });
               if (!isScenario && (commit? xcp_key_std : xcp_key) < 0) // Nieuwe inspectie.
               {
                 fields.push({ dbs: "ins_srtcontroledl_xcp_key",       typ: "key",      seq: "ins_s_srtcontroledl_xcp_key" });
                 var insIns = buildInsert("ins_srtcontroledl_xcp", fields);
                 result.srtcontroledl_xcp_key = insIns.sequences["ins_srtcontroledl_xcp_key"];
                 var err = Oracle.Execute(insIns.sql, true);

                 ins.trackdeelupdate(ins_key,
                                     L("lcl_ins_controle_obj_upd").format(ctrdisc_oms, srtcontrole_oms)
                                       + (!isScenario && scen_key > 0? "\n" + L("lcl_mjb_adjustby_scen").format(params.scen_name) : "")
                                       + "\n" + L("lcl_ins_control_add_exception"),
                                     true); // Geen notificatie.
               }
               else
               {
                 var insUpd = buildTrackingUpdate("ins_srtcontroledl_xcp", " ins_srtcontroledl_xcp_key = " + (commit? xcp_key_std : xcp_key), fields);
                 var err = Oracle.Execute(insUpd.sql, true);

                 if (!isScenario && insUpd && insUpd.trackarray.length)
                   ins.trackdeelupdate(ins_key, L("lcl_ins_controle_obj_upd").format(ctrdisc_oms, srtcontrole_oms)
                                         + (!isScenario && scen_key > 0? "\n" + L("lcl_mjb_adjustby_scen").format(params.scen_name) : "")
                                         + "\n" + insUpd.trackarray.join("\n"),
                                       true); // Geen notificatie.
               }
             }
             else
             {
               // Deactiveren of alle parameter waarden zijn identiek aan de standaard waarden en er is geen groep ingevuld.
               if (xcp_key < 0) // Nieuwe inspectie.
               { // Geen nieuw record aanmaken.
                 var result = { success: true, srtcontroledl_xcp_key: (commit? xcp_key_std : xcp_key), toaster: L("lcl_ins_controle_identical_values") };
               }
               else
               { // Dan kan het record verwijderd worden.
                 var result = { success: true, srtcontroledl_xcp_key: (commit? xcp_key_std : xcp_key), toaster: (deactivate? L("lcl_ins_controle_deactivated") : L("lcl_ins_controle_identical_values")) };

                 // Record verwijderen.
                 var sql = "DELETE FROM ins_srtcontroledl_xcp"
                         + " WHERE ins_deel_key = " + ins_key
                         + "   AND ins_srtcontrole_key = " + srtcontrole_key
                         + "   AND ins_scenario_key = 1";
                 var err = Oracle.Execute(sql, true);

                 ins.trackdeelupdate(ins_key,
                                     L("lcl_ins_controle_obj_upd").format(ctrdisc_oms, srtcontrole_oms) + "\n" + L("lcl_ins_control_del_exception"),
                                     true); // Geen notificatie.
               }
             }

             if (commit)
               // Alleen bij het doorvoeren van een scenario het xcp record (ins_srtcontroledl_xcp_key) verwijderen.
               Oracle.Execute("DELETE FROM ins_srtcontroledl_xcp WHERE ins_srtcontroledl_xcp_key = " + xcp_key);

             if (err && err.friendlyMsg)
             {
               result.warning = err.friendlyMsg;
               result.success = false;
             }

             return result;
           },

       ins_deel_flex_params:
           function (p_inlijst, params)
           { // Fast check to see if we have any listable flex at all, to prevent superfluous column
             var inspect = params.inspect;
             if (inspect) {
               var ins_deelsrtcontrole = params.ins_deelsrtcontrole;
             } else {
               var ins_deel = (params.ins_deel ? params.ins_deel : "dl"); // referentie naar ins_deel_key
             }
             var ins_key = params.ins_key;

             var sql = "SELECT COALESCE (" + lcl.xsql("k.ins_kenmerk_omschrijving", "k.ins_kenmerk_key")
                     + "              ,  " + lcl.xsql("sk.ins_srtkenmerk_omschrijving", "sk.ins_srtkenmerk_key") + ") kenmerk_omschrijving"
                     + "     , sk.ins_srtkenmerk_kenmerktype"
                     + "  FROM ins_srtkenmerk sk"
                     + "     , ins_kenmerk k"
                     + (inspect && ins_key
                       ? "   , ctr_discipline cd"
                         + " , ins_srtcontrole c"
                       : "")
                     + " WHERE sk.ins_srtkenmerk_key = k.ins_srtkenmerk_key"
                     + "   AND BITAND (ins_kenmerk_inlijst, " + (p_inlijst? p_inlijst : 1) + ") = " + (p_inlijst? p_inlijst : 1) // In overzicht tonen {1=Objectenbeheer overzicht, 2=MJOB Planningsconsole}.
                     + "   AND k.ins_kenmerk_verwijder IS NULL"
                     + "   AND sk.ins_srtkenmerk_verwijder IS NULL"
                     + (inspect && ins_key
                       ? "   AND ((k.ins_srtinstallatie_key = c.ins_srtcontrole_key"
                         + "   AND k.ins_kenmerk_niveau = 'C')"
                         + "   OR (k.ins_srtinstallatie_key = cd.ins_discipline_key"
                         + "   AND k.ins_kenmerk_niveau = 'E')"
                         + "   OR (k.ins_srtinstallatie_key IS NULL"
                         + "   AND k.ins_kenmerk_niveau = 'T'))"
                         + " AND cd.ins_discipline_verwijder IS NULL"
                         + " AND EXISTS (SELECT xcp.ins_srtcontrole_key"
                         + "               FROM ins_v_defined_inspect_xcp xcp"
                         + "              WHERE xcp.ins_deel_key = " + ins_key
                         + "                AND xcp.ins_srtcontrole_key = c.ins_srtcontrole_key"
                         + "                AND xcp.ins_srtcontrole_periode > 0"
                         + "                AND xcp.ctr_discipline_key IN"
                         + "                        (SELECT w.ins_discipline_key"
                         + "                           FROM fac_v_webgebruiker w"
                         + "                              , fac_functie f"
                         + "                          WHERE w.fac_functie_key = f.fac_functie_key"
                         + "                            AND f.fac_functie_code = 'WEB_CTRUSE'"
                         + "                            AND w.fac_gebruiker_prs_level_write < 9"
                         + "                            AND w.fac_gebruiker_alg_level_write < 9"
                         + "                            AND w.prs_perslid_key = " + user_key + ")"
                         + "                AND xcp.ins_scenario_key = 1)"
                         + " AND c.ctr_discipline_key = cd.ins_discipline_key"
                       : "")
                     + (inspect
                       ? "   AND k.ins_kenmerk_niveau IN ('T', 'E', 'C')" // T=Alle taken, C=Periodiek taken, E=Taakcategorie.
                       : "   AND k.ins_kenmerk_niveau IN ('D', 'G', 'S')"); // D=Discipline, G=Objectgroep, S=Objectsoort.
             var oRs = Oracle.Execute(sql);
             var v_flexParams = { anyflex: !oRs.eof};
             if (v_flexParams.anyflex)
             {
               var multiflex = (("multiflex" in params) ? params.multiflex : false);
               v_flexParams.bijlageflex = (oRs("ins_srtkenmerk_kenmerktype").Value == "M");
               v_flexParams.flexlabel = oRs("kenmerk_omschrijving").Value;
               oRs.MoveNext();
               if (!oRs.eof)
               {
                 multiflex = (("multiflex" in params) ? multiflex : true); // Alleen wijzigen als params.multiflex niet is meegegeven.
                 v_flexParams.flexlabel = (inspect? L("lcl_flexlist_ctr") : L("lcl_flexlist_ins"));
                 while (!oRs.eof)
                 {
                   if (oRs("ins_srtkenmerk_kenmerktype").Value == "M")
                     v_flexParams.bijlageflex = true;
                   oRs.MoveNext();
                 }
               }
             }
             oRs.Close();

             var ikmd = "(SELECT ins_kenmerkdeel_waarde        waarde"
                      + "      , ins_kenmerk_key               kenmerk_key"
                      + "      , ins_deel_key                  outer_key"
                      + "      , ins_kenmerkdeel_verwijder     verwijder"
                      + "   FROM ins_kenmerkdeel";
             if (inspect) {
                 ikmd += " UNION ALL"
                       + " SELECT ins_kmdeelsrtcontr_waarde    waarde"
                       + "      , ins_kenmerk_key              kenmerk_key"
                       + "      , ins_deelsrtcontrole_key      outer_key"
                       + "      , ins_kmdeelsrtcontr_verwijder verwijder"
                       + "   FROM ins_kmdeelsrtcontr";
             }
             ikmd += ")";

             v_flexParams.sql = (v_flexParams.anyflex
                                ? ", (SELECT LISTAGG(" + ( multiflex
                                                         ? "COALESCE (" + lcl.xsql("ikm.ins_kenmerk_omschrijving", "ikm.ins_kenmerk_key")
                                                         + "         ," + lcl.xsql("iskm.ins_srtkenmerk_omschrijving", "iskm.ins_srtkenmerk_key")
                                                         + "         ) || ':' || CHR(160) || "
                                                         : ""
                                                         )
                                                       + " CASE WHEN iskm.ins_srtkenmerk_kenmerktype IN ('R', 'r', 'S')"
                                                       + "      THEN flx.getdomeinwaarde (iskm.fac_kenmerkdomein_key, ikmd.waarde)"
                                                       + "      WHEN (   iskm.ins_srtkenmerk_kenmerktype = 'N'"
                                                       + "           AND iskm.ins_srtkenmerk_lengte = 1"
                                                       + "           AND iskm.ins_srtkenmerk_nmin = 0"
                                                       + "           AND iskm.ins_srtkenmerk_nmax = 1"
                                                       + "           AND (iskm.ins_srtkenmerk_dec = 0 OR iskm.ins_srtkenmerk_dec IS NULL)"
                                                       + "           )"
                                                       + "      THEN DECODE (ikmd.waarde, "
                                                       + "                   0, " + safe.qL("lcl_check_0") + ", "
                                                       + "                   1, " + safe.qL("lcl_check_1") + ", "
                                                       + "                   ikmd.waarde)"
                                                       + "      ELSE ikmd.waarde"
                                                       + "  END"
                                  + "               , CHR(13)"
                                  + "               )"
                                  + "        WITHIN GROUP (ORDER BY ins_kenmerk_volgnummer)"
                                  + "   FROM ins_srtkenmerk iskm"
                                  + "      , ins_kenmerk ikm"
                                  + "      , " + ikmd + " ikmd"
                                  + "  WHERE ikmd.kenmerk_key = ikm.ins_kenmerk_key"
                                  + "    AND ikmd.outer_key = " + ( inspect
                                                                  ? ins_deelsrtcontrole + ".ins_deelsrtcontrole_key"
                                                                  : ins_deel + ".ins_deel_key"
                                                                  )
                                  + "    AND iskm.ins_srtkenmerk_key = ikm.ins_srtkenmerk_key"
                                  + "    AND BITAND(ikm.ins_kenmerk_inlijst, " + (p_inlijst? p_inlijst : 1) + ") = " + (p_inlijst? p_inlijst : 1) // In overzicht tonen {1=Objectenbeheer overzicht, 2=MJOB Planningsconsole}.
                                  + "    AND iskm.ins_srtkenmerk_verwijder IS NULL"
                                  + "    AND ikm.ins_kenmerk_verwijder IS NULL"
                                  + "    AND ikmd.verwijder IS NULL"
                                  + (inspect
                                    ? "  AND ikm.ins_kenmerk_niveau IN ('T', 'E', 'C')" // T=Alle taken, C=Periodiek taken, E=Taakcategorie.
                                    : "  AND ikm.ins_kenmerk_niveau IN ('D', 'G', 'S')" // D=Discipline, G=Objectgroep, S=Objectsoort.
                                    )
                                  + "    AND (  ikm.ins_kenmerk_niveau <> 'G'"
                                  + "        OR ikm.ins_srtinstallatie_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + "))"
                                  + ") insflex"
                                : "");
             return v_flexParams;
           },

       ins_deel_flex_bijlagen:
           function (p_key, p_inlijst, inspect)
           {
             var bijlagen_aantal = 0;
             var bijlagen_oms = "";
             var bijlagen_lijst = [];

             var sql_k = "SELECT k.ins_kenmerk_key"
                       + "     , COALESCE (" + lcl.xsql("k.ins_kenmerk_omschrijving", "k.ins_kenmerk_key")
                       + "     ,           " + lcl.xsql("sk.ins_srtkenmerk_omschrijving", "iskm.ins_srtkenmerk_key") + ") omschrijving"
                       + "  FROM ins_kenmerk k"
                       + "     , ins_srtkenmerk sk"
                       + (inspect
                         ? "   , ins_deelsrtcontrole idsc"
                           + " , ins_srtcontrole i"
                           + " , ctr_discipline cd"
                         : "   , ins_deel d"
                           + " , ins_srtdeel s"
                           + " , ins_srtgroep g")
                       + " WHERE k.ins_srtkenmerk_key = sk.ins_srtkenmerk_key"
                       + "   AND BITAND(k.ins_kenmerk_inlijst, " + (p_inlijst? p_inlijst : 1) + ") = " + (p_inlijst? p_inlijst : 1) // In overzicht tonen {1=Objectenbeheer overzicht, 2=MJOB Planningsconsole}.
                       + "   AND k.ins_kenmerk_verwijder IS NULL"
                       + "   AND sk.ins_srtkenmerk_verwijder IS NULL"
                       + "   AND sk.ins_srtkenmerk_kenmerktype = 'M'"
                       + (inspect
                         ? " AND k.ins_kenmerk_niveau IN ('C', 'E', 'T')" // C=Periodiek taken, E=Taakcategorie, T=Alle taken.
                           + " AND idsc.ins_srtcontrole_key = i.ins_srtcontrole_key"
                           + " AND i.ctr_discipline_key = cd.ins_discipline_key"
                           + " AND cd.ins_discipline_verwijder IS NULL"
                           + " AND idsc.ins_deelsrtcontrole_key = " + p_key // p_key is een ins_deelsrtcontrole_key.
                           + " AND ((k.ins_srtinstallatie_key = i.ins_srtcontrole_key AND k.ins_kenmerk_niveau = 'C')"
                           + "   OR (k.ins_srtinstallatie_key = cd.ins_discipline_key AND k.ins_kenmerk_niveau = 'E')"
                           + "   OR (k.ins_srtinstallatie_key IS NULL AND k.ins_kenmerk_niveau = 'T'))"
                         : " AND k.ins_kenmerk_niveau IN ('S', 'G', 'D')" // S=Objectsoort, G=Objectgroep, D=Discipline.
                           + " AND d.ins_srtdeel_key = s.ins_srtdeel_key"
                           + " AND d.ins_discipline_key = g.ins_discipline_key"
                           + " AND g.ins_srtgroep_key = s.ins_srtgroep_key"
                           + " AND d.ins_deel_key = " + p_key             // p_key is een ins_deel_key.
                           + " AND ((k.ins_srtinstallatie_key = s.ins_srtdeel_key AND k.ins_kenmerk_niveau = 'S')"
                           + "   OR (k.ins_srtinstallatie_key = s.ins_srtgroep_key AND k.ins_kenmerk_niveau = 'G')"
                           + "   OR (k.ins_srtinstallatie_key = g.ins_discipline_key AND k.ins_kenmerk_niveau = 'D'))")
                       + "   AND k.ins_srtinstallatie_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + ")";
             var oRs_k = Oracle.Execute(sql_k);
             while (!oRs_k.eof)
             {
               var kenmerk_key = oRs_k("ins_kenmerk_key").Value;
               var bijlagen_oms = oRs_k("omschrijving").Value;
               var bestanden = flexProps("INS", p_key, kenmerk_key, "A", {getFiles: true});
               var km_aantal = bestanden.files.length;
               for (var i=0; i<km_aantal; i++)
               {
                 bijlagen_lijst.push(bestanden.files[i].name);
               }
               bijlagen_aantal += km_aantal;

               oRs_k.MoveNext();
             }
             oRs_k.Close();

             return ( bijlagen_aantal > 0
                    ?  "<span title='" +  safe.htmlattr(bijlagen_lijst.join("\n"))  + "'>"
                       + safe.html(bijlagen_oms) + ": " + bijlagen_aantal
                       + "</span>"
                    : ""
                    );
            }
}
%>