<% /*
     $Revision$
     $Id$
*/
%>
<!-- #include file="../PRS/prs.inc" -->
<!-- #include file="../Shared/discx3d.inc" -->
<!-- #include file="../Shared/getkenmerksql.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 véél 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);
           },

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

       getBindingItemString:
           function(bind, bind_key, parent_key)
           {
             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 cp.prs_contactpersoon_naam"
                         + " 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_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.prs_werkplek_key = " + bind_key;
                     break;
                 }

                 case 'T':
                 {
                     sql = "SELECT pa.alg_plaatsaanduiding || DECODE(t.alg_terreinsector_omschrijving,NULL,'',' (' || t.alg_terreinsector_omschrijving || ')')"
                         + " FROM alg_terreinsector t"
                         + ", ins_v_alg_overzicht pa"
                         + " WHERE t.alg_terreinsector_key = pa.alg_onroerendgoed_keys"
                         + " 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;
                 }
             }
             oRs = Oracle.Execute(sql);
             if (!oRs.eof)
                 binding_item = oRs(0).Value;
             return binding_item;
           },

       getGGD:
           function(obj_keys)
           {
             if (obj_keys.length > 0)
             {
               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"
                       + "     , g.alg_gebouw_code || ' ' || g.alg_gebouw_naam" + " geb_oms"
                       + "     , t.alg_terreinsector_code || ' ' || t.alg_terreinsector_naam" + " ter_oms"
                       + "     , v.alg_verdieping_omschrijving ver_oms"
                       + "     , g.alg_gebouw_code || '-' || v.alg_verdieping_code || '-' || r.alg_ruimte_nr rui_oms"
                       + "  FROM ins_v_deel_gegevens_keys 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++;
               oRs.MoveNext();
               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 5: { statustekst = L("lcl_ins_controle_act_req"); break; }
                 case 6: { statustekst = L("lcl_ins_controle_afgerond"); break; }
             }
             if (Session("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"
                                 + "  FROM ins_kenmerkdeel v"
                                 + " WHERE v.ins_kenmerkdeel_verwijder IS NULL"
                                 + "   AND v.ins_deel_key = " + ins_key;

             allKenmerkenSQL     = "SELECT " + lcl.xsql('isk.ins_srtkenmerk_omschrijving', 'isk.ins_srtkenmerk_key') + " kenmerk_omschrijving"
                                 + ",      isk.ins_srtkenmerk_key srtkenmerk_key"
                                 + ",      fac_kenmerkdomein_key"
                                 + "  FROM ins_kenmerk ik, "
                                 + "       ins_srtkenmerk isk"
                                 + " WHERE ik.ins_srtkenmerk_key = isk.ins_srtkenmerk_key"
                                 + "   AND ik.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",
                                                 currentKenmerkenSQL: currentKenmerkenSQL,
                                                 allKenmerkenSQL: allKenmerkenSQL,
                                                 requestQF: Request.Form,
                                                 isNew: params.isnew,
                                                 flexPath: "INS/I",
                                                 multiMode: params.multimode,
                                                 tracking: true,
                                                 module: "INS"
                                               });
             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 het éé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_deel 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;
        },

       func_enabled_deel: // Wat mag ik zoal op dit specifieke object?
                          // autodetect sleutels
           function (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"
                        + "  FROM ins_deel 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") && (beheerder_key == user_key);

               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 || objectbeheerder; // Wijzigen
                 iresult.canChangeAlg = iresult.canChange; // 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);
                 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.canChange = iresult.canChange;
                 iresult.canChangeOwn = iresult.canChange || ((iresult.readuse || iresult.readman) && objectbeheerder);

                 if (params && params.srtcont_key > 0)
                 {
                   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)";
                   var oRs = Oracle.Execute(sql);
                   var hasInspect = !oRs.eof;
                   oRs.Close();

                   var sql = "SELECT insp.ins_deelsrtcontrole_key"
                           + "     , insp.ins_deelsrtcontrole_status"
                           + "     , insp.vervaldatum"
                           + "     , insp.isc_mode"
                           + "     , insp.ctr_discipline_key"
                           + "     , options"
                           // Moment inspectie pas kunnen opslaan op of na geplande inspectiedatum.
                           // 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"
                           + "       WHEN insp.isc_mode = 1"
                           + "       THEN  1"
                           + "       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 = 2 OR"
                           + "            insp.ins_deelsrtcontrole_status = 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 invoerAfterNext"
                           + "  FROM (SELECT idsc.ins_deelsrtcontrole_key"
                           + "             , idsc.ins_deelsrtcontrole_datum"
                           + "             , idsc.ins_deelsrtcontrole_status"
                           + "             , xcp.ins_srtcontroledl_xcp_eind vervaldatum"
                           + "             , isc.ins_srtcontrole_mode isc_mode"
                           + "             , isc.ctr_discipline_key"
                           + "             , isc.ins_srtcontrole_options options"
                           + "             , COALESCE (xcp.ins_srtcontroledl_xcp_eenheid, isc.ins_srtcontrole_eenheid) eenheid"
                           + "             , idsc.ins_deelsrtcontrole_plandatum plandatum"
                           + "             , 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)"
                           + "               THEN ins_deelsrtcontrole_datum_org"
                           + "               ELSE fac.nextcyclusdate(CASE"
                           + "                                       WHEN isc.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"
                           + "                                     , isc.ins_srtcontrole_mode"
                           + "                                     , COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, isc.ins_srtcontrole_eenheid)"
                           + "                                     , COALESCE(xcp.ins_srtcontroledl_xcp_periode, isc.ins_srtcontrole_periode)"
                           + "                                     , COALESCE(xcp.ins_srtcontroledl_xcp_bits, isc.ins_srtcontrole_bits)"
                           + "                                     , 1)"
                           + "               END inspectie_next"
                           + "          FROM ins_srtcontrole isc"
                           + "             , ins_deelsrtcontrole idsc"
                           + "             , ins_srtcontroledl_xcp xcp"
                           + "         WHERE isc.ins_srtcontrole_key = idsc.ins_srtcontrole_key(+)" // Er kan nog voor de eerste keer geinspecteerd moeten worden.
                           + "           AND isc.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
                           + "           AND xcp.ins_deel_key(+) = " + pins_deel_key
                           + "           AND idsc.ins_deel_key(+) = " + pins_deel_key
                           + "           AND isc.ins_srtcontrole_key = " + params.srtcont_key
                           + (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 + "))")
                           + "       ) 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 (stutus is 6) moet er een nieuwe inspectie gestart worden.
                   var ins_deelsrtcontrole_status = oRs("ins_deelsrtcontrole_status").Value != null? oRs("ins_deelsrtcontrole_status").Value : -1;
                   var vervaldatum = oRs("vervaldatum").Value != null? new Date(oRs("vervaldatum").Value) : null;
                   var ctr_discipline_key = oRs("ctr_discipline_key").Value;
                   var isc_options =  oRs("options").Value;
                   var vervallen = vervaldatum != null && vervaldatum < new Date();
                   var invoerAfterNext = oRs("invoerAfterNext").Value == 1;
                   oRs.Close();

                   iresult.invoerAfterNext = invoerAfterNext;

                   // 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)

                   iresult.hasCTRRead = ctrresult.canRead("WEB_CTRUSE");  // Heb ik lees rechten om periodieke taken te zien?
                   iresult.hasCTRWrite = ctrresult.canWrite("WEB_CTRUSE") || objectbeheerder;// Heb ik schrijf rechten om periodieke taken uit te voeren?

                   iresult.canShowXcp = iresult.hasCTRRead && iresult.canRead("WEB_INSMAN"); // Exceptions (xcp) waarden inspecties/taken bekijken (waarden in ins_srtcontroledl_xcp tabel).
                   iresult.canChangeXcp = iresult.hasCTRWrite && iresult.canWrite("WEB_INSMAN"); // Exceptions (xcp) waarden inspecties/taken wijzigen (waarden in ins_srtcontroledl_xcp tabel).

                   // 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 = iresult.writemsu && ins_deelsrtcontrole_status == 6;
                   iresult.canInspEdit = ((iresult.readuse && ins_deelsrtcontrole_status != -1 && ins_deelsrtcontrole_status != 6) ||
                                          iresult.canMsuEdit) &&
                                         !vervallen && actief && iresult.hasCTRWrite;
                   iresult.canInspShow = iresult.readuse && !vervallen && (ins_deelsrtcontrole_status >= 0) && iresult.hasCTRRead;
                   // Bij eerste inspectie of verwerkte inspectie kan er gepland worden.
                   iresult.canInspPlan = iresult.readuse && !vervallen &&
                                         (ins_deelsrtcontrole_status == -1 || ins_deelsrtcontrole_status == 6) &&
                                         actief && iresult.hasCTRWrite &&
                                         ((isc_options & 1) == 1);
                   // Bij eerste inspectie, geplande inspectie of verwerkte inspectie kan er gestart worden.
                   iresult.canInspStart = iresult.readuse && invoerAfterNext && !vervallen &&
                                          (ins_deelsrtcontrole_status <= 0 || ins_deelsrtcontrole_status == 6) &&
                                          actief && iresult.hasCTRWrite &&
                                          ((isc_options & 2) == 2);
                   // Bij eerste inspectie, geplande inspectie, gestarte inspectie of verwerkte inspectie kan er gereedgemeld/afgerond worden.
                   iresult.canInspClose = iresult.readuse && invoerAfterNext &&
                                          ((!vervallen && (ins_deelsrtcontrole_status < 5 || ins_deelsrtcontrole_status == 6)) ||
                                           (ins_deelsrtcontrole_status == 0 || ins_deelsrtcontrole_status == 2)) &&
                                          actief && iresult.hasCTRWrite &&
                                          ((isc_options & 4) == 4);
                   // Afronden kan vanuit elke status. Alleen vanuit status Gereed gemeld/Afgemeld(5) kan het zonder gegevens in te vullen.
                   iresult.canInspFinish = iresult.readuse && invoerAfterNext &&
                                           //(ins_deelsrtcontrole_status == 5 ||
                                           // (ins_deelsrtcontrole_status < 5 && ((isc_options & 4) != 4))) &&
                                           actief && iresult.hasCTRWrite &&
                                           ((isc_options & 8) == 8);
                   // Alleen als de inspectie gereedgemeld is kan SNEL afgerond worden zonder gegevens in te vullen.
                   iresult.canInspFastFinish = iresult.readuse && invoerAfterNext &&
                                               (ins_deelsrtcontrole_status == 5) &&
                                               actief && iresult.hasCTRWrite &&
                                               ((isc_options & 8) == 8);
                 }
                 else
                 {
                   iresult.invoerAfterNext = true;

                   // Zijn er soort controles waar de user lees of schrijf rechten op heeft?
                   // Eerst lezen.
                   var bsql = "SELECT COUNT(*) aantal"
                            + "  FROM (SELECT di.ins_srtcontrole_key"
                            + "          FROM ins_v_defined_inspect di"
                            + "             , ins_srtcontroledl_xcp xcp"
                            + "         WHERE di.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
                            + "           AND di.ins_deel_key = xcp.ins_deel_key(+)"
                            + "           AND di.ins_deel_key = " + pins_deel_key
                            + "           AND di.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 + ")"
                            + "         GROUP BY di.ins_srtcontrole_key"
                            + "                , di.ins_deel_key)";
                   var boRs = Oracle.Execute(bsql);
                   var add = boRs("aantal").Value > 0;
                   iresult.hasAnyReadXcp = boRs("aantal").Value > 0 && iresult.canRead("WEB_INSMAN"); // Enige rechten om exceptions (xcp) waarden te lezen.
                   boRs.close();

                   // Nu schrijven.
                   var bsql = "SELECT COUNT(*) aantal"
                            + "  FROM (SELECT di.ins_srtcontrole_key"
                            + "          FROM ins_v_defined_inspect di"
                            + "             , ins_srtcontroledl_xcp xcp"
                            + "         WHERE di.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)"
                            + "           AND di.ins_deel_key = xcp.ins_deel_key(+)"
                            + "           AND di.ins_deel_key = " + pins_deel_key
                            + "           AND di.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 + ")"
                            + "         GROUP BY di.ins_srtcontrole_key"
                            + "                , di.ins_deel_key)";
                   var boRs = Oracle.Execute(bsql);
                   var add = boRs("aantal").Value > 0;
                   iresult.hasAnyWriteXcp = boRs("aantal").Value > 0 && iresult.canWrite("WEB_INSMAN"); // Enige rechten om exceptions (xcp) waarden te schrijven.
                   iresult.canDoAnyInspect = boRs("aantal").Value > 0 && iresult.canRead("WEB_INSMAN"); // Enige rechten om inspecties te doen.
                   boRs.close();
                }
               }
               ioRs.Close();

               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)
           {
               var iresult = {canDelete: false, canChange: false}; // Verwijderen en Wijzigen
               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 = prs.canWriteAfdeling(afd_key, "WEB_INSMAN");
                 var canWriteINSUSE = prs.canWriteAfdeling(afd_key, "WEB_INSUSE");
                 iresult.writeman = canWriteINSMAN;
                 iresult.writeuse = canWriteINSUSE;
                 iresult.canDelete = canWriteINSMAN; // Verwijderen
                 iresult.canChange = canWriteINSMAN || canWriteINSUSE; // Wijzigen
                 iresult.canChangeAlg = canWriteINSMAN; // Wijzigen algemene gegevens
                 iresult.canCopy = canWriteINSMAN; // Kopiëren
               }
               else if (ins_alg_ruimte_type == "P")
               {
                 iresult = user.func_enabled("INS",
                                             ins_discipline_key,
                                             null, // alg_key is nvt
                                             ins_alg_ruimte_key, // prs_key
                                             false, // pessimist
                                             true); // nog even optional
                 if (!iresult || !iresult.anyfound)
                    return null;
                 iresult.writeman = iresult.canWrite("WEB_INSMAN");
                 iresult.writeuse = iresult.canWrite("WEB_INSUSE");
                 iresult.canDelete = iresult.canWrite("WEB_INSMAN"); // Verwijderen
                 iresult.canChange = iresult.canWrite("WEB_INSMAN") || iresult.canWrite("WEB_INSUSE"); // Wijzigen
                 iresult.canChangeAlg = iresult.canWrite("WEB_INSMAN"); // Wijzigen algemene gegevens
                 iresult.canCopy = iresult.canWrite("WEB_INSMAN"); // Kopiëren
               }
               else
               {
                 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();
                 }
                 else if (alg_ruimte_type == "T")
                 {
                   var sql = "SELECT t.alg_locatie_key"
                           + " FROM alg_terreinsector t"
                           + " WHERE t.alg_terreinsector_key = " + alg_ruimte_key;
                   var oRs = Oracle.Execute(sql);
                   alg_ruimte_key = oRs("alg_locatie_key").Value;
                   oRs.Close();
                 }
                 // Voor alg_ruimte_type = "P" heeft alg_ruimte_key al de juiste waarde

                 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.canDelete = iresult.canWrite("WEB_INSMAN"); // Verwijderen.
                 iresult.canChange = iresult.canWrite("WEB_INSMAN") || iresult.canWrite("WEB_INSUSE"); // Wijzigen.
                 iresult.canChangeAlg = iresult.canWrite("WEB_INSMAN"); // 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;
           },

       getobjectinspect_sql:
           function (pautfunction, params)
           { // lever de objecten of inpectie sql op.
             var urole = params.urole;
             var fronto = (urole == "fo");
             var backo = (urole == "bo");
             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 = params.reg_key;
             var dist_key = params.dist_key;
             var loc_key = params.loc_key;
             var bld_key = params.bld_key;
             var terr_key = params.terr_key;               // FGII parameters
             var flr_key = params.flr_key;
             var room_key = params.room_key;
             var wpl_key = params.wpl_key;
             var deel = params.deel;
             var deel_opm = params.deel_opm;
             var disc_key = params.disc_key;
             var insgroup_key = params.insgroup_key;
             var objsrt_key = params.objsrt_key;
             var objsrt_oms = params.objsrt_oms;
             var groep = params.groep;
             var ctrdisc_key = params.ctrdisc_key;
             var dep_key = params.dep_key;
             var persoon_key = params.persoon_key;
             var beh_key = params.beh_key;
             var cpersoon_key = params.cpersoon_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 room_key_arr = params.room_key_arr;       // FGII parameters
             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 insSuccessY = params.insSuccessY;
             var insSuccessN = params.insSuccessN;
             var embedded = params.embedded;
             var tiny = params.tiny || parent_key || koppel_key;
             var srtcontrole = params.srtcontrole;
             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 sql_objincl = "";
             if (insObjIncl || parent_key > 0)
               sql_objincl = "";
             else
               sql_objincl += " AND i.ins_deel_parent_key IS NULL ";

             if (!expObjIncl && !deel)
               sql_objincl += " AND (i.ins_deel_vervaldatum IS NULL OR i.ins_deel_vervaldatum > TRUNC(SYSDATE)) ";

             if (!inacObjIncl && !deel)
               sql_objincl += " AND i.ins_deel_actief = 1 ";

             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 || dist_key || loc_key || bld_key || terr_key || flr_key || wpl_key || room_key || room_key_arr)
               {
                 hasPosition = true;
               }

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

             ///////////////////////////////////////////////////////////
             //
             // 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 = "";
             if (fronto)
             {
               sqlLentOutFrom = "CASE WHEN  i.ins_alg_ruimte_type_org = 'A'"
                              + "     THEN (SELECT " + S("prs_dep_string")
                              + "             FROM prs_v_afdeling d"
                              + "            WHERE d.prs_afdeling_key = i.ins_alg_ruimte_key_org)"
                              + "     WHEN i.ins_alg_ruimte_type_org = 'P'"
                              + "     THEN (SELECT " + S("prs_pers_string")
                              + "             FROM prs_perslid p"
                              + "            WHERE p.prs_perslid_key = i.ins_alg_ruimte_key_org)"
                              + "     WHEN i.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 = i.ins_alg_ruimte_key_org"
                              + "              AND o.alg_onroerendgoed_type = i.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 = "(SELECT MAX(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)";

                   // Eerstvolgende inspectie
                   var sqlNext = "SELECT ins_deel_key"
                               + (inspDone
                                 ? "   , inspectie_date"
                                 : "   , inspectie_next")
                               + "     , ins_srtcontroledl_xcp_startdat"
                               + "     , nonext"
                               + "     , inspectie_eenheid"
                               + "     , inspectie_eind"
                               + "     , ins_srtcontrole_omschrijving"
                               + "     , ins_srtcontrole_key"
                               + "     , options"
                               + "     , ins_deelsrtcontrole_status"
                               + "     , ins_deelsrtcontrole_plandatum"
                               + "     , ctr_controle_type"
                               + (!mobile
                                 ? "     , periode"
                                   + "     , groepoms"
                                   + "     , ins_deelsrtcontrole_key"
                                   + "     , ins_controlemode_success"
                                   + "     , ctr_disc_key"
                                   + "     , ctr_disc_oms"
                                 : "")
                               + "  FROM ("
                               + (inspDone
                                 ? "      SELECT 1 rn" // Afgehandelde inspecties.
                                   + "         , di.ins_deel_key"
                                   + "         , (SELECT MAX (idsc.ins_deelsrtcontrole_datum)"
                                   + "              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) inspectie_date"
                                   + "         , di.ins_srtcontroledl_xcp_startdat"
                                   + "         , NULL nonext"
                                   + "         , di.ins_srtcontrole_eenheid inspectie_eenheid"
                                   + "         , di.ins_srtcontrole_eind inspectie_eind"
                                   + "         , " + lcl.xsqla('di.ins_srtcontrole_omschrijving', 'di.ins_srtcontrole_key')
                                   + "         , di.ins_srtcontrole_options options"
                                   + "         , di.ins_srtcontrole_key"
                                   + "         , -1 ins_deelsrtcontrole_status"
                                   + "         , NULL ins_deelsrtcontrole_key"
                                   + "         , (SELECT idsc.ins_deelsrtcontrole_plandatum"
                                   + "              FROM ins_deelsrtcontrole idsc"
                                   + "             WHERE 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))"
                                   + "           ins_deelsrtcontrole_plandatum"
                                   // 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 = (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)))"
                                       + "           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"
                                     : "")
                                   + "      FROM ins_v_defined_inspect_xcp di"
                                   + "     WHERE EXISTS (" + lastinspect + ")"
                                   + (srtcontrole > -1
                                     ? "     AND di.ins_srtcontrole_key = " + srtcontrole
                                     : "")
                                   + (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)))" + (insSuccessY? " = 1" : " IS NULL"))
                                   + "       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.
                                     + "         , di.ins_deel_key"
                                     + "         , fac.nextcyclusdate(di.ins_deel_aanmaak"
                                       + "                          , di.ins_srtcontrole_mode"
                                       + "                          , di.ins_srtcontrole_eenheid"
                                       + "                          , di.ins_srtcontrole_periode"
                                       + "                          , di.ins_srtcontrole_bits"
                                       + "                          , 1) inspectie_next"
                                     + "         , di.ins_srtcontroledl_xcp_startdat"
                                     + "         , CASE WHEN " + lastinspect + " IS NULL THEN 1 ELSE 0 END nonext"
                                     + "         , di.ins_srtcontrole_eenheid inspectie_eenheid"
                                     + "         , di.ins_srtcontrole_eind inspectie_eind"
                                     + "         , " + lcl.xsqla('di.ins_srtcontrole_omschrijving', 'di.ins_srtcontrole_key')
                                     + "         , di.ins_srtcontrole_key"
                                     + "         , di.ins_srtcontrole_options options"
                                     + "         , -1 ins_deelsrtcontrole_status"
                                     + "         , NULL ins_deelsrtcontrole_key"
                                     + "         , NULL ins_deelsrtcontrole_plandatum"
                                     + "         , 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"
                                       : "")
                                     + "      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)"
                                     + (srtcontrole > -1
                                       ? "     AND di.ins_srtcontrole_key = " + srtcontrole
                                       : "")
                                     + "       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.
                                   + "         , di.ins_deel_key"
                                   + "         ,          CASE"
                                     + "                  WHEN " + lastinspect + " IS NULL" // Inspectie die voor het eerst is ingepland(0) of gestart(2) maar nog geen uitgevoerde/afgemelde(6) inspectie heeft.
                                   + "                   THEN fac.nextcyclusdate(di.ins_deel_aanmaak" // Dan registratiedatum + planning
                                     + "                                     , di.ins_srtcontrole_mode"
                                     + "                                     , di.ins_srtcontrole_eenheid"
                                     + "                                     , di.ins_srtcontrole_periode"
                                     + "                                     , di.ins_srtcontrole_bits"
                                     + "                           , 1) "
                                     + "                  WHEN idsc.ins_deelsrtcontrole_status IN (0, 2)"
                                     + "                  THEN ins_deelsrtcontrole_datum_org" // In status 0 en 2 wordt de volgende inspectie in ins_deelsrtcontrole_datum_org direct opgeslagen.
                                     + "                  ELSE"
                                     + "                    fac.nextcyclusdate(CASE"
                                     + "                                       WHEN di.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"
                                     + "                                     , di.ins_srtcontrole_mode"
                                     + "                                     , di.ins_srtcontrole_eenheid"
                                     + "                                     , di.ins_srtcontrole_periode"
                                     + "                                     , di.ins_srtcontrole_bits"
                                     + "                                     , 1)"
                                     + "                  END inspectie_next"
                                   + "         , ins_srtcontroledl_xcp_startdat"
                                   + "         , CASE WHEN " + lastinspect + " IS NULL THEN 1 ELSE 0 END nonext"
                                   + "         , di.ins_srtcontrole_eenheid inspectie_eenheid"
                                   + "         , di.ins_srtcontrole_eind inspectie_eind"
                                   + "         , " + lcl.xsqla('di.ins_srtcontrole_omschrijving', '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)"
                                   + "           THEN idsc.ins_deelsrtcontrole_plandatum"
                                   + "           ELSE NULL"
                                   + "           END ins_deelsrtcontrole_plandatum"
                                   + "         , 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"
                                     : "")
                                   + "      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"
                                   + (srtcontrole > -1
                                     ? "     AND di.ins_srtcontrole_key = " + srtcontrole
                                     : "")
                                   + "       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_next)")
                               + " 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 altijd tonen).
                               + (inspBusy || inspClosed || inspSoon
                               ? "   AND (inspectie_eind IS NULL OR inspectie_eind > SYSDATE OR ins_deelsrtcontrole_status = 0 OR ins_deelsrtcontrole_status = 2)"
                               : "");

                   sqlInspectie_select = (inspDone? "inspectie_date" : "inspectie_next")
                                       + "    , ispn.ins_srtcontroledl_xcp_startdat"
                                       + "    , ispn.ins_srtcontrole_omschrijving"
                                       + "    , ispn.ins_srtcontrole_key"
                                       + "    , ispn.options"
                                       + "    , ispn.ins_deelsrtcontrole_status"
                                       + "    , ispn.ins_deelsrtcontrole_plandatum"
                                       + "    , ispn.inspectie_eind"
                                       + "    , ispn.inspectie_eenheid"
                                       + "    , ispn.nonext"
                                       + "    , ispn.ctr_controle_type"
                                       + (!mobile
                                         ? "    , ispn.groepoms"
                                           + "    , ispn.ins_deelsrtcontrole_key"
                                           + "    , ispn.ins_controlemode_success"
                                           + "    , ispn.ctr_disc_key"
                                           + "    , ispn.ctr_disc_oms"
                                         : "");

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

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

             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 km.ins_kenmerk_volgnummer >= 900"
                                                + "GROUP BY sd.ins_srtdeel_key) k";
                 var  sqlKenmerkBewerkbaar_where = " AND i.ins_srtdeel_key = k.ins_srtdeel_key(+)";
             }
             else // Dan doen we er toch niets mee
             {
                 sqlKenmerkBewerkbaar_select = ", 0 bewerkbaar";
                 sqlKenmerkBewerkbaar_from = "DUAL";
                 sqlKenmerkBewerkbaar_where = "";
             }

             // 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"
                               + ", " + lcl.xsql('s.ins_srtdeel_omschrijving', 's.ins_srtdeel_key')+" soort"
                               + ", i.ins_deel_omschrijving"
                               + ", (SELECT ins_discipline_omschrijving"
                               + "              FROM ins_discipline idc"
                               + "             WHERE i.ins_discipline_key = idc.ins_discipline_key) ins_disc_oms"
                               + ", (SELECT ins_srtgroep_omschrijving"
                               + "              FROM ins_srtgroep idc"
                               + "             WHERE s.ins_srtgroep_key = idc.ins_srtgroep_key) ins_groep_oms"
                               + ", i.ins_deel_key"
                               + ", i.ins_alg_ruimte_type"
                               + ", " + sqlInspectie_select
                               + (!mobile
                                 ? ", s.ins_srtdeel_code"
                                   + ", i.ins_deel_opmerking"
                                   + ", s.ins_srtdeel_key"
                                   + ", s.ins_srtdeel_upper"
                                   + ", i.ins_deel_getekend"
                                   + ", i.ins_discipline_key"
                                   + ", -1 district"
                                   + ", i.ins_deel_x" // is coordinaat bekend?
                                   + ", i.ins_deel_dwgx" // is dwg coordinaat bekend?
                                   + ", ins_srtgroep_key"
                                   + ", ins_deel_upper"
                                   + ", s.ins_srtdeel_uitleenbaar"
                                   + ", i.ins_alg_ruimte_key_org"
                                   + ", i.ins_alg_ruimte_type_org"
                                   + ", " + sqlLentOutFrom + " uitgegeven_vanuit"
                                   + ", rd.res_deel_key"
                                   + ", rd.res_deel_opmerking"
                                   + ", i.ins_deel_vervaldatum"
                                   + ", i.ins_deel_actief"
                                 : "");

               sqlOwner_from = " FROM ins_deel i"
                             + ", ins_srtdeel s"
                             + sqlInspectie_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) rd";

               sqlOwner_where = " WHERE s.ins_srtdeel_key = i.ins_srtdeel_key"
                              + " AND i.ins_deel_verwijder IS NULL"
                              + " AND i.ins_deel_key =  rd.res_ins_deel_key(+)"
                              + " AND i.ins_deel_module = 'INS'"
                              + " AND s.ins_srtgroep_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + ")"
                              + sql_objincl
                              + sqlInspectie_where
                              + (fronto
                                ? " AND s.ins_srtdeel_uitleenbaar = 1"
                                : "")
                              + (koppel_key
                                ? " AND idk.ins_deelkoppeling_verwijder IS NULL"
                                  + " AND ((     i.ins_deel_key = idk.ins_deelkoppeling_naar_key"
                                  + "        AND idk.ins_deelkoppeling_van_key=" + koppel_key
                                  + "      )"
                                  + "   OR (     i.ins_deel_key = idk.ins_deelkoppeling_van_key"
                                  + "        AND idk.ins_deelkoppeling_naar_key=" + koppel_key + "))"
                                : "")
                              + ((insLentOut && !insAvail)
                                 ? " AND i.ins_alg_ruimte_key_org IS NOT NULL"
                                 : (!insLentOut && insAvail)
                                    ? " AND i.ins_alg_ruimte_key_org IS NULL"
                                    : "");

               if (loc_key|| bld_key)
               {
                   sqlOwner_from += ", (SELECT alg_ruimte_key"
                                  + "     FROM alg_v_allonroerendgoed"
                                  + "    WHERE " + (bld_key ? "alg_gebouw_key" : "alg_locatie_key")
                                         + " = " + (bld_key ? bld_key : loc_key)
                                  + "  ) a";
                   sqlOwner_where += " AND i.ins_alg_ruimte_key_org = a.alg_ruimte_key";
               }

               sqlOwnerA = sqlOwner_select
                         + (!mobile
                           ? sqlKenmerkBewerkbaar_select
                             + ", b.prs_bedrijf_key prs_bedrijf_key" // bedrijf key
                             + ", d.prs_afdeling_key1"
                             + ", CASE WHEN i.ins_alg_ruimte_type_org IS NOT NULL"
                             + "       THEN (SELECT " + S("prs_pers_string")
                             + "               FROM prs_perslid p"
                             + "              WHERE p.prs_perslid_key = i.ins_alg_ruimte_key)"
                             + "       ELSE (SELECT " + S("prs_dep_string") + " FROM prs_v_afdeling d WHERE prs_afdeling_key = i.ins_alg_ruimte_key)"
                             + "       END uitgeleend_aan"
                             + ", NULL alg_ruimte_key " // person key
                             + ", i.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 d"
                         + ", prs_bedrijf b"
                         + ", " + sqlKenmerkBewerkbaar_from
                         + (koppel_key? ", ins_deelkoppeling idk" : "")
                         + sqlOwner_where
                         + sqlKenmerkBewerkbaar_where
                         + " AND d.prs_bedrijf_key = b.prs_bedrijf_key";

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

               sqlOwnerA += " AND i.ins_alg_ruimte_key = d.prs_afdeling_key"
                          + " AND i.ins_alg_ruimte_type = 'A'"; // Object is NIET uitgeleend, anders was het type 'P'.



               sqlOwnerP = sqlOwner_select
                         + (!mobile
                           ? sqlKenmerkBewerkbaar_select
                             + ", b.prs_bedrijf_key prs_bedrijf_key " // bedrijf key
                             + ", d.prs_afdeling_key1"
                             + ", " + S("prs_pers_string") + " uitgeleend_aan"
                             + ", i.ins_alg_ruimte_key alg_ruimte_key " // person key
                             + ", 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 d"
                         + ", prs_bedrijf b"
                         + ", " + sqlKenmerkBewerkbaar_from
                         + (koppel_key? ", ins_deelkoppeling idk" : "")
                         + sqlOwner_where
                         + sqlKenmerkBewerkbaar_where
                         + " AND p.prs_afdeling_key = d.prs_afdeling_key"
                         + " AND d.prs_bedrijf_key = b.prs_bedrijf_key"
                         + " AND i.ins_alg_ruimte_key = p.prs_perslid_key";

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

               sqlOwnerP += " AND i.ins_alg_ruimte_type = 'P'"        // Object is wel of niet uitgeleend.
                          + (S("ins_auth_obj_lendout") == 1
                            ? " AND i.ins_alg_ruimte_key_org IS NULL" // Dit deel kijkt naar NIET uitgeleende objecten. sqlOwnerA_org naar uitgeleende objecten.
                            : "");

               sqlOwnerCP = sqlOwner_select
                          + (!mobile
                            ? sqlKenmerkBewerkbaar_select
                              + ", (SELECT c.prs_bedrijf_key FROM prs_contactpersoon c WHERE c.prs_contactpersoon_key = i.ins_alg_ruimte_key) prs_bedrijf_key" // bedrijf key
                              + ", 0 dummy1" // department key
                              + ", c.prs_contactpersoon_naam uitgeleend_aan"
                              + ", i.ins_alg_ruimte_key alg_ruimte_key" // person key
                              + ", NULL prs_afdeling_key" // department key
                              + (koppel_key? ", ins_deelkoppeling_omschrijving, ins_deelkoppeling_van_key, ins_deelkoppeling_naar_key" : "")
                            : "")
                          + sqlOwner_from
                          + ", prs_contactpersoon c"
                          + ", prs_bedrijf b"
                          + ", " + sqlKenmerkBewerkbaar_from
                          + (koppel_key? ", ins_deelkoppeling idk" : "")
                          + sqlOwner_where
                          + sqlKenmerkBewerkbaar_where
                          + " AND c.prs_bedrijf_key = b.prs_bedrijf_key"
                          + " AND i.ins_alg_ruimte_key = c.prs_contactpersoon_key";

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

               sqlOwnerCP += " AND i.ins_alg_ruimte_type = 'C'"; // Object is NIET uitgeleend, anders was het type 'P'.

             }

             if (!hasOwner)
             { // Owner filter would imply only owned objects
               sqlPosition = (terr_key
                               ? "SELECT t.alg_terreinsector_omschrijving"
                               : "SELECT o.alg_plaatsaanduiding"
                                 + " || DECODE(o.alg_plaatsomschrijving, '','' ,' (' || o.alg_plaatsomschrijving || ')')"
                             )
                             + " plaats"
                           + ", " + lcl.xsql('s.ins_srtdeel_omschrijving', 's.ins_srtdeel_key') + " soort"
                           + ", i.ins_deel_omschrijving"
                           + ", (SELECT ins_discipline_omschrijving"
                           + "              FROM ins_discipline idc"
                           + "             WHERE i.ins_discipline_key = idc.ins_discipline_key) ins_disc_oms"
                           + ", (SELECT ins_srtgroep_omschrijving"
                           + "              FROM ins_srtgroep idc"
                           + "             WHERE s.ins_srtgroep_key = idc.ins_srtgroep_key) ins_groep_oms"
                           + ", i.ins_deel_key"
                           + ", i.ins_alg_ruimte_type"
                           + ", " + sqlInspectie_select
                           + (!mobile
                             ? ", s.ins_srtdeel_code"
                               + ", i.ins_deel_opmerking"
                               + ", s.ins_srtdeel_key"
                               + ", s.ins_srtdeel_upper"
                               + ", i.ins_deel_getekend"
                               + ", i.ins_discipline_key"
                               + ", l.alg_district_key"
                               + ", i.ins_deel_x" // is coordinaat bekend?
                               + ", i.ins_deel_dwgx" // is dwg coordinaat bekend?
                               + ", ins_srtgroep_key" // filtering only
                               + ", ins_deel_upper" // filtering only
                               + ", s.ins_srtdeel_uitleenbaar"
                               + ", i.ins_alg_ruimte_key_org"
                               + ", i.ins_alg_ruimte_type_org"
                               + ", " + sqlLentOutFrom + " uitgegeven_vanuit"
                               + ", rd.res_deel_key"
                               + ", rd.res_deel_opmerking"
                               + ", i.ins_deel_vervaldatum"
                               + ", i.ins_deel_actief"
                               + sqlKenmerkBewerkbaar_select
                               + ", NULL prs_bedrijf_key"
                               + ", NULL prs_afdeling_key1"
                               + ", CASE WHEN i.ins_alg_ruimte_type_org IS NOT NULL"
                               + "       THEN (SELECT " + S("prs_pers_string")
                               + "               FROM prs_perslid p"
                               + "              WHERE p.prs_perslid_key = i.ins_alg_ruimte_key)"
                               + "       ELSE NULL"
                               + "       END uitgeleend_aan"
                               + ", i.ins_alg_ruimte_key alg_ruimte_key"
                               + ", 0 dummy1" // department key
                               + (koppel_key? ", ins_deelkoppeling_omschrijving, ins_deelkoppeling_van_key, ins_deelkoppeling_naar_key" : "")
                             : "")
                           + " FROM ins_deel i"
                           + (terr_key
                             ? ", alg_terreinsector t"
                             : ", ins_v_alg_overzicht o")
                           + ", ins_srtdeel s"
                           + sqlInspectie_from
                           + ", alg_locatie l"
                           + ", " + sqlKenmerkBewerkbaar_from
                           + (koppel_key? ", ins_deelkoppeling idk" : "")
                           + ", alg_district di" // I added this for alg_district_key (FSN#1082)
                           + ", (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) rd"
                           + " WHERE  i.ins_deel_verwijder IS NULL"
                           + " AND i.ins_deel_module = 'INS'"
                           + " AND i.ins_deel_key =  rd.res_ins_deel_key(+)"
                           + " AND s.ins_srtgroep_key NOT IN (" + S("sle_ins_srt_groep_key") + ", " + S("cil_ins_srt_groep_key") + ")"
                           + sql_objincl
                           + sqlInspectie_where
                           + sqlKenmerkBewerkbaar_where
                           + " AND l.alg_district_key = di.alg_district_key"
                           + " AND s.ins_srtdeel_key = i.ins_srtdeel_key"
                           + (fronto
                             ? " AND s.ins_srtdeel_uitleenbaar = 1"
                             : "")
                           + ((insLentOut && !insAvail)
                             ? " AND i.ins_alg_ruimte_key_org IS NOT NULL"
                             : (!insLentOut && insAvail)
                               ? " AND i.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)
                   //sqlPosition += " AND i.ins_alg_ruimte_key IN (" + room_key_arr.join(",") + ")";
                   sqlPosition += " AND ((i.ins_alg_ruimte_key IN (" + room_key_arr.join(",") + ") AND i.ins_alg_ruimte_type='R')"
                                + " OR (i.ins_alg_ruimte_key IN (SELECT prs_werkplek_key FROM prs_werkplek WHERE prs_alg_ruimte_key IN (" + room_key_arr.join(",") + ")) AND i.ins_alg_ruimte_type='W'))";
                 else if (room_key)
                   sqlPosition += " AND ((i.ins_alg_ruimte_key = " + room_key + " AND i.ins_alg_ruimte_type='R') "
                                + " OR (i.ins_alg_ruimte_key IN (SELECT prs_werkplek_key FROM prs_werkplek WHERE prs_alg_ruimte_key=" + room_key + ") AND i.ins_alg_ruimte_type='W'))";
                 else if (flr_key)
                   sqlPosition += " AND o.alg_verdieping_key = " + flr_key;
                 else if (terr_key)
                   sqlPosition += " AND i.ins_alg_ruimte_key IN (" + terr_key + ")";
                 else if (bld_key)
                   sqlPosition += " AND o.alg_gebouw_key = " + bld_key;
                 else if (loc_key)
                   sqlPosition += (terr_key
                                  ? " AND t.alg_locatie_key"
                                  : " AND i.ins_alg_locatie_key")
                                + " = " + loc_key;
                 else if (dist_key)
                   sqlPosition += " AND di.alg_district_key = " + dist_key;
                 else if (reg_key)
                   sqlPosition += " AND di.alg_regio_key = " + reg_key;
                 else if (!terr_key && fgraph)
                   sqlPosition += " AND i.ins_alg_ruimte_key = -1"; // geen terreinen bij fgraph => geen objecten om te laten zien
               }

               if (ins_key_arr)
               {
                 sqlPosition += " AND i.ins_deel_key IN (" + ins_key_arr.join(",") + ")";
               }
               else if (parent_key)
               {
                 sqlPosition += " AND i.ins_deel_parent_key IN (" + parent_key + ")";
               }
               else if (koppel_key)
               {
                 sqlPosition += " AND idk.ins_deelkoppeling_verwijder IS NULL"
                              + " AND ((     i.ins_deel_key = idk.ins_deelkoppeling_naar_key"
                              + "        AND idk.ins_deelkoppeling_van_key=" + koppel_key
                              + "      )"
                              + "   OR (     i.ins_deel_key = idk.ins_deelkoppeling_van_key"
                              + "        AND idk.ins_deelkoppeling_naar_key=" + koppel_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 i.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 = i.ins_alg_ruimte_key_org"
                                 + " AND o.alg_onroerendgoed_type = i.ins_alg_ruimte_type_org"
                                 + " AND i.ins_alg_ruimte_type_org IN ('T','R','W')"
                                 + " AND o.alg_locatie_key = l.alg_locatie_key";

               sqlPosition += (terr_key
                              ? " AND t.alg_terreinsector_key = i.ins_alg_ruimte_key"
                                + " AND i.ins_alg_ruimte_type = 'T'"                  // Object is NIET uitgeleend, anders was het type 'P'.
                                + " AND t.alg_locatie_key = l.alg_locatie_key"
                              : " AND o.alg_onroerendgoed_keys = i.ins_alg_ruimte_key"
                                + " AND o.alg_onroerendgoed_type = i.ins_alg_ruimte_type"
                                + " AND i.ins_alg_ruimte_type IN ('T','R','W')"       // Object is NIET uitgeleend, anders was het type 'P'.
                                + " AND o.alg_locatie_key = l.alg_locatie_key"        // PF: de redundante ins_alg_locatie_key is niet nodig
                              )

             }

             // And some more conditions that apply for both modes (sqlPosition(_org) and hasOwner(_org)):
             var sql_ex = "";
             if (mld_key)
               sql_ex += " AND i.ins_deel_key IN (SELECT ins_deel_key FROM mld_melding_object WHERE mld_melding_key=" + mld_key + ")";
             if (objsrt_key)
               sql_ex += " AND s.ins_srtdeel_key IN (" + objsrt_key.join(",") + ")";
             else if (insgroup_key)
               sql_ex += " AND ins_srtgroep_key = " + insgroup_key;
             else if (disc_key)
               sql_ex += " AND ins_discipline_key IN (" + disc_key + ")";

             if (beh_key)
               sql_ex += " AND prs_perslid_key_beh =" + beh_key;
             if (deel)
               sql_ex += " AND ins_deel_upper LIKE " + safe.quoted_sql_wild("%" + deel + "%");
             if (deel_opm)
               sql_ex += " AND UPPER(ins_deel_opmerking) LIKE " + safe.quoted_sql_wild("%" + deel_opm + "%");
             if (objsrt_oms)
               sql_ex += " AND (  (ins_srtdeel_upper LIKE " + safe.quoted_sql_wild("%" + objsrt_oms + "%") + ")"
                       + "     OR (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 (inspect && ctrdisc_key > -1)
               sql_ex += " AND ispn.ctr_disc_key = " + ctrdisc_key;

             // Nu filtercondities voor flexkenmerken toevoegen
             sql_ex += getKenmerkSql("INS", "i.ins_deel_key");

             if (sqlPosition != "")
             {
               sqlPosition += sql_ex;
               if (auth_org)
                 sqlPosition_org += sql_ex;
             }

             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,
                                      "i.ins_discipline_key",
                                      "di.alg_regio_key",
                                      "l.alg_district_key",
                                      "l.alg_locatie_key",
                                      "o.alg_gebouw_key",
                                      "o.alg_verdieping_key",
                                      "o.alg_ruimte_key",
                                      "", // b.prs_bedrijf_key: not used because algprs == 0
                                      "", // d.prs_afdeling_key: not used because algprs == 0
                                      pautfunction,
                                      (disc_key? disc_key : ''),
                                      0);  // AKZA#430/PF, AKZA#496/MGE

               if (auth_org)
                 sqlPosition_org = discx3d (sqlPosition_org,
                                            "i.ins_discipline_key",
                                            "di.alg_regio_key",
                                            "l.alg_district_key",
                                            "l.alg_locatie_key",
                                            "o.alg_gebouw_key",
                                            "o.alg_verdieping_key",
                                            "o.alg_ruimte_key",
                                            "", // b.prs_bedrijf_key: not used because algprs == 0
                                            "", // d.prs_afdeling_key: not used because algprs == 0
                                           pautfunction,
                                           (disc_key? disc_key : ''),
                                           0);  // AKZA#430/PF, AKZA#496/MGE
             }

             if (sqlOwnerA != "" && sqlOwnerP != "" && sqlOwnerCP != "")
             {
               sqlOwnerA = discx3d (sqlOwnerA,
                                    "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",
                                    "d.prs_afdeling_key",
                                    pautfunction,
                                    (disc_key? disc_key : ''),
                                    1);  // AKZA#430/PF, AKZA#496/MGE

               if (auth_org)
                 sqlOwnerA_org = discx3d (sqlOwnerA_org,
                                          "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",
                                          "d.prs_afdeling_key",
                                          pautfunction,
                                          (disc_key? disc_key : ''),
                                          1);  // AKZA#430/PF, AKZA#496/MGE

               sqlOwnerP = discx3d (sqlOwnerP,
                                    "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",
                                    "d.prs_afdeling_key",
                                    pautfunction,
                                    (disc_key? disc_key : ''),
                                    1);  // AKZA#430/PF, AKZA#496/MGE
               // Geen autorisatie bij externe bedrijven (prs_bedrijf)

               if (auth_org)
                 sqlOwnerP_org = discx3d (sqlOwnerP_org,
                                          "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",
                                          "d.prs_afdeling_key",
                                          pautfunction,
                                          (disc_key? disc_key : ''),
                                          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 + " UNION " + sqlOwnerCP + sql_ex + " UNION "
                          : "")
                        + sqlOwnerP + sql_ex
                        + (auth_org // S("ins_auth_obj_lendout") == 1 && fronto && insLentOut
                          ? " UNION " + sqlOwnerA_org + sql_ex + " UNION " + sqlOwnerP_org + sql_ex + " UNION " + sqlOwnerCP_org + sql_ex
                          : "");

               // Now apply user filtering on this query:
               if (persoon_key)
               {
                 sqlOwner = "SELECT * FROM (" + sqlOwner + ") x WHERE x.alg_ruimte_key = " + persoon_key;
               }
               else if (cpersoon_key)
               {
                 sqlOwner = "SELECT * FROM (" + sqlOwner + ") x WHERE 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;
               }
             }

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

             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" : "")
                               + (inspClosed && inspBusy? ", " : "")
                               + (inspClosed? "5" : "")
                               + ")"
                             : "");

                 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 * FROM (" + sql + ") x WHERE COALESCE(ins_deelsrtcontrole_plandatum, inspectie_next) BETWEEN " + dtsoonfrom.toSQL(true) + " AND " + dtsoonto.toSQL(true) + (sqlBC != ''? " OR " + sqlBC : "");
                   else if (dtsoonfrom == null && dtsoonto != null) // Te laat + binnenkort.
                     sql = "SELECT * FROM (" + sql + ") x WHERE COALESCE(ins_deelsrtcontrole_plandatum, inspectie_next) < " + dtsoonto.toSQL(true) + (sqlBC != ''? " OR " + sqlBC : "");
                   else if (dtsoonfrom != null && dtsoonto == null) // Binnenkort + toekomst.
                     sql = "SELECT * FROM (" + sql + ") x WHERE COALESCE(ins_deelsrtcontrole_plandatum, inspectie_next) >= " + dtsoonfrom.toSQL(true) + (sqlBC != ''? " OR " + sqlBC : "");
                   else if (dtsoonfrom == null && dtsoonto == null)
                     sql = "SELECT * FROM (" + sql + ") x WHERE 1 = 1"; // Alles tonen onafhankelijk van sqlBC.
                 }
                 else if (inspBusy || inspClosed) // Onderhanden (inspBusy), vervolgactie vereist (inspClosed).
                   sql = "SELECT * FROM (" + sql + ") x WHERE " + sqlBC;
                 else // Geen checkbox aangevinkt.
                   sql = "SELECT * FROM (" + sql + ") x WHERE 1 = 1"; // Alles tonen.

                 if (cnt_bedrijf_key > 0) // 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 += " 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_deel 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_deel 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_deel 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_deel 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.
                   sql += "   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)"
                        + "                      )"
                        + "     )";

                 }
             }

             sql = "SELECT * FROM (" + sql + ") XX 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" : " ins_deel_omschrijving, plaats, ins_disc_oms, ins_groep_oms, soort"));

             return sql;
           }

}
%>