<!-- #include file="../Shared/json2.js" -->
<% /*
     $Revision$
     $Id$
*/

cnt = { setcontractstatus:
           function (cnt_key, cnt_status_key)
           {
             // Deze zet de status en doet dan bijpassende tracking en notificatie
             var sql = "BEGIN cnt.setcontractstatus(" + cnt_key + ", " + cnt_status_key + ", " + user_key + "); END;"
             Oracle.Execute(sql);
             // zou leuk zijn om true of false op te leveren naar gelang de status echt anders is geworden
           },

        trackcontractgoedkeuren:
           function (cnt_key, ptxt)
           {
               shared.trackaction("CNTFIT", cnt_key, ptxt);
           },

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

        trackcontractverwijderen:
           function (cnt_key, ptxt)
           {
               shared.trackaction("CNTDEL", cnt_key, ptxt);
           },

        getCntLocationsSql:
           function ()
           {
             // Alleen personen met rechten op de locaties van de contracten mogen goedkeuren.
             // Daarvoor hebben we de locatie van de contracten nodig.
             // LET OP: - type 4 (algemeen / generiek) zit er niet in.
             return " SELECT cp.cnt_contract_key"
                  + "      , cp.cnt_alg_plaats_key alg_locatie_key"
                  + "   FROM cnt_contract_plaats cp"
                  + "  WHERE cnt_alg_plaats_code = 'L'"
                  + " UNION ALL"
                  + " SELECT cp.cnt_contract_key"
                  + "      , g.alg_locatie_key"
                  + "   FROM cnt_contract_plaats cp, alg_gebouw g"
                  + "  WHERE cnt_alg_plaats_code = 'G'"
                  + "    AND cp.cnt_alg_plaats_key = g.alg_gebouw_key"
                  + " UNION ALL"
                  + " SELECT cp.cnt_contract_key"
                  + "      , t.alg_locatie_key"
                  + "   FROM cnt_contract_plaats cp, alg_terreinsector t"
                  + "  WHERE cnt_alg_plaats_code = 'T'"
                  + "    AND cp.cnt_alg_plaats_key = t.alg_terreinsector_key"
                  + " UNION ALL"
                  + " SELECT co.cnt_contract_key"
                  + "      , d.ins_alg_locatie_key"
                  + "   FROM cnt_contract_object co"
                  + "      , ins_deel d"
                  + "  WHERE co.cnt_ins_deel_key = d.ins_deel_key"
                  + "    AND d.ins_alg_locatie_key IS NOT NULL"
                  + " UNION ALL"
                  + " SELECT co.cnt_contract_key"
                  + "      , g.alg_locatie_key"
                  + "   FROM cnt_contract_onrgoed co"
                  + "      , alg_gebouw g"
                  + "      , alg_verdieping v"
                  + "      , alg_ruimte r"
                  + " WHERE co.alg_onrgoed_niveau = 'R'"
                  + "   AND co.alg_onrgoed_key = r.alg_ruimte_key"
                  + "   AND r.alg_verdieping_key = v.alg_verdieping_key"
                  + "   AND v.alg_gebouw_key = g.alg_gebouw_key"
                  + " UNION ALL"
                  + " SELECT co.cnt_contract_key"
                  + "      , t.alg_locatie_key"
                  + "   FROM cnt_contract_onrgoed co, alg_terreinsector t"
                  + "  WHERE co.alg_onrgoed_niveau = 'T'"
                  + "    AND co.alg_onrgoed_key = t.alg_terreinsector_key";
           },

        getCntApprovers:
           function (cnt_key)
           { //  Ontvanger(s) = eerste, tweede, derde, vierde of vijfde fiatteur(s). Deze hebben WEB_CNTGO1, WEB_CNTGO2, WEB_CNTGO3, WEB_CNTGO4 en/of WEB_CNTGO5 rechten.
             var approver_arr = [];
             // Tot welk bedrag is er al goedgekeurd.
             var sql = "SELECT cnt_contract_approved"
                     + "     , cnt_contract_kosten"
                     + "  FROM cnt_contract c"
                     + " WHERE cnt_contract_key = " + cnt_key;
             var oRs = Oracle.Execute(sql);
             var kosten = oRs("cnt_contract_kosten").Value? oRs("cnt_contract_kosten").Value : 0;
             var approved = oRs("cnt_contract_approved").Value? oRs("cnt_contract_approved").Value : -1;
             oRs.Close();

             var functie_code;
             if (kosten <= S("cnt_contract_limit1")) // Dit eerst testen i.v.m. Ter goedkeuring. Verder moet sowieso goedgekeurd worden.
               return []; // Het bedrag is lager als de eerste limiet. Het contract hoeft niet goed gekeurd te worden, dus een lege fiatteurs array teruggeven.
             else if ((S("cnt_approval_all") == 0 && approved <= S("cnt_contract_limit1")) || (S("cnt_approval_all") == 1 && kosten <= S("cnt_contract_limit2")))
               functie_code = "WEB_CNTGO1";
             else if ((S("cnt_approval_all") == 0 && approved <= S("cnt_contract_limit2")) || (S("cnt_approval_all") == 1 && kosten <= S("cnt_contract_limit3")))
               functie_code = "WEB_CNTGO2";
             else if ((S("cnt_approval_all") == 0 && approved <= S("cnt_contract_limit3")) || (S("cnt_approval_all") == 1 && kosten <= S("cnt_contract_limit4")))
               functie_code = "WEB_CNTGO3";
             else if ((S("cnt_approval_all") == 0 && approved <= S("cnt_contract_limit4")) || (S("cnt_approval_all") == 1 && kosten <= S("cnt_contract_limit5")))
               functie_code = "WEB_CNTGO4";
             else if ((S("cnt_approval_all") == 0 && approved <= S("cnt_contract_limit5")) || (S("cnt_approval_all") == 1 && kosten > S("cnt_contract_limit5")))
               functie_code = "WEB_CNTGO5";
             else return []; // Het goedgekeurde bedrag zit al boven de vijfde limiet. Geen approval meer nodig.

             // Alleen personen met rechten op de locaties van de contracten mogen goedkeuren.
             // Daarvoor hebben we de locatie van de contracten nodig.
             var sql_cntloc = cnt.getCntLocationsSql();


             // Bepaal de fiatteurs.
             // De functiekey apart bepalen is 15x sneller
             sql = "SELECT fac_functie_key FROM fac_functie WHERE fac_functie_code = " + safe.quoted_sql(functie_code);
             oRs = Oracle.Execute(sql);
             var functie_key = oRs("fac_functie_key").Value;
             oRs.Close();

             // De ALGwritelevel (niveau) van de te bepalen goedkeurders weet ik niet.
             // Dat moet dus in de query zelf opgevraagd worden.
             var AlGwritelevel_GOE = "SELECT COALESCE (MIN (fac_gebruiker_alg_level_write), 9) awrite"
                                   + "  FROM fac_v_webgebruiker w"
                                   + " WHERE w.prs_perslid_key = g.prs_perslid_key"
                                   + "   AND w.fac_functie_key IN (" + functie_key + ")";

             sql = "SELECT DISTINCT g.prs_perslid_key"
                 + "  FROM fac_functie f"
                 + "     , fac_v_webgebruiker g"
                 + "     , cnt_contract c"
                 + "     , (" + sql_cntloc + ") cntloc"
                 + " WHERE g.fac_functie_key = " + functie_key
                 + "   AND g.ins_discipline_key = c.ins_discipline_key"
                 + "   AND c.cnt_contract_key = " + cnt_key
                 + "   AND c.cnt_contract_key = cntloc.cnt_contract_key(+)"
                 // Als AlGwritelevel_GOE > -1 is dan moet de contract locatie(s) binnen de locatie scope van de goedkeurders zitten.
                 + "   AND (cntloc.alg_locatie_key IN (SELECT alg_locatie_key FROM fac_v_my_locations"
                 + "                                    WHERE prs_perslid_key = g.prs_perslid_key"
                 + "                                      AND niveau = (" + AlGwritelevel_GOE + "))"
                 // Op contracten zonder locatie(s) heeft iedereen rechten.
                 + "        OR cntloc.alg_locatie_key IS NULL"
                 // Heeft een goedkeurder alle CNTGOX rechten dan hoef je niet naar locatie(s) te kijken.
                 + "        OR (" + AlGwritelevel_GOE + ") = -1)";
             oRs = Oracle.Execute(sql);
             while(!oRs.eof)
             {
               approver_arr.push(oRs("prs_perslid_key").Value); // Fiatteur.
               oRs.MoveNext();
             }
             oRs.Close();
             return approver_arr;
           },

        getcntstatustext:
           function (p)
           {
             var statustekst = "??";
             var s = parseInt(p, 10);
             switch (s) {
                 case 0: { statustekst = (S("cnt_contract_approval") == 1? L("lcl_cnt_active_approval") : L("lcl_cnt_active")); break; }
                 case 1: { statustekst = L("lcl_cnt_inactive"); break; }
                 case 2: { statustekst = L("lcl_cnt_new"); break; }
                 case 3: { statustekst = L("lcl_cnt_forapproval"); break; }
             }
             if (Session("logging")>0)
               statustekst += " (" + String(p) + ")";
             return statustekst;
           },

        // return the right sql-condition for the given phases
        getfaseconditionsql:
           function (p)
           {
              var fasesql = "";
              var addOr = " AND (";
              if (p.cntffutu)
              {
                fasesql = " AND (SYSDATE < c.cnt_contract_looptijd_van";
                addOr = " OR ";
              }
              if (p.cntfact)
              {
                fasesql += addOr + " (SYSDATE BETWEEN c.cnt_contract_looptijd_van"
                       + " AND cnt.cnt_getRappeldatum(c.cnt_contract_key))";
                addOr = " OR ";
              }
              if (p.cntfrap)
              {
                fasesql += addOr + " (SYSDATE"
                       + " BETWEEN cnt.cnt_getRappeldatum(c.cnt_contract_key)"
                       + " AND cnt.cnt_getOpzegdatum(c.cnt_contract_key))";
                addOr = " OR ";
              }
              if (p.cntfopz)
              {
                fasesql += addOr + " (SYSDATE - 1"
                       + " BETWEEN cnt.cnt_getOpzegdatum(c.cnt_contract_key) - 1"
                       +  " AND c.cnt_contract_looptijd_tot)";
                addOr = " OR ";
              }
              if (p.cntfverl)
              {
                fasesql += addOr + " SYSDATE > c.cnt_contract_looptijd_tot";
                addOr = " OR ";
              }
              if (addOr == " OR ")
              {
                fasesql += ")";
              }
              return fasesql;
           },

        getfromwherelist_sql:
           function(pautfunction, params)
           {
             var cntsrt_key = params.cntsrt_key;
             var cntnum = params.cntnum;
             var dienst_key = params.dienst_key;
             var uitvoerder_key = params.uitvoerder_key;
             var cnt_persoon_key = params.cnt_persoon_key;
             var eigenaar_key = params.eigenaar_key;
             var manager_key = params.manager_key;
             var beheerder_key = params.beheerder_key;
             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 objectsrt_key = params.objectsrt_key;
             var mantel_key = params.mantel_key;
             var descript = params.descript;
             var ins_key = params.ins_key;
             var kp_key = params.kp_key;
             var ksgrp_key = params.ksgrp_key;
             var ks_key = params.ks_key;
             // Statussen.
             var cntAct = params.cntAct;
             var cntInact = params.cntInact;
             var cntNew = params.cntNew;
             var cntTgoe = params.cntTgoe;
             // Fases binnen status Acief
             var cntFFutu = params.cntFFutu;
             var cntFAct = params.cntFAct;
             var cntFRap = params.cntFRap;
             var cntFOpz = params.cntFOpz;
             var cntFVerl = params.cntFVerl;
             var grp_sel = params.grp_sel;
             var mobile = params.mobile == 1;
             var tiny = params.tiny;

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

             // Voeg laatste tracking datum toe
             sqltrack = ", (SELECT MAX(t.fac_tracking_datum)"
                      + "     FROM fac_tracking t"
                      + "        , fac_srtnotificatie sn"
                      + "    WHERE t.fac_srtnotificatie_key = sn.fac_srtnotificatie_key"
                      + "      AND t.fac_tracking_refkey = c.cnt_contract_key" // contract key uit "sql"
                      + "      AND sn.fac_srtnotificatie_xmlnode = 'contract') recentdatum";

             sql = "SELECT c.cnt_contract_nummer"
                 + "     , c.cnt_contract_versie"
                 + "     , c.cnt_contract_omschrijving"
                 + "     , c.cnt_contract_opmerking"
                 + "     , c.cnt_contract_document"
                 + "     , COALESCE(b.prs_bedrijf_naam, af" + S("prs_dep_string") + ", " + S("prs_pers_string") + ") uitvoerder" // af + S("prs_dep_string") heeft parameter afd.
                 + "     , " + S("prs_dep_string") + " eigenaar"
                 + "     , c.cnt_contract_looptijd_van begindatum"
                 + "     , c.cnt_contract_looptijd_tot einddatum"
                 + "     , cnt.cnt_getOpzegdatum(c.cnt_contract_key) cnt_opzegdatum"
                 + "     , cnt.cnt_getRappeldatum(c.cnt_contract_key) cnt_rappeldatum"
                 + "     , cnt.cnt_contract_status("
                   + "       c.cnt_contract_looptijd_van"
                   + "     , cnt.cnt_getRappeldatum(c.cnt_contract_key)"
                   + "     , cnt.cnt_getOpzegdatum(c.cnt_contract_key)"
                   + "     , c.cnt_contract_looptijd_tot) fase_actief"
                 + "     , c.cnt_contract_status"
                 + "     , c.cnt_contract_key cnt_contract_key"
                 + "     , COALESCE(c.ins_discipline_key, -1) disc_key"
                 + "     , c.prs_afdeling_key_eig eigenaar_key"
                 + "     , c.cnt_contract_nummer_intern"
                 + "     , dp.cnt_srtcontract_type"
                 + "     , alg_locatie_oms"
                 + "     , alg_locatie_omschrijving"
                 + "     , alg_district_omschrijving"
                 + "     , alg_locatie_code"
                 + "     , alg_locatie_count"
                 + "     , c.ins_discipline_key"
                 + "     , " + lcl.xsqla('cd.ins_discipline_omschrijving', 'cd.ins_discipline_key')
                 + "     , c.cnt_contract_kosten"
                 + "     , di.prs_dienst_omschrijving"
                 + "     , (SELECT " + S("prs_kpn_string")
                         + "  FROM prs_kostenplaats k"
                         + " WHERE k.prs_kostenplaats_key = c.prs_kostenplaats_key) kostenplaats"
                 + sqltrack
                 + "  FROM prs_v_aanwezigbedrijf b"
                 + "     , cnt_v_aanwezigcontract c"
                 + "     , prs_dienst di"
                 + (ksgrp_key
                   ? "   , prs_kostensoort ks"
                   : "")
                 + "     , prs_v_afdeling d"
                 + "     , prs_v_afdeling afd"
                 + "     , prs_perslid p"
                 + "     , alg_district ad"
                 + "     , cnt_disc_params dp"
                 + "     , cnt_discipline cd";

             // Om drie redenen hebben we de locatie_key nodig in de hoofd query
             //   - Voor als de gebruiker filtert op locatie (optioneel)
             //   - Voor als de gebruiker beperkte autorisatie heeft (optioneel)
             //   - Om de locatieomschrijving in de lijst te kunnen tonen (niet bij maninfo)
             // Voor die eerste twee is sql_cnt_loc_keyA die bij contracten met meerdere locaties alles bevat
             //  Voor de tweede is sql_cnt_loc_key die groeppeert en telt per locatie
             // LET OP: - type 4 (algemeen / generiek) zit er niet in
             sql_cnt_loc_keyA = " SELECT cp.cnt_contract_key"
                              + "      , cp.cnt_alg_plaats_key alg_locatie_key"
                              + "   FROM cnt_contract_plaats cp"
                              + "  WHERE cnt_alg_plaats_code = 'L'"
                              + " UNION ALL"
                              + " SELECT cp.cnt_contract_key"
                              + "      , g.alg_locatie_key"
                              + "   FROM cnt_contract_plaats cp, alg_gebouw g"
                              + "  WHERE cnt_alg_plaats_code = 'G'"
                              + "    AND cp.cnt_alg_plaats_key = g.alg_gebouw_key"
                              + " UNION ALL"
                              + " SELECT cp.cnt_contract_key"
                              + "      , t.alg_locatie_key"
                              + "   FROM cnt_contract_plaats cp, alg_terreinsector t"
                              + "  WHERE cnt_alg_plaats_code = 'T'"
                              + "    AND cp.cnt_alg_plaats_key = t.alg_terreinsector_key"
                              + " UNION ALL"
                              + " SELECT co.cnt_contract_key"
                              + "      , d.ins_alg_locatie_key"
                              + "   FROM cnt_contract_object co"
                              + "      , ins_deel d"
                              + "  WHERE co.cnt_ins_deel_key = d.ins_deel_key"
                              + " UNION ALL"
                              + " SELECT co.cnt_contract_key"
                              + "      , g.alg_locatie_key"
                              + "   FROM cnt_contract_onrgoed co"
                              + "      , alg_gebouw g"
                              + "      , alg_verdieping v"
                              + "      , alg_ruimte r"
                              + " WHERE co.alg_onrgoed_niveau = 'R'"
                              + "   AND co.alg_onrgoed_key = r.alg_ruimte_key"
                              + "   AND r.alg_verdieping_key = v.alg_verdieping_key"
                              + "   AND v.alg_gebouw_key = g.alg_gebouw_key"
                              + " UNION ALL"
                              + " SELECT co.cnt_contract_key"
                              + "      , t.alg_locatie_key"
                              + "   FROM cnt_contract_onrgoed co, alg_terreinsector t"
                              + "  WHERE co.alg_onrgoed_niveau = 'T'"
                              + "    AND co.alg_onrgoed_key = t.alg_terreinsector_key";

             sql_cnt_loc_key = "SELECT MIN(alg_locatie_omschrijving || ' (' || alg_locatie_code || ')') alg_locatie_oms"
                             + "     , MIN(alg_locatie_omschrijving) alg_locatie_omschrijving"
                             + "     , MIN(alg_locatie_code) alg_locatie_code"
                             + "     , MIN(alg_district_key) alg_district_key"
                             + "     , cnt_contract_key"
                             + "     , MIN(ll.alg_locatie_key) alg_locatie_key"
                             + "     , COUNT(distinct alg_locatie_code) alg_locatie_count"
                             + "  FROM alg_locatie ll"
                             + "     , (" + sql_cnt_loc_keyA + ") scloc"
                             + "  WHERE ll.alg_locatie_key = scloc.alg_locatie_key"
                             + " GROUP BY cnt_contract_key";

             sql += ", (" + sql_cnt_loc_key + ") cloc";

             sql += " WHERE b.prs_bedrijf_key(+) = c.cnt_prs_bedrijf_key"
                  + " AND c.cnt_prs_afdeling_key = afd.prs_afdeling_key(+)"
                  + " AND c.cnt_prs_perslid_key = p.prs_perslid_key(+)"
                  + " AND c.prs_dienst_key = di.prs_dienst_key(+)"
                  + " AND d.prs_afdeling_key = c.prs_afdeling_key_eig"
                  + " AND c.ins_discipline_key = dp.cnt_ins_discipline_key"
                  + " AND c.ins_discipline_key = cd.ins_discipline_key"
                  + " AND cloc.cnt_contract_key(+) = c.cnt_contract_key"
                  + " AND cloc.alg_district_key = ad.alg_district_key(+)";

             if (cntsrt_key)
               sql += " AND c.ins_discipline_key = " + cntsrt_key;

             sql += getKenmerkSql("CNT", "c.cnt_contract_key", true);

             // Dienst.
             if (dienst_key)
             {
               sql += " AND (c.prs_dienst_key = " + dienst_key
                   +  "      OR (c.prs_dienst_key IS NULL "
                   +  "          AND EXISTS (SELECT '' FROM prs_bedrijfdienstlocatie dl "
                   +  "                       WHERE dl.prs_bedrijf_key = b.prs_bedrijf_key AND dl.prs_dienst_key = " + dienst_key + ")))";
             }

             // Uitvoerder.
             if (uitvoerder_key)
               sql += " AND b.prs_bedrijf_key = " + uitvoerder_key;

             // Persoon (Contractpartij).
             if (cnt_persoon_key)
               sql += " AND c.cnt_prs_perslid_key = " + cnt_persoon_key;

             // Mantel.
             if (mantel_key)
               sql += " AND c.cnt_contract_mantel_key = " + mantel_key;

             // Afdeling (Eigenaar).
             if (eigenaar_key)
               sql += " AND c.prs_afdeling_key_eig = " + eigenaar_key;

             // Verantwoordelijk manager.
             if (manager_key)
               sql += " AND c.prs_perslid_key_eig = " + manager_key;

             // Beheerder.
             if (beheerder_key)
               sql += " AND c.prs_perslid_key_beh = " + beheerder_key;

             // Regio, District, Locatie en gebouw.
             if (bld_key)
             {
               sql_bld = bld_key;
               sql_loc = loc_key;
             }
             else if (loc_key)
               sql_loc = loc_key;
             else if (dist_key)
               sql_loc = "SELECT alg_locatie_key FROM alg_locatie WHERE alg_district_key = " + dist_key;
             else if (reg_key)
               sql_loc = "SELECT alg_locatie_key FROM alg_locatie l, alg_district d WHERE l.alg_district_key = d.alg_district_key AND d.alg_regio_key = " + reg_key;

             // Merk op dat we hier niet kunnen verwijzen naar cloc binnen sql omdat die MIN(alg_locatie_key) en MIN(alg_gebouw_key) bevat.
             if (reg_key || dist_key || loc_key)
             {
               sql += " AND c.cnt_contract_key IN"
                    + " (SELECT cnt_contract_key FROM cnt_v_aanwezigcontract_plaats"
                    + " WHERE (cnt_alg_plaats_code = 'L' AND cnt_alg_plaats_key IN (" + sql_loc + "))";

               if (bld_key)
               {
                 sql += " OR (cnt_alg_plaats_code = 'G' AND cnt_alg_plaats_key = "
                      + bld_key
                      + ") OR (cnt_alg_plaats_code = 'T' AND cnt_alg_plaats_key = "
                      + bld_key + ")";
               }
               else
               {
                 sql += " OR (cnt_alg_plaats_code = 'G' AND cnt_alg_plaats_key IN "
                      + " (SELECT alg_gebouw_key FROM alg_v_aanweziggebouw WHERE alg_locatie_key IN (" + sql_loc + "))"
                      + " OR cnt_alg_plaats_code = 'T' AND cnt_alg_plaats_key IN "
                      + " (SELECT alg_terreinsector_key FROM alg_v_aanwezigterreinsector WHERE alg_locatie_key IN (" + sql_loc + ")))";
               }

               sql += " UNION SELECT cnt_contract_key FROM cnt_v_aanwezigcontract_object co, ins_v_aanwezigdeel ad"
                    + " WHERE cnt_ins_deel_key = ad.ins_deel_key AND ad.ins_alg_locatie_key IN (" + sql_loc + ")";

               sql += " UNION SELECT cnt_contract_key FROM cnt_v_contract_locatie_geg cl"
                    + " WHERE alg_locatie_key IN (" + sql_loc + "))";
             }

             // Objectsoort.
             if (objectsrt_key)
             {
               sql += " AND c.cnt_contract_key IN "
                    + " (SELECT cnt_contract_key FROM cnt_v_aanwezigcontract_object"
                    + " WHERE cnt_ins_srtdeel_key = " + objectsrt_key +")";
             // we assume that srtdeel is defined if deel is defined. It is.
             //     + " OR cnt_ins_deel_key IN "
             //     + "(SELECT ins_deel_key FROM ins_v_aanwezigdeel WHERE ins_srtdeel_key = " + objectsrt_key + "))";
             }
             if (ins_key)
             {
               sql += " AND c.cnt_contract_key IN "
                    + " (SELECT DISTINCT cnt_contract_key"
                    + "    FROM (SELECT   cnt_contract_key"
                    + "            FROM cnt_contract_object"
                    + "           WHERE cnt_ins_deel_key =" + ins_key + ""
                    + "          UNION"
                    + "          SELECT co.cnt_contract_key"
                    + "            FROM cnt_v_aanwezigcontract_object co"
                    + "               , ins_deel d"
                    + "               , cnt_v_aanwezigcontract_plaats ccp"
                    + "               , alg_v_allonroerendgoed aao"
                    + "           WHERE cnt_ins_deel_key IS NULL"
                    + "             AND co.cnt_ins_srtdeel_key = d.ins_srtdeel_key"
                    + "             AND d.ins_deel_key =" + ins_key + ""
                    + "             AND ccp.cnt_contract_key = co.cnt_contract_key"
                    + "             AND COALESCE (d.ins_alg_ruimte_type_org,"
                    + "                           ins_alg_ruimte_type) = 'R'"
                    + "             AND COALESCE (d.ins_alg_ruimte_key_org,"
                    + "                           ins_alg_ruimte_key) = aao.alg_ruimte_key"
                    + "             AND ( (ccp.cnt_alg_plaats_code = 'L'"
                    + "                    AND ccp.cnt_alg_plaats_key = aao.alg_locatie_key)"
                    + "                  OR (ccp.cnt_alg_plaats_code = 'G'"
                    + "                      AND ccp.cnt_alg_plaats_key = aao.alg_gebouw_key))"
                    + "          UNION"
                    + "          SELECT co.cnt_contract_key"
                    + "            FROM cnt_v_aanwezigcontract_object co"
                    + "               , ins_deel d"
                    + "           WHERE cnt_ins_deel_key IS NULL"
                    + "             AND co.cnt_ins_srtdeel_key = d.ins_srtdeel_key"
                    + "             AND d.ins_deel_key =" + ins_key + ""
                    + "             AND (co.cnt_contract_key NOT IN"
                    + "                       (SELECT cnt_contract_key"
                    + "                          FROM cnt_v_aanwezigcontract_plaats)"
                    + "                  OR COALESCE (d.ins_alg_ruimte_type_org,"
                    + "                               ins_alg_ruimte_type) != 'R')))";
              }

             if (kp_key)
             {
               sql += " AND c.prs_kostenplaats_key = " + kp_key;
             }

             if (ksgrp_key)
             {
                sql += " AND c.prs_kostensoort_key = ks.prs_kostensoort_key"
                     + " AND ks.prs_kostensoortgrp_key = " + ksgrp_key;
             }

             if (ks_key)
             {
                // Ook die van het contractsoort beschouwen, het gaat om de geldende ks, niet per se de geregistreerde
                // deze is niks sneller: sql += " AND (c.prs_kostensoort_key = " + ks_key + " OR (cd.prs_kostensoort_key = " + ks_key + " AND c.prs_kostensoort_key IS NULL))";
                sql += " AND COALESCE(c.prs_kostensoort_key, cd.prs_kostensoort_key) = " + ks_key;
             }

             // Beschrijving
             if (descript)
             {
               sql += " AND UPPER(c.cnt_contract_omschrijving) LIKE " + safe.quoted_sql_wild("%"+descript+"%");
             }

             // we don't use status field because we don't have mechanism to change its value
             // in case of mld_melding status was changed as the result of user's actions
             // here it gets changed as the result of current date changing

             // Contract number
             if (cntnum)
             {
                 sql += " AND (UPPER(c.cnt_contract_nummer) LIKE " + safe.quoted_sql_wild(cntnum + "%")
                      + "      OR UPPER(c.cnt_contract_nummer_intern) LIKE " + safe.quoted_sql_wild(cntnum + "%") + ")";
             }
             else
             {
               var statussen = "";
               var komma = ", ";
               var actief = false;
               var sqlactief = "";
               if (cntAct)
               {
                 //statussen = "0", en dan ook naar de fases binnen de status Actief kijken.
                 sqlactief += " (c.cnt_contract_status = 0"
                            + cnt.getfaseconditionsql({cntffutu: cntFFutu, cntfact: cntFAct, cntfrap: cntFRap, cntfopz: cntFOpz, cntfverl: cntFVerl})
                            + ")";
               }
               if (cntInact)
                 statussen += "1";
               if (cntNew)
                 statussen += (statussen != ""? komma : "") + "2";
               if (cntTgoe)
                 statussen += (statussen != ""? komma : "") + "3";
               var sqlINT = statussen == ""? "" :  " (c.cnt_contract_status IN (" + statussen + "))";

               if (sqlactief != "" && sqlINT != "")
                 sql += " AND (" + sqlactief + " OR" + sqlINT + ")";
               else if (sqlactief != "" || sqlINT != "")
                 sql += " AND" + sqlactief + sqlINT; // Één van beide is een lege string.
               else
                 sql += " AND 1 = 0";
             }

             // scope
             // sql bevat al wel een alg_locatie_key maar er zit een group-by (en een MIN) in
             // wat te streng is voor scope
             // Daarom teruggrijpen op sql_cnt_loc_keyA die nog geen group-by op contract heeft gedaan
             sql_scope = " SELECT cnt_contract_key"
                       + "   FROM (SELECT cc.cnt_contract_key"
                         + "            , ins_discipline_key"
                         + "            , di.alg_regio_key"
                         + "            , ll.alg_district_key"
                         + "            , clk.alg_locatie_key"
                         + "         FROM (" + sql_cnt_loc_keyA + ") clk"
                         + "            , cnt_contract cc"
                         + "            , alg_locatie ll"
                         + "            , alg_district di"
                         + "        WHERE cc.cnt_contract_key = clk.cnt_contract_key"
                         + "          AND ll.alg_locatie_key(+) = clk.alg_locatie_key" // persoons/afdelingsgebonden objecten hebben geen ins_alg_locatie_key vandaar (+)
                         + "          AND ll.alg_district_key = di.alg_district_key(+)" // persoons/afdelingsgebonden objecten hebben geen ins_alg_locatie_key vandaar (+)
                         + "      ) sc"
                       + "      , prs_v_afdeling_boom boom"
                       + "  WHERE boom.prs_afdeling_key = c.prs_afdeling_key_eig";

             // Autorisatie voor ALG (cnt_contract_plaats) en PRS (cnt_contract.prs_afdeling_key_eig)
             sql_scope = discx3d (sql_scope,
                                  "sc.ins_discipline_key",
                                  "sc.alg_regio_key",
                                  "sc.alg_district_key",
                                  "sc.alg_locatie_key",
                                  "sc.alg_gebouw_key",
                                  "", // verdieping not supported
                                  "", // ruimte not supported
                                  "boom.prs_bedrijf_key",
                                  "boom.prs_afdeling_key",
                                  pautfunction,
                                  (!cntnum && cntsrt_key? cntsrt_key : ""),
                                  2);

             // Scopeloos contract of nog geen scope toegekend. Alleen disc en eigenaar controleren
             sql_scopeloos = "SELECT cnt_contract_key"
                           + "  FROM cnt_contract c"
                           + "     , prs_v_afdeling_boom boom"
                           + " WHERE NOT EXISTS (SELECT cnt_contract_key"
                             + "                   FROM cnt_contract_plaats cp"
                             + "                  WHERE cp.cnt_contract_key = c.cnt_contract_key)"
                           + "   AND NOT EXISTS (SELECT cnt_contract_key"
                             + "                   FROM cnt_contract_onrgoed co"
                             + "                  WHERE co.cnt_contract_key = c.cnt_contract_key)"
                           + "   AND NOT EXISTS (SELECT cnt_contract_key"
                             + "                   FROM cnt_contract_object co"
                             + "                  WHERE co.cnt_contract_key = c.cnt_contract_key"
                           + "   AND co.cnt_ins_deel_key IS NOT NULL)"  // alleen de contracten met objecten uitsluiten. Niet de contracten met contractsoorten uitsluiten.
                           + "   AND boom.prs_afdeling_key = c.prs_afdeling_key_eig";

             // Autorisatie voor PRS (cnt_contract.prs_afdeling_key_eig)
             sql_scopeloos = discx3d (sql_scopeloos,
                                      "c.ins_discipline_key",
                                      "", // regio not supported
                                      "", // district not supported
                                      "", // locatie not supported
                                      "", // gebouw not supported
                                      "", // verdieping not supported
                                      "", // ruimte not supported
                                      "boom.prs_bedrijf_key",
                                      "boom.prs_afdeling_key",
                                      pautfunction,
                                      (cntsrt_key? cntsrt_key : ""),
                                      1);

             // En de contracten waarvan ik eigenaar of beheerder ben, ook al zouden die verder buiten de scope vallen
             sql_mine = "SELECT cnt_contract_key FROM cnt_contract WHERE c.prs_perslid_key_beh = " + user_key + " OR c.prs_perslid_key_eig = " + user_key;

             sql = sql + " AND c.cnt_contract_key IN (" + sql_scope + " UNION ALL " + sql_scopeloos + " UNION ALL " + sql_mine + ")"
                 + (grp_sel == "" || grp_sel == null
                   ? ""
                   : " AND ins_discipline_omschrijving = " + safe.quoted_sql(grp_sel));

             // Op datum (c.cnt_contract_looptijd_tot) sorteren: UWVA#13274 en daarbinnen op c.cnt_contract_nummer en c.cnt_contract_nummer_intern: UWVA#14609
             // Als tiny (framed) dan ook sorteren op status en fase
             sql += " ORDER BY" + (excel || mobile? " UPPER("+ lcl.xsql('cd.ins_discipline_omschrijving','cd.ins_discipline_key') +")," : "")
                  + (mobile
                    ? "       uitvoerder"
                      + "   , cnt_contract_omschrijving"
                    :  (tiny
                       ? "  c.cnt_contract_status"
                      +  "  , decode(cnt.cnt_contract_status (c.cnt_contract_looptijd_van, cnt.cnt_getRappeldatum (c.cnt_contract_key), cnt.cnt_getOpzegdatum (c.cnt_contract_key), c.cnt_contract_looptijd_tot), 4, 2, 1)"
                      +  "  , c.cnt_contract_looptijd_tot"
                    :  "  c.cnt_contract_looptijd_tot")
                      +  "  , c.cnt_contract_nummer")
                  + "        , c.cnt_contract_nummer_intern";

             return sql;
           },

        findSenderForNotifications: function (cnt_key)
        {
          var sql = "SELECT MAX (cd.ins_discipline_email) email"
                  + "  FROM cnt_contract c"
                  + "     , cnt_discipline cd"
                  + " WHERE c.ins_discipline_key = cd.ins_discipline_key"
                  + "   AND c.cnt_contract_key = " + cnt_key;
          var oRs = Oracle.Execute(sql);
          var lsender = oRs("email").Value;
          oRs.Close();
          if (lsender == null)
          {
            sql = "SELECT MAX(email) email"
                + "  FROM (SELECT l.alg_locatie_email email"
                + "          FROM cnt_contract_plaats"
                + "             , alg_locatie l"
                + "         WHERE cnt_alg_plaats_key = l.alg_locatie_key"
                + "           AND cnt_alg_plaats_code = 'L'"
                + "           AND cnt_contract_plaats_verwijder IS NULL"
                + "           AND cnt_contract_key = " + cnt_key
                + "        UNION"
                + "        SELECT l.alg_locatie_email email"
                + "          FROM cnt_contract_plaats"
                + "             , alg_locatie l"
                + "             , alg_gebouw g"
                + "         WHERE cnt_alg_plaats_code = 'G'"
                + "           AND cnt_alg_plaats_key = g.alg_gebouw_key"
                + "           AND g.alg_locatie_key = l.alg_locatie_key"
                + "           AND cnt_contract_plaats_verwijder IS NULL"
                + "           AND cnt_contract_key = " + cnt_key
                + "        UNION"
                + "        SELECT l.alg_locatie_email email"
                + "          FROM cnt_contract_plaats"
                + "             , alg_locatie l"
                + "             , alg_terreinsector t"
                + "         WHERE cnt_alg_plaats_code = 'T'"
                + "           AND cnt_alg_plaats_key = t.alg_terreinsector_key"
                + "           AND t.alg_locatie_key = l.alg_locatie_key"
                + "           AND cnt_contract_plaats_verwijder IS NULL"
                + "           AND cnt_contract_key = " + cnt_key + ")";
            oRs = Oracle.Execute(sql);
            lsender = oRs("email").Value;
            oRs.Close();
          }
          return lsender;
        },


        //// Levert de "Contract ##KEY## (##LEV##/##OMSCH##) is goedgekeurd" en
        //// "Uw goedkeuring wordt verzocht voor contract ##KEY## (##LEV##/##OMSCH##)" op.
        sendNeedApprovalNotifications: function (cnt_key, approver_arr)
        {
          if (approver_arr == null || approver_arr.length == 0)
              return false;

          // These notifications are now sent on behalf of the system, what might be the local FM organisation
          var lsender = cnt.findSenderForNotifications(cnt_key);

          // notify approver by message & mail as configured in fac_srtnotificatie with CNTAPP
          // putnotificationsrtprio doet geen vertaling van ##LEV##/##OMSCH## (notify_tracking zou dat wel doen) dus doen we het hier zelf maar.
          var omssql = "SELECT fac_srtnotificatie_oms"
                     + "  FROM fac_srtnotificatie"
                     + " WHERE fac_srtnotificatie_code = 'CNTAPP'";
          var oRs = Oracle.Execute(omssql);
          var oms = L(oRs("fac_srtnotificatie_oms").Value, { autolcl: true });
          oRs.Close();

          for (var i = 0; i < approver_arr.length; i++)
          { // Alle fiatteurs een notificatie sturen.
            Oracle.Execute("BEGIN fac.putnotificationsrtprio(NULL, "
                            + approver_arr[i]
                            + ", 'CNTAPP', "
                            + cnt_key
                            + ", cnt.sprintf(" + safe.quoted_sql(oms) + ", " + cnt_key + "), "
                            + "  NULL, NULL, NULL, NULL, 2, "
                            + (lsender? safe.quoted_sql(lsender) : "NULL") + "); END;");
          }

          var sql = "SELECT COUNT(prs_perslid_naam_full) aantal_fiatteurs FROM prs_v_perslid_fullnames_all WHERE prs_perslid_key IN (" + approver_arr.join(",") + ")";
          var oRs = Oracle.Execute(sql);
          var aantal_fiatteurs = oRs("aantal_fiatteurs").Value;
          oRs.Close();
          return L("lcl_cnt_regapprove").format(aantal_fiatteurs);
        },

        cnt_get_afdeling:
          function _cnt_get_afdeling(afd_key) {
            sql = "SELECT " + S("prs_dep_string") + " afdeling"
                + " FROM prs_v_afdeling d"
                + " WHERE d.prs_afdeling_key = " + afd_key;
            var oRs = Oracle.Execute(sql);

            var afdeling = oRs("afdeling").Value;
            oRs.Close();

            var result = { afd_key: afd_key,
                           afdeling: afdeling };

            return result;
          },

        cnt_contract_info: // deze functie mettertijd uitbreiden
           function (cnt_key)
           {
              var sql = "SELECT cnt.cnt_contract_status(cc.cnt_contract_looptijd_van"
                        + "                           , cnt.cnt_getRappeldatum(cc.cnt_contract_key)"
                        + "                           , cnt.cnt_getOpzegdatum(cc.cnt_contract_key)"
                        + "                           , cc.cnt_contract_looptijd_tot) fase_actief"
                        + "     , cc.cnt_contract_status"
                        + "     , cc.cnt_contract_versie"
                        + "     , cc.cnt_contract_kosten"
                        + "     , cc.cnt_contract_termijnkosten"
                        + "     , cc.cnt_contract_termijntermijn"
                        + "     , (SELECT " + lcl.xsqla('cnt_termijn_omschrijving', 'cnt_termijn_key')
                          + "        FROM cnt_termijn"
                          + "       WHERE cnt_termijn_key = cc.cnt_contract_termijntermijn) termijntermijn_oms"
                        + "     , cnt.termijnjaarfactor(cc.cnt_contract_termijntermijn) termijnjaarfactor"
                        + "     , cc.cnt_contract_approved"
                        + "     , COALESCE(cc.cnt_contract_verlenging, -1) cnt_contract_verlenging"
                        + "     , cc.cnt_contract_nummer"
                        + "     , cc.cnt_contract_nummer_intern"
                        + "     , cc.cnt_contract_omschrijving"
                        + "     , cc.cnt_contract_opmerking"
                        + "     , cc.cnt_contract_document"
                        + "     , cc.cnt_contract_korting"
                        + "     , cc.cnt_contract_uurloon"
                        + "     , cc.cnt_contract_looptijd_van"
                        + "     , cc.cnt_contract_looptijd_tot"
                        + "     , cc.prs_contactpersoon_key"
                        + "     , cc.cnt_contract_verwijder"
                        + "     , cc.cnt_contract_locked_user_key"
                        + "     , cc.cnt_contract_locked_date"
                        + "     , cc.bes_bestelopdr_key"
                        + "     , cc.cnt_contract_opzegtermijn"
                        + "     , (SELECT " + lcl.xsqla('cnt_termijn_omschrijving', 'cnt_termijn_key')
                          + "        FROM cnt_termijn"
                          + "       WHERE cnt_termijn_key = cc.cnt_contract_opzegtermijn) opzegtermijn_oms"
                        + "     , cnt.cnt_getOpzegdatum(cc.cnt_contract_key) opzegdatum"
                        + "     , cc.cnt_contract_rappeltermijn"
                        + "     , (SELECT " + lcl.xsqla('cnt_termijn_omschrijving', 'cnt_termijn_key')
                          + "        FROM cnt_termijn"
                          + "       WHERE cnt_termijn_key = cc.cnt_contract_rappeltermijn) rappeltermijn_oms"
                        + "     , cnt.cnt_getRappeldatum(cc.cnt_contract_key) rappeldatum"
                        + "     , cc.cnt_prs_bedrijf_key"
                        + "     , (SELECT prs_bedrijf_naam"
                          + "        FROM prs_bedrijf"
                          + "       WHERE prs_bedrijf_key = cc.cnt_prs_bedrijf_key) bedrijf_naam"
                        + "     , cc.cnt_prs_perslid_key"
                        + "     , (SELECT prs_perslid_naam_full"
                          + "        FROM prs_v_perslid_fullnames_all pf"
                          + "       WHERE pf.prs_perslid_key = cc.cnt_prs_perslid_key) perslid_naam"
                        + "     , cc.prs_dienst_key"
                        + "     , (SELECT " + lcl.xsqla('prs_dienst_omschrijving', 'prs_dienst_key')
                          + "        FROM prs_dienst"
                          + "       WHERE prs_dienst_key = cc.prs_dienst_key) dienst_omschrijving"
                        + "     , cc.cnt_prs_afdeling_key"
                        + "     , (SELECT " + S("prs_dep_string")
                          + "        FROM prs_v_afdeling d"
                          + "       WHERE d.prs_afdeling_key = cc.cnt_prs_afdeling_key) afdeling_naam"
                        + "     , cc.prs_afdeling_key_eig"
                        + "     , (SELECT " + S("prs_dep_string")
                          +"         FROM prs_v_afdeling d"
                          + "       WHERE d.prs_afdeling_key = cc.prs_afdeling_key_eig) afdeling_naam_eig"
                        + "     , cc.prs_perslid_key_beh"
                        + "     , (SELECT prs_perslid_naam_full"
                          + "        FROM prs_v_perslid_fullnames_all pf"
                          + "       WHERE pf.prs_perslid_key = cc.prs_perslid_key_beh) perslid_naam_beh"
                        + "     , cc.prs_perslid_key_eig"
                        + "     , (SELECT prs_perslid_naam_full"
                          + "        FROM prs_v_perslid_fullnames_all pf"
                          + "       WHERE pf.prs_perslid_key = cc.prs_perslid_key_eig) perslid_naam_eig"
                        + "     , cc.ins_discipline_key"
                        + "     ," + lcl.xsqla('cs.ins_discipline_omschrijving','cs.ins_discipline_key')
                        + "     , cc.prs_kostenplaats_key"
                        + "     , (SELECT " + S("prs_kpn_string")
                          + "        FROM prs_kostenplaats k "
                          + "       WHERE k.prs_kostenplaats_key = cc.prs_kostenplaats_key) kostenplaats_naam"
                        + "     , cc.prs_kostensoort_key"
                        + "     , (SELECT prs_kostensoort_oms || '-' || " + lcl.xsqla('prs_kostensoort_opmerking', 'prs_kostensoort_key')
                          + "        FROM prs_kostensoort"
                          + "       WHERE prs_kostensoort_key = COALESCE(cc.prs_kostensoort_key, cs.prs_kostensoort_key)) kostensoort_naam"
                        + "     , dp.cnt_srtcontract_type"
                        + "     , dp.cnt_disc_params_factuurschema"
                        + "     , cc.cnt_contract_mantel_key"
                        + "     , mc.cnt_contract_nummer_intern mantelcontractnummer"
                        + "     , mc.cnt_contract_omschrijving mantelomschrijving"
                        + "     , (SELECT COUNT(*) FROM cnt_contract_plaats ccp WHERE ccp.cnt_contract_key = cc.cnt_contract_key) nnScope"
                        + "     , bdp.bes_disc_params_contract"
                        + "  FROM cnt_contract cc"
                        + "     , cnt_discipline cs"
                        + "     , cnt_disc_params dp"
                        + "     , cnt_contract mc"
                        + "     , bes_disc_params bdp"
                        + " WHERE cc.ins_discipline_key = cs.ins_discipline_key"
                        + "   AND cc.ins_discipline_key = dp.cnt_ins_discipline_key"
                        + "   AND cc.cnt_contract_mantel_key = mc.cnt_contract_key (+)"
                        + "   AND cc.ins_discipline_key = bdp.bes_disc_params_cnt_disckey(+)"
                        + "   AND cc.cnt_contract_key = " + cnt_key;
              var oRs = Oracle.Execute(sql);
              var result = { fase_actief: oRs("fase_actief").Value,
                             contract_status: oRs("cnt_contract_status").Value,
                             contract_status_str: cnt.getcntstatustext(oRs("cnt_contract_status").Value),
                             versie: oRs("cnt_contract_versie").Value,
                             kosten: oRs("cnt_contract_kosten").Value? oRs("cnt_contract_kosten").Value : 0,
                             termijnkosten: oRs("cnt_contract_termijnkosten").Value,
                             termijntermijn: oRs("cnt_contract_termijntermijn").Value,
                             termijntermijn_oms: oRs("termijntermijn_oms").Value,
                             termijnjaarfactor: oRs("termijnjaarfactor").Value,
                             approved: oRs("cnt_contract_approved").Value? oRs("cnt_contract_approved").Value : 0,
                             verlenging: oRs("cnt_contract_verlenging").Value,
                             nummer: oRs("cnt_contract_nummer").Value,
                             nummer_intern: oRs("cnt_contract_nummer_intern").Value,
                             omschrijving: oRs("cnt_contract_omschrijving").Value,
                             opmerking: oRs("cnt_contract_opmerking").Value,
                             document: oRs("cnt_contract_document").Value,
                             korting: oRs("cnt_contract_korting").Value,
                             uurloon: oRs("cnt_contract_uurloon").Value,
                             looptijd_van: new Date(oRs("cnt_contract_looptijd_van").Value),
                             looptijd_tot: new Date(oRs("cnt_contract_looptijd_tot").Value),
                             contactpersoon_key: oRs("prs_contactpersoon_key").Value,
                             verwijderdatum: oRs("cnt_contract_verwijder").Value,
                             locked_user_key: oRs("cnt_contract_locked_user_key").value,
                             locked_date: new Date(oRs("cnt_contract_locked_date").value),
                             bestelopdr_key: oRs("bes_bestelopdr_key").Value,
                             opzegtermijn: oRs("cnt_contract_opzegtermijn").Value,
                             opzegtermijn_oms: oRs("opzegtermijn_oms").Value,
                             opzegdatum: new Date(oRs("opzegdatum").Value),
                             rappeltermijn: oRs("cnt_contract_rappeltermijn").Value,
                             rappeltermijn_oms: oRs("rappeltermijn_oms").Value,
                             rappeldatum: new Date(oRs("rappeldatum").Value),
                             bedrijf_key: oRs("cnt_prs_bedrijf_key").Value,
                             bedrijf_naam: oRs("bedrijf_naam").Value,
                             perslid_key: oRs("cnt_prs_perslid_key").Value,
                             perslid_naam: oRs("perslid_naam").Value,
                             prs_dienst_key: oRs("prs_dienst_key").Value,
                             dienst_omschrijving: oRs("dienst_omschrijving").Value,
                             afdeling_key: oRs("cnt_prs_afdeling_key").Value,
                             afdeling_naam: oRs("afdeling_naam").Value,
                             afdeling_key_eig:  oRs("prs_afdeling_key_eig").Value,
                             afdeling_naam_eig: oRs("afdeling_naam_eig").Value,
                             perslid_key_beh: oRs("prs_perslid_key_beh").Value,
                             perslid_naam_beh: oRs("perslid_naam_beh").Value,
                             perslid_key_eig: oRs("prs_perslid_key_eig").Value,
                             perslid_naam_eig: oRs("perslid_naam_eig").Value,
                             discipline_key: oRs("ins_discipline_key").Value,
                             discipline_omschrijving: oRs("ins_discipline_omschrijving").Value,
                             prs_kostenplaats_key: oRs("prs_kostenplaats_key").Value,
                             kostenplaats_naam: oRs("kostenplaats_naam").Value,
                             prs_kostensoort_key: oRs("prs_kostensoort_key").Value,
                             kostensoort_naam: oRs("kostensoort_naam").Value,
                             srtcontract_type: oRs("cnt_srtcontract_type").Value,
                             hasfactuurschema: oRs("cnt_disc_params_factuurschema").Value == 1,
                             mantel_key: oRs("cnt_contract_mantel_key").Value,
                             mantelcontractnummer: oRs("mantelcontractnummer").Value,
                             mantelomschrijving: oRs("mantelomschrijving").Value,
                             nnScope: oRs("nnScope").Value,
                             isAbonnement: oRs("bes_disc_params_contract").Value == 1
                           };
              oRs.Close()

              if (result.locked_user_key)
              {
                var expire = new Date;
                expire.setMinutes(expire.getMinutes() - S("mld_locked_expire"));
                if (result.locked_date < expire)
                { // In de database laten we het lock gewoon staan ter analyse achteraf welke locks niet worden vrijgegeven.
                  result.locked_user_key = null;
                  result.locked_date = null;
                }
              }

              return result;
           },

       getvervangentext:
           // Lever de string behorend bij prioriteit p
           function (p) {
              var ps = "??";
              switch (p) {
                  case -1: { ps = L("lcl_unknown"); break; }
                  case  0: { ps = L("lcl_No"); break; }
                  case  1: { ps = L("lcl_Yes"); break; }
              }
              return ps;
           },

        func_enabled_contract: // Wat mag ik zoal op dit specifiek contract?
          function _func_enabled_contract(pcnt_contract_key, cnt_info) // cnt_info mag je optioneel alvast meegeven
          {
            if (!cnt_info)
              cnt_info = cnt.cnt_contract_info(pcnt_contract_key); // Haal gegevens van het contract op.

            // Alleen personen met rechten op de locaties van de contracten mogen goedkeuren.
            // Daarvoor hebben we de locatie van de contracten nodig.
            var sql_cntloc = cnt.getCntLocationsSql();
            var sql_loc = "SELECT alg_locatie_key"
                        + "  FROM (" + sql_cntloc + ") cntloc"
                        + " WHERE cntloc.cnt_contract_key = " + pcnt_contract_key;
            var oRs_loc = Oracle.Execute(sql_loc);
            var loc_arr = [];
            while (!oRs_loc.eof)
            {
              var ors_loc_key = oRs_loc("alg_locatie_key").Value;
              if (ors_loc_key) // Geen lege waarden toevoegen!
                loc_arr.push(ors_loc_key);
              oRs_loc.MoveNext();
            }
            oRs_loc.Close();

            var afd_key = cnt_info.afdeling_key_eig; // te controleren
            if (user == cnt_info.perslid_key_eig || user == cnt_info.perslid_key_beh)
                afd_key = null; // dan niet moeilijk doen over de afdeling

            // Als een contract geen locaties heeft dan heb je alle rechten op dat contract.
            var cresult = user.func_enabled2("CNT",
                                                { ins_discipline_key: cnt_info.discipline_key,
                                                  loc_key: loc_arr,
                                                  afd_key: afd_key,
                                                  checkOptimistic: false, // checkOptimistic
                                                  isOptional: true
                                                });
            var actief = cnt_info.contract_status == 0;
            var inactief = cnt_info.contract_status == 1;
            var nieuw = cnt_info.contract_status == 2;
            var terGoedkeuring = cnt_info.contract_status == 3;
            var isVerlengbaar = (new Date(cnt_info.opzegdatum) > new Date() && (cnt_info.verlenging < 0 || (cnt_info.verlenging & 2) != 2)); // bit 2 hoog = niet verlengbaar
            cresult.cnt_info = cnt_info; // teruggeven
            cresult.mijncontract = cnt_info.perslid_key_beh == user_key || cnt_info.perslid_key_eig == user_key;

            cresult.canMANread = cresult.canRead("WEB_CNTMAN");
            cresult.canMANwrite = cresult.canWrite("WEB_CNTMAN");
            cresult.canUSEread = cresult.canRead("WEB_CNTUSE") || cresult.mijncontract;
            cresult.canUSEwrite = cresult.canWrite("WEB_CNTUSE");
            cresult.canReadAny = cresult.canUSEread || cresult.canMANread;

            cresult.canGoedkeur1 = cresult.canWrite("WEB_CNTGO1") &&                                                   // Heb ik de rechten om goed te keuren op dit niveau 1?
                                   terGoedkeuring &&                                                                   // Moet het contract gekeurd worden (juiste status)
                                   ((S("cnt_approval_all") == 0 && cnt_info.kosten >= S("cnt_contract_limit1")) ||     // Zijn de kosten hoger als de limiet
                                    (S("cnt_approval_all") == 1 && cnt_info.kosten <= S("cnt_contract_limit2"))) &&    // Zijn de kosten onder mijn limiet om volledig goed te keuren
                                   cnt_info.approved <= S("cnt_contract_limit1");                                      // Welke goedkeur? 1, 2 of 3?
            cresult.canGoedkeur2 = cresult.canWrite("WEB_CNTGO2") &&
                                   terGoedkeuring &&
                                   // Setting cnt_approval_all is
                                   // 0: Het approved bedrag is eigen bestellimiet of vorige goedkeur niveau rechten heb ik al (dan direct niveau hoger)
                                   // 1: Het approved bedrag is kleiner of gelijk aan eigen bestellimiet
                                   ((S("cnt_approval_all") == 0 && cnt_info.kosten >= S("cnt_contract_limit2") && (cnt_info.approved == S("cnt_contract_limit2") || cresult.canGoedkeur1)) ||
                                    (S("cnt_approval_all") == 1 && cnt_info.kosten <= S("cnt_contract_limit3") && cnt_info.approved <= S("cnt_contract_limit2")));
            cresult.canGoedkeur3 = cresult.canWrite("WEB_CNTGO3") &&
                                   terGoedkeuring &&
                                   ((S("cnt_approval_all") == 0 && cnt_info.kosten >= S("cnt_contract_limit3") && (cnt_info.approved == S("cnt_contract_limit3") || cresult.canGoedkeur2)) ||
                                    (S("cnt_approval_all") == 1 && cnt_info.kosten <= S("cnt_contract_limit4") && cnt_info.approved <= S("cnt_contract_limit3")));
            cresult.canGoedkeur4 = cresult.canWrite("WEB_CNTGO4") &&
                                   terGoedkeuring &&
                                   ((S("cnt_approval_all") == 0 && cnt_info.kosten >= S("cnt_contract_limit4") && (cnt_info.approved == S("cnt_contract_limit4") || cresult.canGoedkeur3)) ||
                                    (S("cnt_approval_all") == 1 && cnt_info.kosten <= S("cnt_contract_limit5") && cnt_info.approved <= S("cnt_contract_limit4")));
            cresult.canGoedkeur5 = cresult.canWrite("WEB_CNTGO5") &&
                                   terGoedkeuring &&
                                   ((S("cnt_approval_all") == 0 && cnt_info.kosten >= S("cnt_contract_limit5") && (cnt_info.approved == S("cnt_contract_limit5") || cresult.canGoedkeur4)) ||
                                    (S("cnt_approval_all") == 1 && cnt_info.kosten > S("cnt_contract_limit5") && cnt_info.approved <= S("cnt_contract_limit5"))) &&
                                   cnt_info.kosten > cnt_info.approved;
            cresult.forApproval = nieuw && cresult.canUSEwrite;
            cresult.canReject = cresult.canGoedkeur1 || cresult.canGoedkeur2 || cresult.canGoedkeur3 || cresult.canGoedkeur4 || cresult.canGoedkeur5;

            // Ik mag in principe alleen de allernieuwste versie splitten of bewerken
            var csql = "SELECT cnt.getnieuwsteversiekey(" + pcnt_contract_key + ") newkey FROM DUAL";
            var coRs = Oracle.Execute(csql);
            var newestkey = coRs("newkey").Value;
            coRs.Close();
            // Met CNTMAN rechten kan men alleen de laatste versie van een contract wijzigen.
            // Met CNTMSU rechten kan men alle versies van een contract wijzigen ook oudere versies (volgens AAEN#20694).
            // Met CNTMSU rechten kan je een contract inactiveren (sluiten)
            // Met CNTMSU (Super user) mag je dus net iets meer als met CNTMAN rechten.
            // Als het approve mechanisme actief is (S("cnt_contract_approval") == 1) dan kan ik ook met CNTUSE rechten wijzigen. Daarna volgt altijd nog het goedkeuren.
            // PAS OP!!!: CNTMSU is disciplineloos dus niet in cresult! Daardoor zijn cresult.canWrite("WEB_CNTMSU") en cresult.canRead("WEB_CNTMSU") altijd false.
            // Van een abonnement contract kan nooit een nieuwe versie worden gemaakt.

            // Met welke rechten mogen welke acties uitgevoerd worden?
            // Voor status 2 en 3 is het approval mechanisme actief en geldt AUTOMATISCH cnt_contract_approval = 1.
            // Voor de helderheid mag je met CNTMAN rechten niets in de status Nieuw(2) en Ter goedkeuring(3).
            // Cijfers 0 t/m 3 zijn statussen, Nieuwste = Alleen bij de nieuwste versie, approval = Setting cnt_contract_approval.
            //                        CNTUSE                                                   CNTMAN                                 CNTMSU
            // Splitsen:              (0, 3) + approval = 1 + nieuwste                         (0, 1) + nieuwste                      ---
            // Wijzigen alg geg:      (2, 3) + nieuwste                                        (0, 1) + nieuwste                      cnt_inactivate_mode = 0, CNTMAN + (cnt_inactivate_mode = 1)
            //          flex:         (0, 2, 3) + approval = 1 + >=100 + nieuwste              (0, 1) + nieuwste + <=100              ---
            // Wijzigen abo:          ((0 + beheerder), 2, 3) + verlengbaar                    0 + verlengbaar                        ---
            // Delete fase 0:         2, 3                                                     (0, 1)                                 cnt_inactivate_mode = 0
            //        fase 1 t/m 4:   2, 3                                                      ---                                   ---
            // Inactivate/Sluiten     CNTMSU + 0 +  cnt_inactivate_mode = 0                    CNTMSU + 0 + cnt_inactivate_mode = 1   Zie kolomen CNTUSE en CNTMAN

            var haveCNTMSUrights = user.checkAutorisation("WEB_CNTMSU", true) != null; // Pas op: disciplineloos dus niet in cresult!
            cresult.canChangeFlex = (((actief || inactief) && cresult.canMANwrite) ||
                                     ((!inactief) && S("cnt_contract_approval") == 1 && cresult.canUSEwrite)) &&
                                    (pcnt_contract_key == newestkey);
            cresult.canSplit = cresult.canChangeFlex &&
                               !cnt_info.isAbonnement &&
                               !nieuw;
            var canChangeAbonnement = cnt_info.isAbonnement &&
                                       isVerlengbaar &&
                                       ((actief && cresult.canMANwrite) ||
                                        (cresult.mijncontract && actief) ||
                                        ((nieuw || terGoedkeuring) && cresult.canUSEwrite));
            cresult.canChange = (cresult.canChangeFlex && !cnt_info.isAbonnement) ||
                                (haveCNTMSUrights && (S("cnt_inactivate_mode") == 0 || (S("cnt_inactivate_mode") == 1 && cresult.canMANwrite))) ||
                                canChangeAbonnement;
            cresult.canChangeAlg = cresult.canChange &&
                                   !(actief && cresult.canUSEwrite && !cresult.canMANwrite && !haveCNTMSUrights); // Alleen nog status Actief(0) uitsluiten bij ALLEEN CNTUSE rechten (zie overzicht hierboven).
            cresult.canChangeKosten = (cresult.canMANwrite ||
                                       ((nieuw || terGoedkeuring) && cresult.canUSEwrite)) &&
                                      !cnt_info.isAbonnement;
            if (S("cnt_scopeverdeling") == 1 && cnt_info.nnScope > 0)
                cresult.canChangeKosten = false; // Invullen doe je bij de scope verdeling
            // Inactiveren contract met WEB_CNTMAN/WEB_CNTUSE read rechten and WEB_CNTMSU rechten (cnt_inactivate_mode = 0) of met extra WEB_CNTMAN write rechten (cnt_inactivate_mode = 1)
            cresult.canInactivate = (cresult.canUSEread || cresult.canMANread) &&
                                    haveCNTMSUrights &&
                                    (S("cnt_inactivate_mode") == 0 || (S("cnt_inactivate_mode") == 1 && cresult.canMANwrite)) &&
                                    actief;
            // Ik kan verlengen als het een abonnement contract betreft, als ik de contract beheerder (cnt_info.perslid_key_beh) ben en als ik WEB_CNTUSE of WEB_CNTMAN schrijf rechten heb.
            // MGE: als ik contractbeheerder ben heb ik toch automatisch WEB_CNTUSE rechten?
            cresult.canVerlengen = canChangeAbonnement;
            cresult.canReadNotes = (cresult.canUSEread || cresult.canMANread);
            cresult.canWriteNotes = cresult.canReadNotes;

            cresult.canDelete = ((nieuw || terGoedkeuring) && cresult.canUSEwrite);
            cresult.canChangeSrt = haveCNTMSUrights;
            if (cnt_info.fase_actief == 0)  // Nu - Ingangsdatum (voor Ingangsdatum)
              cresult.canDelete = cresult.canDelete ||
                                  ((actief || inactief) && cresult.canMANwrite) ||
                                  (haveCNTMSUrights && S("cnt_inactivate_mode") == 0);

            var sql = "SELECT count(*)"
                    + "  FROM fin_factuur"
                    + " WHERE fin_factuur_verwijder IS NULL"
                    + "   AND cnt_contract_key = " + pcnt_contract_key;
            var oRs = Oracle.Execute(sql);
            cresult.hasFactuur = (oRs(0).value > 0);
            oRs.Close();
            cresult.canDelete = cresult.canDelete && !cresult.hasFactuur; // Contracten met facturen mogen nooit verwijderd worden.

            return cresult;
          },

        func_enabled_cnt: // Wat mag ik zoal voor deze specifieke discipline?
          function _func_enabled_cnt(pdiscipline_key)
          {
            var cresult = user.func_enabled2("CNT",
                                             { ins_discipline_key: pdiscipline_key,
                                               alg_key: -1, // Er is nog geen contract key bekend en dus ook geen loc_key/alg_key. Anders was cnt.func_enabled_contract(cnt_key) wel aangeroepen.
                                               prs_key: user_key, // key_eig, // TODO: Vind de juiste perslid. Je hebt prs_afdeling_key_eig
                                               checkOptimistic: false, // checkOptimistic
                                               isOptional: true
                                             });

            cresult.canMANread = cresult.canRead("WEB_CNTMAN");
            cresult.canMANwrite = cresult.canWrite("WEB_CNTMAN");
            cresult.canUSEread = cresult.canRead("WEB_CNTUSE") || cresult.mijncontract;
            cresult.canUSEwrite = cresult.canWrite("WEB_CNTUSE");
            cresult.canReadAny = cresult.canUSEread || cresult.canMANread;

            return cresult;
          },


        getcntmutatiestatustext:
          function(p)
          {
            var statustekst = "??";
            switch (p) { // grofweg op volgorde timeline
                case 0: { statustekst = L("lcl_cnt_mutatie_vervallen"); break; }
                case 1: { statustekst = L("lcl_cnt_mutatie_open"); break; }
                case 2: { statustekst = L("lcl_cnt_mutatie_concept"); break; }
                case 3: { statustekst = L("lcl_cnt_mutatie_ontvangen_ok"); break; }
                case 4: { statustekst = L("lcl_cnt_mutatie_ontvangen_nok"); break; }
                case 5: { statustekst = L("lcl_cnt_mutatie_voltooid"); break; }
                case 6: { statustekst = L("lcl_cnt_mutatie_geexporteerd"); break; }
            }
            if (Session("logging") > 0)
              statustekst += " (" + String(p) + ")";
            return statustekst;
          },

          lock: function (cnt_key)
          {
            var sql = "UPDATE cnt_contract"
                    + "   SET cnt_contract_locked_user_key = " + user_key
                    + "     , cnt_contract_locked_date = SYSDATE"
                    + " WHERE cnt_contract_key = " + cnt_key;
            Oracle.Execute(sql);
          },

          unlock: function (cnt_key)
          {
            var sql = "UPDATE cnt_contract"
                    + "   SET cnt_contract_locked_user_key = NULL"
                    + "     , cnt_contract_locked_date = SYSDATE"
                    + " WHERE cnt_contract_key = " + cnt_key
                    + "   AND cnt_contract_locked_user_key = " + user_key; // Alleen als we zelf het lock hadden
            Oracle.Execute(sql);
          },

        getLocationSql:
          function(select_loc_keys, alias)
          { // De select_loc_keys parameter is een SELECT string: SELECT alg_locatie_key FROM alg_locatie xx WHERE UPPER (xx.alg_locatie_omschrijving) LIKE '%XXXXXXXXXX%'.
            sql = " cnt_contract.cnt_contract_key IN (SELECT cnt_contract_key"
                + "                                     FROM cnt_v_aanwezigcontract_plaats"
                + "                                    WHERE (cnt_alg_plaats_code = 'L'"
                + "                                           AND cnt_alg_plaats_key IN (" + select_loc_keys + "))"
                + "                                       OR ((cnt_alg_plaats_code = 'G'"
                + "                                            AND cnt_alg_plaats_key IN (SELECT alg_gebouw_key"
                + "                                                                         FROM alg_v_aanweziggebouw"
                + "                                                                        WHERE alg_locatie_key IN (" + select_loc_keys + ")))"
                + "                                        OR (cnt_alg_plaats_code = 'T'"
                + "                                            AND cnt_alg_plaats_key IN (SELECT alg_terreinsector_key"
                + "                                                                         FROM alg_v_aanwezigterreinsector"
                + "                                                                        WHERE alg_locatie_key IN (" + select_loc_keys + "))))"
                + "                                   UNION"
                + "                                   SELECT cnt_contract_key"
                + "                                     FROM cnt_v_aanwezigcontract_object co"
                + "                                        , ins_v_aanwezigdeel ad"
                + "                                    WHERE cnt_ins_deel_key = ad.ins_deel_key"
                + "                                      AND ad.ins_alg_locatie_key IN (" + select_loc_keys + ")"
                + "                                   UNION"
                + "                                   SELECT cnt_contract_key"
                + "                                     FROM cnt_v_contract_locatie_geg cl"
                + "                                    WHERE alg_locatie_key IN (" + select_loc_keys + "))";

            return sql;
          }

      }

%>
