<%
/*
     $Revision$
     $Id$

    File:               fac_fiattering_list.inc
    Description:        Overzicht fiatteringsverzoeken
    Parameters:
    Context:            Gemeenschappelijke code van FAC/fac_fiattering_list.asp en PDA/fiat_list.asp

*/

function getSqlFiatBes(fiatstatus, prsKeys, params)
{
   var v_sql_bestelling_bedrag = "(SELECT b.bes_bestelling_key"
                              + "      , SUM(bi.bes_bestelling_item_prijs * bi.bes_bestelling_item_aantal) bestelling_bedrag"
                              + "   FROM bes_bestelling b"
                              + "      , bes_bestelling_item bi"
                              + "  WHERE b.bes_bestelling_key = bi.bes_bestelling_key"
                              + (fiatstatus == "open"
                                ? "    AND b.bes_bestelling_status = 2"      // Te fiatteren
                                : (fiatstatus == "close"
                                  ? "    AND b.bes_bestelling_status != 2"   // Gefiatteerd
                                  : "    AND b.bes_bestelling_status = 1")) // Afgewezen
                              + "  GROUP BY b.bes_bestelling_key)";

  // Kan ik zelf fiatteren?: true:  totaalbedrag <= can_selfapprove
  //                         false  totaalbedrag > can_selfapprove
  // TODO: Het totaalbedrag zou eigenlijk berekend moeten worden via staffelprijzen en staffelkortingen.
  //       Dit zou een databasefunctie moeten worden.
  //       Tot nu toe gebruikt geen enkele klant staffelprijzen en staffelkortingen.
  //       Dus voor nu kan totaalbedrag berekend worden via de som van aantal maal prijs
  var totaalbedrag = "(SELECT SUM(i1.bes_bestelling_item_aantal * COALESCE(i1.bes_bestelling_item_prijs, 0))"
                   + "   FROM bes_bestelling_item i1"
                   + "  WHERE i1.bes_bestelling_key = b.bes_bestelling_key)";

  // Deze mag/hoeft niet meer te fiatteren
  var exclude_fiatter = " COALESCE(b.bes_bestelling_fiat_user, "
                      + " CASE"
                      + " WHEN " + totaalbedrag + " <= " + S("can_selfapprove")
                      + " THEN -1"
                      + " ELSE b.prs_perslid_key"
                      + " END)";

  var fiatteur = " (SELECT p2.prs_perslid_naam_full"
               + "  FROM prs_v_perslid_fullnames_all p2"
               + " WHERE p2.prs_perslid_key ="
               + (fiatstatus == "open"
                 ? " prs.getkpverantwoordelijke (b.prs_kostenplaats_key, " + S("prs_approvemethod") + ", " + exclude_fiatter + "))" // Open. Toon wie de fiatteur is.
                 : " b.bes_bestelling_fiat_user)") // Gefiatteerd en afgewezen. Toon wie dat is geweest. (Afwijzer werd voorheen niet opgeslagen, nu wel)

  // Tijdens het uiteindelijk fiatteren wordt gekeken afhankelijk van totaalbedrag of er wellicht na kostenplaatsverantwoordelijke ook nog door kostenplaatsgroepverantwoordelijke moet worden gefiatteerd.
  var sql = " SELECT to_char(b.bes_bestelling_key) aanvraagnummer"
          + "      , b.bes_bestelling_datum datum"
          + "      , p.prs_perslid_naam_full"
          + "      , prijs.bestelling_bedrag bedrag"
          + "      , 'BES' module"
          + "      , 'mld_typeopdr_omschrijving' type"
          + ",       " + safe.quoted_sql(fiatstatus) + " fiatstatus"
          + "      , b.bes_bestelling_key request_key"
          + "      , b.bes_bestelling_status statuskey"
          + "      , b.bes_bestelling_datum sortdate"
          + "      , " + lcl.xsql('td.ins_discipline_omschrijving','td.ins_discipline_key') +" categorie"
          + "      , " + fiatteur + " fiatteur"
          + "      , bes_bestelling_parentkey"
          + "      , NULL prefix"
          + "      , NULL uitvoerende"
          + "      , l.alg_locatie_omschrijving || ' (' || l.alg_locatie_code || ')' locatie"
          + "      , NULL gebouw"
          + "      , NULL terrein"
          + "   FROM prs_v_perslid_fullnames_all p"
          + "      , bes_bestelling b"
          + "      , " + v_sql_bestelling_bedrag + " prijs"
          + "      , bes_bestelling_item bi"
          + "      , bes_srtdeel sd"
          + "      , bes_srtgroep sg"
          + "      , ins_tab_discipline td"
          + "      , prs_kostenplaats k"
          + "      , " + fac.getVSqlVerantwoordelijk(prsKeys) + "ver"
          + (fiatstatus != "open"
            ? "    , fac_tracking ft"
              + "  , fac_srtnotificatie fno"
            : "")
          + "      , mld_v_afleveradres m"
          + "      , alg_locatie l"
          + (params.bld_key
            ? ", alg_gebouw g"
            : "")
          + "  WHERE bi.bes_bestelling_key = b.bes_bestelling_key"
          + "    AND prijs.bes_bestelling_key = b.bes_bestelling_key"
          + "    AND sd.bes_srtdeel_key = bi.bes_srtdeel_key"
          + "    AND sd.bes_srtgroep_key = sg.bes_srtgroep_key"
          + "    AND sg.ins_discipline_key = td.ins_discipline_key"
          + "    AND p.prs_perslid_key = b.prs_perslid_key"
          + "    AND b.prs_kostenplaats_key = k.prs_kostenplaats_key"
          + "    AND k.prs_kostenplaats_key = ver.prs_kostenplaats_key(+)"
          + "    AND b.mld_adres_key_lev = m.mld_adres_key" // Afleveradres is altijd verplicht
          + "    AND m.alg_locatie_key = l.alg_locatie_key(+)"
          + (fiatstatus == "open"
            ? " AND b.bes_bestelling_status IN (2, 3)" // nieuw, eerste keer gefiatteerd
              + " AND b.bes_bestelling_status = 2"
/* A1 */              + " AND ((bes_bestelling_fiat_user IS NULL AND"
              + "       prs.getkpverantwoordelijke (b.prs_kostenplaats_key, " + S("prs_approvemethod") + ", " + exclude_fiatter + ") IN (" + prsKeys + ")" + ")"
/* A2 */              + "     OR (bes_bestelling_fiat_user IS NOT NULL AND"
              + "         ver.prs_perslid_key IN (" + prsKeys + ")" + "))"
            : " AND ft.fac_tracking_refkey = b.bes_bestelling_key"
              + " AND ft.fac_srtnotificatie_key = fno.fac_srtnotificatie_key"
              + " AND fno.fac_srtnotificatie_code IN (" + (fiatstatus == "close"? "'BESFIT', 'BESACP'" : "'BESREJ'") + ")"
              + " AND ft.prs_perslid_key IN (" + prsKeys + ")")
          + (fiatstatus == "open" // Als nog gefiatteerd moet worden door kostenplaatsgroep verantwoordelijke en ik heb net gefiatteerd dan wil ik die niet meer zien (want dan was het wel in 1 keer goedgekeurd).
            ? " AND (bes_bestelling_fiat_user <> " + user_key + " OR bes_bestelling_fiat_user IS NULL)" // Geldt alleen voor nog te fiatteren bestellingen, zie canApprove bij bestellingen. Dan heb je toch de rechten niet.
            : "") // Door mij goedgekeurde of afgekeurde bestellingen hoef ik niet meer af te melden maar wil ik nog wel zien
          + (params.bld_key
            ? " AND l.alg_locatie_key = g.alg_locatie_key AND g.alg_gebouw_key = " + params.bld_key
            : "")
          + (params.loc_key_arr && !params.bld_key
            ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
            : "")
          + " GROUP BY b.bes_bestelling_key"
          + "        , b.bes_bestelling_datum"
          + "        , p.prs_perslid_naam_full"
          + "        , b.bes_bestelling_status"
          + "        , prijs.bestelling_bedrag"
          + "        , "+ lcl.xsql('td.ins_discipline_omschrijving','td.ins_discipline_key')
          + "        , b.prs_kostenplaats_key"
          + "        , b.prs_perslid_key"
          + "        , b.bes_bestelling_fiat_user"
          + "        , bes_bestelling_parentkey"
          + "        , l.alg_locatie_omschrijving"
          + "        , l.alg_locatie_code";
  return sql;
}

function getCntScope(params)
{
  return " SELECT l.alg_locatie_key loc"
       + "      , " + S("alg_loc_string") + " loc_oms"
       + "      , NULL gebter"
       + "      , NULL gebter_oms"
       + "      , cp.cnt_contract_key cnt_key"
       + "   FROM cnt_contract_plaats cp"
       + "      , 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"
       + (params.loc_key_arr
         ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
         : "")
       + " UNION"
       + " SELECT l.alg_locatie_key loc"
       + "      , " + S("alg_loc_string") + " loc_oms"
       + "      , g.alg_gebouw_key gebter"
       + "      , g.alg_gebouw_omschrijving gebter_oms"
       + "      , cp.cnt_contract_key cnt_key"
       + "   FROM cnt_contract_plaats cp"
       + "      , 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"
       + (params.bld_key
         ? " AND g.alg_gebouw_key = " + params.bld_key
         : (params.loc_key_arr
           ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
           : ""))
       + " UNION"
       + " SELECT l.alg_locatie_key loc"
       + "      , " + S("alg_loc_string") + " loc_oms"
       + "      , t.alg_terreinsector_key gebter"
       + "      , t.alg_terreinsector_omschrijving gebter_oms"
       + "      , cp.cnt_contract_key cnt_key"
       + "   FROM cnt_contract_plaats cp"
       + "      , 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"
       + (params.loc_key_arr
         ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
         : "");
}

function getCntGebonden(params)
{
  var filterlocatie = (params.dist_key ? true : false);
  var filter_gebonden = "";
  if (filterlocatie)
  {
    if (params.cnt)
      filter_gebonden = " c.cnt_contract_key = cp.cnt_contract_key";
    if (params.bld_key)
    {
      // Filteren op gebouw levert alleen de gebouwgebonden contracten.
      filter_gebonden += (params.cnt? " AND" : "") + " cp.cnt_alg_plaats_key = " + params.bld_key
                       + " AND cp.cnt_alg_plaats_code = 'G'";
    }
    else if (params.loc_key_arr)
    {
      // Filteren op locatie moet zowel de locatie gebonden contracten opleveren
      // als de gebouwgebonden contracten binnen deze locatie.
      var locaties = params.loc_key_arr.join(","); // De geselecteerde locatie, of alle locaties in het geselecteerde district.
      var gebouwen = "";
      sql_f = "SELECT alg_gebouw_key"
            + "  FROM alg_gebouw"
            + " WHERE alg_locatie_key IN (" + locaties + ")";
      var bld_key_arr = [];
      var oRsf = Oracle.Execute(sql_f);
      if (!oRsf.eof)
      {
        while (!oRsf.eof)
        {
          bld_key_arr.push(oRsf("alg_gebouw_key").Value);
          oRsf.moveNext();
        }
        oRsf.Close();
        gebouwen = bld_key_arr.join(",");
      }
      filter_gebonden += (params.cnt? " AND" : "") + " (  (cp.cnt_alg_plaats_code = 'L' AND cp.cnt_alg_plaats_key IN (" + locaties + "))"
               + (gebouwen ? " OR (cp.cnt_alg_plaats_code = 'G' AND cp.cnt_alg_plaats_key IN (" + gebouwen + "))" : "")
                           + " )";
    }
  }
  return filter_gebonden;
}

function getSqlFiatCnt(fiatstatus, prsKeys, params)
{ // Contracten: Goedkeuren tot de drie limieten
  var scope = getCntScope(params);

  var loc_count = "(SELECT COUNT(loc) FROM theScope scope WHERE scope.cnt_key = c.cnt_contract_key)";
  var loc_oms = "(SELECT loc_oms FROM theScope scope WHERE scope.cnt_key = c.cnt_contract_key)";
  var gebter_oms = "(SELECT gebter_oms FROM theScope scope WHERE scope.cnt_key = c.cnt_contract_key)";
  var filterlocatie = (params.dist_key ? true : false);
  params.cnt = true;
  var filter_gebonden = getCntGebonden(params);

  function getSqlLocAut(lfunctie_code)
  {
    var sql_cntloc = cnt.getCntLocationsSql();
    return " AND EXISTS(SELECT g.prs_perslid_key"
         + "              FROM fac_v_webgebruiker g"
         + "                 , fac_functie f"
         + "                 , cnt_contract c1"
         + "                 , (" + sql_cntloc + ") cntloc"
         + "             WHERE g.fac_functie_key = f.fac_functie_key"
         + "               AND g.ins_discipline_key = c.ins_discipline_key"
         + "               AND g.prs_perslid_key IN (" + prsKeys + ")"
         + "               AND f.fac_functie_code = " + safe.quoted_sql(lfunctie_code)
         + "               AND c1.cnt_contract_key = cntloc.cnt_contract_key(+)"
         + "               AND c1.cnt_contract_key = c.cnt_contract_key"
         + "               AND (g.fac_gebruiker_alg_level_write = -1"
         + "                    OR (g.fac_gebruiker_alg_level_write < 9"
         + "                        AND (cntloc.alg_locatie_key IN (SELECT alg_locatie_key"
         + "                                                         FROM fac_v_my_locations"
         + "                                                        WHERE prs_perslid_key IN (" + prsKeys + ")"
         + "                                                          AND niveau = fac_gebruiker_alg_level_write)"
         + "                             OR cntloc.alg_locatie_key IS NULL)" // Op contracten zonder locatie(s) heeft iedereen rechten.
         + ")))";
  }


  var sql = " WITH theScope AS (" + scope + ")"
          + " SELECT DISTINCT TO_CHAR (c.cnt_contract_nummer_intern)||NVL2(cnt_contract_versie,'.'||cnt_contract_versie,'') aanvraagnummer"
          + "      , c.cnt_contract_aanmaak datum"
          + "      , p.prs_perslid_naam_full"
          + "      , c.cnt_contract_kosten bedrag"
          + "      , 'CNT' module"
          + "      , 'mld_typeopdr_omschrijving' type"
          + "      , " + safe.quoted_sql(fiatstatus) + " fiatstatus"
          + "      , c.cnt_contract_key request_key"
          + "      , c.cnt_contract_status statuskey"
          + "      , c.cnt_contract_aanmaak sortdate"
          + "      , "+ lcl.xsql('td.ins_discipline_omschrijving','td.ins_discipline_key') +" categorie"
          + (fiatstatus == "open"
            ? "    , CASE"
              + "    WHEN COALESCE (c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit1")
              + "    THEN '1'"
              + "    WHEN COALESCE (c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit2")
              + "    THEN '2'"
              + "    WHEN COALESCE (c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit3")
              + "    THEN '3'"
              + "    WHEN COALESCE (c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit4")
              + "    THEN '4'"
              + "    WHEN COALESCE (c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit5")
              + "    THEN '5'"
              + "    ELSE '0'"
              + "    END fiatteur"
            : "    , ' '")
          + "      , NULL bes_bestelling_parentkey"
          + "      , NULL prefix"
          + "      , NULL uitvoerende"
          + "      , CASE " + loc_count
            + "      WHEN 0"
            + "      THEN NULL"
            + "      WHEN 1"
            + "      THEN " + loc_oms
            + "      ELSE " + safe.quoted_sql(L("lcl_cnt_locatie_m")) + " || "
            + "           ' (' || TO_CHAR(" + loc_count + ") || ')'"  // Er kunnen meerdere locaties zijn (contract scope)
            + "      END locatie"
          + "      , CASE " + loc_count
            + "      WHEN 1"
            + "      THEN TO_CHAR (" + gebter_oms + ")"
            + "      ELSE NULL"
            + "      END gebouw"
          + "      , NULL terrein"
          + "  FROM prs_v_perslid_fullnames_all p"
          + "      , cnt_v_aanwezigcontract c"
          + "      , ins_tab_discipline td"
          + "      , prs_kostenplaats k"
          + "      , fac_v_webgebruiker w"
          + "      , fac_functie f"
          + (fiatstatus != "open"
            ? ", fac_tracking ft"
              + ", fac_srtnotificatie fno"
            : "")
          + (filterlocatie
            ? ", cnt_contract_plaats cp"
            : "")
          + " WHERE c.ins_discipline_key = td.ins_discipline_key"
          + "   AND c.prs_perslid_key_beh = p.prs_perslid_key"
          + "   AND c.prs_kostenplaats_key = k.prs_kostenplaats_key"
          + "   AND w.prs_perslid_key IN (" + prsKeys + ")"
          + "   AND w.fac_functie_key = f.fac_functie_key"
          + "   AND w.ins_discipline_key = c.ins_discipline_key"
          //+ "   AND fac_functie_code LIKE 'WEB_CNTGO%'"
           + (fiatstatus == "open"
            ? " AND c.cnt_contract_status = 3"
              + " AND COALESCE(c.cnt_contract_approved, 0) < cnt_contract_kosten"                   // Contract is nog niet volledig goedgekeurd.
/* A1 */      + " AND (   (c.cnt_contract_kosten > " + S("cnt_contract_limit1")         // Zijn de kosten hoger als de limiet.
              + "          AND COALESCE(c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit1") // Goedkeur 1.
              + (S("cnt_approval_all") == 1
                ? "        AND cnt_contract_kosten > " + S("cnt_contract_limit1")
                  + "      AND cnt_contract_kosten <= " + S("cnt_contract_limit2")                  // Er moet in 1 keer goed gekeurd te worden.
                : "")
              + getSqlLocAut('WEB_CNTGO1')
              + "          AND f.fac_functie_code LIKE 'WEB_CNTGO1')"                               // Heb ik rechten voor de eerste goedkeur.
/* A2 */      + "      OR (c.cnt_contract_kosten > " + S("cnt_contract_limit2")                     // Zijn de kosten hoger als de limiet.
              + "          AND COALESCE(c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit2") // Goedkeur 2.
              + (S("cnt_approval_all") == 0
                ? "        AND COALESCE(c.cnt_contract_approved, 0) > " + S("cnt_contract_limit1")  // Eerste goedkeuring is geweest.
                : "        AND cnt_contract_kosten > " + S("cnt_contract_limit1")
                  + "      AND cnt_contract_kosten <= " + S("cnt_contract_limit3"))                 // Er moet in 1 keer goed gekeurd worden.
              + getSqlLocAut('WEB_CNTGO2')
              + "          AND f.fac_functie_code LIKE 'WEB_CNTGO2')"                               // Heb ik rechten voor de tweede goedkeur.
/* A3 */      + "      OR (c.cnt_contract_kosten > " + S("cnt_contract_limit3")                     // Zijn de kosten hoger als de limiet.
              + "          AND COALESCE(c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit3") // Goedkeur 3.
              + (S("cnt_approval_all") == 0
                ? "        AND COALESCE(c.cnt_contract_approved, 0) > " + S("cnt_contract_limit2")  // Tweede goedkeuring is geweest.
                : "        AND cnt_contract_kosten > " + S("cnt_contract_limit2")
                  + "      AND cnt_contract_kosten <= " + S("cnt_contract_limit4"))                 // Er moet in 1 keer goed gekeurd worden.
              + getSqlLocAut('WEB_CNTGO3')
              + "          AND f.fac_functie_code LIKE 'WEB_CNTGO3')"                               // Heb ik rechten voor de derde goedkeur.
/* A4 */      + "      OR (c.cnt_contract_kosten > " + S("cnt_contract_limit4")                     // Zijn de kosten hoger als de limiet.
              + "          AND COALESCE(c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit4") // Goedkeur 4.
              + (S("cnt_approval_all") == 0
                ? "        AND COALESCE(c.cnt_contract_approved, 0) > " + S("cnt_contract_limit3")  // Derde goedkeuring is geweest.
                : "        AND cnt_contract_kosten > " + S("cnt_contract_limit3")
                  + "      AND cnt_contract_kosten <= " + S("cnt_contract_limit5"))                 // Er moet in 1 keer goed gekeurd worden.
              + getSqlLocAut('WEB_CNTGO4')
              + "          AND f.fac_functie_code LIKE 'WEB_CNTGO4')"                               // Heb ik rechten voor de vierde goedkeur.
/* A5 */      + "      OR (c.cnt_contract_kosten > " + S("cnt_contract_limit5")                     // Zijn de kosten hoger als de limiet.
              + "          AND COALESCE(c.cnt_contract_approved, 0) <= " + S("cnt_contract_limit5") // Goedkeur 5.
              + (S("cnt_approval_all") == 0
                ? "        AND COALESCE(c.cnt_contract_approved, 0) > " + S("cnt_contract_limit4")  // Vierde goedkeuring is geweest.
                : "        AND cnt_contract_kosten > " + S("cnt_contract_limit5"))                  // Er moet in 1 keer goed gekeurd te worden.
              + getSqlLocAut('WEB_CNTGO5')
              + "          AND f.fac_functie_code LIKE 'WEB_CNTGO5'))"                              // Heb ik rechten voor de vijfde goedkeur.
              + " AND COALESCE (fac_gebruiker_prs_level_write, 9) < 9"                              // Heb ik enige schrijfrechten, dan heb ik alle schrijfrechten. Autorisatie is Ja/Nee.
            : " AND c.cnt_contract_status = " + (fiatstatus == "close"? "0" : "2")
              + " AND ft.fac_tracking_refkey = c.cnt_contract_key"
              + " AND ft.fac_srtnotificatie_key = fno.fac_srtnotificatie_key"
              + " AND fno.fac_srtnotificatie_code IN (" + (fiatstatus == "close"? "'CNTFIT'" : "'CNTREJ'") + ")"
              + " AND ft.prs_perslid_key IN (" + prsKeys + ")")
          + (filterlocatie
            ? " AND" + filter_gebonden
            : "");
  return " SELECT * FROM (" + sql + ")";
}


function getSqlFiatMld(fiatstatus, prsKeys, params)
{ // opdrachten: te fiatteren op mijn budgetten
  var sql = (params.goedkeur
            ? " SELECT op.mld_opdr_key" // Query wordt gebruikt als subquery voor getSqlGoedkeurMld (AND op.mld_opdr_key NOT IN (...))
            : " SELECT sd.ins_srtdiscipline_prefix || op.mld_melding_key || '/' || op.mld_opdr_bedrijfopdr_volgnr aanvraagnummer"
              + "      , mld_opdr_datumbegin datum"
              + "      , pf.prs_perslid_naam_full"
              + "      , mld_opdr_kosten bedrag"
              + "      , 'MLD' module"
              + "      , mld_typeopdr_omschrijving type"
              + "      , " + safe.quoted_sql(fiatstatus) + " fiatstatus"
              + "      , op.mld_opdr_key request_key"
              + "      , op.mld_statusopdr_key statuskey"
              + "      , mld_opdr_datumbegin sortdate"
              + "      , "+ lcl.xsql('td.ins_discipline_omschrijving','td.ins_discipline_key') +" categorie"
              + (fiatstatus == "open"
                ? "    , p2.prs_perslid_naam_full"
                : "    , ' '") + " fiatteur"
              + "      , NULL bes_bestelling_parentkey"
              + "      , sd.ins_srtdiscipline_prefix prefix"
              + "      , NULL uitvoerende"
              + "      , CASE "
                + "      WHEN l.alg_locatie_key IS NULL"
                + "      THEN NULL"
                + "      ELSE l.alg_locatie_omschrijving || ' (' || l.alg_locatie_code || ')'"
                + "      END locatie"
              + "      , g.alg_gebouw_code || ' ' || g.alg_gebouw_naam gebouw"
              + "      , t.alg_terreinsector_code || ' ' || alg_terreinsector_naam terrein")
          + "   FROM mld_melding m"
          + "      , mld_stdmelding sm"
          + "      , mld_opdr op"
          + "      , mld_typeopdr ot"
          + "      , prs_v_perslid_fullnames_all pf"
          + "      , prs_kostenplaats k"
          + "      , ins_tab_discipline td"
          + "      , ins_srtdiscipline sd"
          + "      , fac_tracking ft"
          + "      , fac_srtnotificatie fno"
          + "      , " + fac.getVSqlVerantwoordelijk(prsKeys) + "ver"
          + (fiatstatus == "open"
            ? "      , prs_v_perslid_fullnames_all p2"
            : "")
          + "      , alg_locatie l"
          + "      , alg_v_allonroerendgoed onrg"
          + "      , alg_v_aanweziggebouw g"
          + "      , alg_terreinsector t"
          + "  WHERE op.mld_melding_key = m.mld_melding_key"
          + "    AND op.mld_typeopdr_key = ot.mld_typeopdr_key"
          + "    AND COALESCE(op.prs_kostenplaats_key, m.prs_kostenplaats_key) = k.prs_kostenplaats_key" // Indien melding en opdracht geen kostenplaats hebben, dan ook niet fiateren en is de opdrachtstatus al "Uitgegeven"
          + "    AND k.prs_kostenplaats_key = ver.prs_kostenplaats_key(+)"
          + "    AND pf.prs_perslid_key = m.prs_perslid_key"
          + "    AND ft.fac_tracking_refkey = op.mld_opdr_key"
          + "    AND ft.fac_srtnotificatie_key = fno.fac_srtnotificatie_key"
          + "    AND op.mld_melding_key = m.mld_melding_key"
          + "    AND m.mld_stdmelding_key = sm.mld_stdmelding_key"
          + "    AND sm.mld_ins_discipline_key = td.ins_discipline_key"
          + "    AND sd.ins_srtdiscipline_key = td.ins_srtdiscipline_key"
          + "    AND m.mld_alg_locatie_key = l.alg_locatie_key(+)"
          + "    AND m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)"
          + "    AND onrg.alg_gebouw_key = g.alg_gebouw_key(+)"
          + "    AND onrg.alg_terreinsector_key = t.alg_terreinsector_key(+)"
          + (fiatstatus == "open"
            ? " AND fno.fac_srtnotificatie_code = 'ORDFIA'"// Er moe(s)t uberhaupt gefiatteerd worden
              + " AND op.mld_statusopdr_key = 3"
              // Door gebruik van de database functie fac.gettrackinguserkey (peventcode IN VARCHAR2, pkey IN NUMBER) in het WHERE statement
              // is de query zeer traag indien er vervangers zijn gedefinieerd (prsKeys bestaat uit meer dan 1 key).
              // Daarom de database functie fac.gettrackinguserkey (peventcode IN VARCHAR2, pkey IN NUMBER) uitgeschreven
              // fac_tracking en fac_srtnotificatie mee joinen duurder langer als onderstaande oplossing.
/* A1 */              //+ " AND p2.prs_perslid_key = CASE WHEN fac.gettrackinguserkey('ORDFOK', op.mld_opdr_key) IS NULL "
/* A1 */              + " AND p2.prs_perslid_key = CASE WHEN NOT EXISTS"
              + "                                    (SELECT prs_perslid_key"
              + "                                       FROM fac_tracking t"
              + "                                          , fac_srtnotificatie st"
              + "                                      WHERE t.fac_srtnotificatie_key = st.fac_srtnotificatie_key"
              + "                                        AND st.fac_srtnotificatie_code = 'ORDFOK'"
              + "                                        AND fac_tracking_refkey = op.mld_opdr_key"
              + "                                        )"
              + "                          THEN prs.getkpverantwoordelijke (op.prs_kostenplaats_key, " + S("prs_approvemethod") + ", -1)"
/* A2 */              + "                          ELSE ver.prs_perslid_key"
              + "                          END"
              + " AND p2.prs_perslid_key IN (" + prsKeys + ")"                                   // Wel ORDFOK tracking aanwezig. Neem kostenplaatsgroepverantwoordelijke
            : " AND fno.fac_srtnotificatie_code = " + (fiatstatus == "close"? "'ORDFOK'" : "'ORDFNO'") // Er is gefiatteerd.
              + " AND ft.prs_perslid_key IN (" + prsKeys + ")") // Gefiatterd door jezelf of waarvoor je vervanger bent
          + (params.bld_key // sortering op gebouw, locatie of district
            ? " AND g.alg_gebouw_key = " + params.bld_key
            : (params.loc_key_arr
              ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
              : ""))
          + (params.opdrtype_key
            ? " AND ot.mld_typeopdr_key = " + params.opdrtype_key
            : "");
  return sql;
}

// opdrachten die eerst nog goedgekeurd moet worden (nog voordat ze gefiatteerd mogen worden)
function getSqlGoedkeurMld(fiatstatus, prsKeys, params)
{ // opdrachten: goedkeuren
  params.goedkeur = true;
  var sql = " SELECT sd.ins_srtdiscipline_prefix || op.mld_melding_key || '/' || op.mld_opdr_bedrijfopdr_volgnr aanvraagnummer"
          + "      , mld_opdr_datumbegin datum"
          + "      , pf.prs_perslid_naam_full"
          + "      , mld_opdr_kosten bedrag"
          + "      , 'GOED' module"
          + "      , mld_typeopdr_omschrijving type"
          + "      , " + safe.quoted_sql(fiatstatus) + " fiatstatus"
          + "      , op.mld_opdr_key request_key"
          + "      , op.mld_statusopdr_key statuskey"
          + "      , mld_opdr_datumbegin sortdate"
          + "      , "+ lcl.xsql('td.ins_discipline_omschrijving','td.ins_discipline_key') +" categorie"
          + "      , ' ' fiatteur" // dat kunnen er meerdere met WEB_ORDGOE zijn
          + "      , NULL bes_bestelling_parentkey"
          + "      , sd.ins_srtdiscipline_prefix prefix"
          + "      , NULL uitvoerende"
          + "      , CASE "
            + "      WHEN l.alg_locatie_key IS NULL"
            + "      THEN NULL"
            + "      ELSE l.alg_locatie_omschrijving || ' (' || l.alg_locatie_code || ')'"
            + "      END locatie"
          + "      , g.alg_gebouw_code || ' ' || g.alg_gebouw_naam gebouw"
          + "      , t.alg_terreinsector_code || ' ' || alg_terreinsector_naam terrein"
          + "   FROM mld_melding m"
          + "      , mld_disc_params mdp"
          + "      , mld_stdmelding sm"
          + "      , mld_opdr op"
          + "      , mld_typeopdr ot"
          + "      , prs_v_perslid_fullnames_all pf"
          + "      , prs_perslid p"
          + "      , ins_tab_discipline td"
          + "      , ins_srtdiscipline sd"
          + (fiatstatus != "open"
            ? "      , fac_tracking ft"
              + "    , fac_srtnotificatie fno"
            : "")
          + "      , alg_locatie l"
          + "      , alg_v_allonroerendgoed onrg"
          + "      , alg_v_aanweziggebouw g"
          + "      , alg_terreinsector t"
          + "  WHERE op.mld_melding_key = m.mld_melding_key"
          + "    AND op.mld_typeopdr_key = ot.mld_typeopdr_key"
          + "    AND pf.prs_perslid_key = m.prs_perslid_key"
          + "    AND p.prs_perslid_key = m.prs_perslid_key"
          + "    AND op.mld_melding_key = m.mld_melding_key"
          + "    AND m.mld_stdmelding_key = sm.mld_stdmelding_key"
          + "    AND sm.mld_ins_discipline_key = td.ins_discipline_key"
          + "    AND sd.ins_srtdiscipline_key = td.ins_srtdiscipline_key"
          + "    AND mdp.mld_ins_discipline_key = sm.mld_ins_discipline_key"
          + "    AND EXISTS("
          + "         SELECT g.prs_perslid_key"
          + "           FROM fac_v_webgebruiker g"
          + "              , fac_functie f"
          + "              , prs_perslid pzelf"
          + "          WHERE g.fac_functie_key = f.fac_functie_key"
          + "            AND g.ins_discipline_key = sm.mld_ins_discipline_key"
          + "            AND pzelf.prs_perslid_key IN (" + prsKeys + ")"
          + "            AND g.prs_perslid_key = pzelf.prs_perslid_key"
          + "            AND (g.fac_gebruiker_prs_level_write = -1"
          + "                 OR (g.fac_gebruiker_prs_level_write < 9"
          + "                     AND pzelf.prs_afdeling_key IN"
          + "                              (SELECT   prs_afdeling_key"
          + "                                 FROM   prs_v_afdeling_familie a"
          + "                                WHERE   a.prs_afdeling_elder_key IN"
          + "                                              (SELECT aa.prs_afdeling_elder_key"
          + "                                                 FROM prs_v_afdeling_familie aa"
          + "                                                WHERE aa.prs_afdeling_key = p.prs_afdeling_key"
          + "                                                  AND aa.niveau = g.fac_gebruiker_prs_level_write))))"
          + "            AND (g.fac_gebruiker_alg_level_write = -1"
          + "                 OR (g.fac_gebruiker_alg_level_write < 9"
          + "                     AND m.mld_alg_locatie_key IN" // alleen locatie en lager ondersteund
          + "                              (SELECT alg_locatie_key"
          + "                                 FROM fac_v_my_locations"
          + "                                WHERE prs_perslid_key = pzelf.prs_perslid_key"
          + "                                  AND niveau = fac_gebruiker_alg_level_write)))"
          + (fiatstatus == "open"
            ? (S("mld_opdr_approval_all") == 0
              ? "                 AND ((fac_functie_code = 'WEB_ORDGOE'"
                + "                    AND ((op.mld_opdr_kosten >= mdp.mld_disc_params_bestellimiet"
                + "                          AND COALESCE (op.mld_opdr_approved, 0) <= mdp.mld_disc_params_bestellimiet)"
                + "                         OR (op.mld_opdr_kosten >= ot.mld_typeopdr_gvs AND COALESCE (op.mld_opdr_approved, -1) < 0)))"
                + "                OR (fac_functie_code = 'WEB_ORDGO2'"
                + "                    AND op.mld_opdr_kosten >= mdp.mld_disc_params_bestellimiet2"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) = mdp.mld_disc_params_bestellimiet2)"
                + "                OR (fac_functie_code = 'WEB_ORDGO3'"
                + "                    AND op.mld_opdr_kosten >= mdp.mld_disc_params_bestellimiet3"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) = mdp.mld_disc_params_bestellimiet3)"
                + "                OR (fac_functie_code = 'WEB_ORDGO4'"
                + "                    AND op.mld_opdr_kosten >= mdp.mld_disc_params_bestellimiet4"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) = mdp.mld_disc_params_bestellimiet4)"
                + "                OR (fac_functie_code = 'WEB_ORDGO5'"
                + "                    AND op.mld_opdr_kosten >= mdp.mld_disc_params_bestellimiet5"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) >= mdp.mld_disc_params_bestellimiet5)"
                + "                  )"
              : "                AND ((fac_functie_code = 'WEB_ORDGOE'"
                + "                    AND op.mld_opdr_kosten <= mdp.mld_disc_params_bestellimiet2"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) <= mdp.mld_disc_params_bestellimiet)"
                + "                OR (fac_functie_code = 'WEB_ORDGO2'"
                + "                    AND op.mld_opdr_kosten <= mdp.mld_disc_params_bestellimiet3"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) <= mdp.mld_disc_params_bestellimiet2)"
                + "                OR (fac_functie_code = 'WEB_ORDGO3'"
                + "                    AND op.mld_opdr_kosten <= mdp.mld_disc_params_bestellimiet4"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) <= mdp.mld_disc_params_bestellimiet3)"
                + "                OR (fac_functie_code = 'WEB_ORDGO4'"
                + "                    AND op.mld_opdr_kosten <= mdp.mld_disc_params_bestellimiet5"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) <= mdp.mld_disc_params_bestellimiet4)"
                + "                OR (fac_functie_code = 'WEB_ORDGO5'"
                + "                    AND op.mld_opdr_kosten >= mdp.mld_disc_params_bestellimiet5"
                + "                    AND COALESCE(op.mld_opdr_approved, 0) <= mdp.mld_disc_params_bestellimiet5)"
                + "                  )")
            : "")
          + "              )"
          + "    AND m.mld_alg_locatie_key = l.alg_locatie_key(+)"
          + "    AND m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)"
          + "    AND onrg.alg_gebouw_key = g.alg_gebouw_key(+)"
          + "    AND onrg.alg_terreinsector_key = t.alg_terreinsector_key(+)"
          + (fiatstatus == "open"
             ? " AND op.mld_statusopdr_key = 10"
             :  " AND mld_opdr_kosten > mdp.mld_disc_params_bestellimiet" // zo duur, moet wel een goedkeur geweest zijn
              + " AND ft.fac_tracking_refkey = op.mld_opdr_key"
              + " AND ft.prs_perslid_key IN (" + prsKeys + ")"
              + " AND ft.fac_srtnotificatie_key = fno.fac_srtnotificatie_key"
              + " AND fno.fac_srtnotificatie_code IN"
              + (fiatstatus == "close"
                ? " ('ORDFOK', 'ORDGOE') AND m.prs_perslid_key != ft.prs_perslid_key" // Als goedkeurder ook de opdracht heeft aangemaakt dan komt opdracht niet in de gefiatteerd lijst. Is niet zo gemakkelijk en zal performance kosten.
                : " ('ORDGNO')"))
          + (params.bld_key // sortering op gebouw, locatie of district
            ? " AND g.alg_gebouw_key = " + params.bld_key
            : (params.loc_key_arr
              ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
              : ""))
          + (params.opdrtype_key
            ? " AND ot.mld_typeopdr_key = " + params.opdrtype_key
            : "")
          + (fiatstatus == "close"
            ? " AND op.mld_opdr_key NOT IN (" + getSqlFiatMld(fiatstatus, prsKeys, params) + ")"
            : "");
  return sql;
}

// Offertes die geaccepteerd of afgewezen dienen te worden van meldingen waarvoor nog geen uitvoeringsopdracht is aangemaakt.
function getSqlAccAfwOff(params)
{ // opdrachten: accepten/afwijzen
  // Zonder WEB_ORDOAP rechten kom ik hier al niet.
  var sql = " SELECT o.mld_melding_key || '/' || o.mld_opdr_bedrijfopdr_volgnr aanvraagnummer"
          + "      , mld_opdr_datumbegin datum"
          + "      , pf.prs_perslid_naam_full"
          + "      , mld_opdr_kosten bedrag"
          + "      , 'OFFERTE' module"
          + "      , mld_typeopdr_omschrijving type"
          + "      , 'open' fiatstatus"
          + "      , o.mld_opdr_key request_key"
          + "      , o.mld_statusopdr_key statuskey"
          + "      , mld_opdr_einddatum sortdate"
          + "      , "+ lcl.xsql('td.ins_discipline_omschrijving','td.ins_discipline_key') +" categorie"
          + "      , ' ' fiatteur" // dat kunnen er meerdere met WEB_ORDOAP zijn
          + "      , NULL bes_bestelling_parentkey"
          + "      , sd.ins_srtdiscipline_prefix prefix"
          + "      , COALESCE((SELECT b.prs_bedrijf_naam FROM prs_bedrijf b WHERE b.prs_bedrijf_key = o.mld_uitvoerende_keys),"
          + "                 COALESCE((SELECT " + S("prs_pers_string") + " FROM prs_perslid p WHERE p.prs_perslid_key = o.mld_uitvoerende_keys),"
          + "                 '')) uitvoerende"
          + "      , CASE "
            + "      WHEN l.alg_locatie_key IS NULL"
            + "      THEN NULL"
            + "      ELSE l.alg_locatie_omschrijving || ' (' || l.alg_locatie_code || ')'"
            + "      END locatie"
          + "      , g.alg_gebouw_code || ' ' || g.alg_gebouw_naam gebouw"
          + "      , t.alg_terreinsector_code || ' ' || alg_terreinsector_naam terrein"
          + "   FROM mld_melding m"
          + "      , mld_stdmelding sm"
          + "      , mld_opdr o"
          + "      , mld_typeopdr ot"
          + "      , prs_v_perslid_fullnames_all pf"
          + "      , ins_tab_discipline td"
          + "      , ins_srtdiscipline sd"
          + "      , (SELECT o1.mld_melding_key"
          + "              , COUNT (o1.mld_opdr_key) aantal_opdrachten"
          + "              , MAX(o1.mld_opdr_bedrijfopdr_volgnr) lastopdrachtvolgnr"
          + "           FROM mld_opdr o1"
          + "              , mld_typeopdr mto"
          + "          WHERE o1.mld_typeopdr_key = mto.mld_typeopdr_key"
          + "            AND mto.mld_typeopdr_isofferte = 0"
          + "         GROUP BY o1.mld_melding_key) opdracht"
          + "      , alg_locatie l"
          + "      , alg_v_allonroerendgoed onrg"
          + "      , alg_v_aanweziggebouw g"
          + "      , alg_terreinsector t"
          + "  WHERE o.mld_melding_key = m.mld_melding_key"
          + "    AND o.mld_typeopdr_key = ot.mld_typeopdr_key"
          + "    AND pf.prs_perslid_key = m.prs_perslid_key"
          + "    AND m.mld_stdmelding_key = sm.mld_stdmelding_key"
          + "    AND sm.mld_ins_discipline_key = td.ins_discipline_key"
          + "    AND sd.ins_srtdiscipline_key = td.ins_srtdiscipline_key"
          + "    AND ot.mld_typeopdr_isofferte = 1"
          + "    AND o.mld_melding_key = opdracht.mld_melding_key(+)"
          + "    AND (opdracht.aantal_opdrachten IS NULL"
          + "         OR opdracht.lastopdrachtvolgnr < o.mld_opdr_bedrijfopdr_volgnr)"
          + "    AND o.mld_statusopdr_key IN (6)"
          + "    AND m.mld_alg_locatie_key = l.alg_locatie_key(+)"
          + "    AND m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)"
          + "    AND onrg.alg_gebouw_key = g.alg_gebouw_key(+)"
          + "    AND onrg.alg_terreinsector_key = t.alg_terreinsector_key(+)"
          + (params.bld_key // sortering op gebouw, locatie of district
            ? " AND g.alg_gebouw_key = " + params.bld_key
            : (params.loc_key_arr
              ? " AND l.alg_locatie_key IN (" + params.loc_key_arr.join(",") + ")"
              : ""))
          + (params.opdrtype_key
            ? " AND ot.mld_typeopdr_key = " + params.opdrtype_key
            : "");
  return sql;
}

// Facturen die gefiatteerd moet worden.
function getSqlFiatFin(fiatstatus, prsKeys, params)
{ // Facturen: fiatteren.
  // Zonder WEB_FINBOF rechten of zonder dat ik budgethouder ben, kom ik hier al niet.
  var scope = getCntScope(params);

  var loc_count = "(SELECT COUNT(loc) FROM theScope scope WHERE scope.cnt_key = c.cnt_contract_key)";
  var loc_oms = "(SELECT loc_oms FROM theScope scope WHERE scope.cnt_key = c.cnt_contract_key)";
  var gebter_oms = "(SELECT gebter_oms FROM theScope scope WHERE scope.cnt_key = c.cnt_contract_key)";
  var filterlocatie = (params.dist_key ? true : false);
  var filter_gebonden = getCntGebonden(params);

  var authparamsFINBOF = user.checkAutorisation("WEB_FINBOF", true);
  var sql = " WITH theScope AS (" + scope + ")"
          + " SELECT to_char(f.fin_factuur_key) aanvraagnummer"
          + "      , f.fin_factuur_datum datum"
          + "      , pf.prs_perslid_naam_full"
          + "      , (fin_factuur_totaal + fin_factuur_totaal_btw) bedrag"
          + "      , 'FIN' module"
          + "      , CASE"
            + "      WHEN f.bes_bestelopdr_key IS NOT NULL"
            + "      THEN 'Bestelling'"
            + "      WHEN f.cnt_contract_key IS NOT NULL"
            + "      THEN 'Contract'"
            + "      WHEN f.mld_opdr_key IS NOT NULL"
            + "      THEN 'Opdracht'"
            + "      END type"
          + "      , " + safe.quoted_sql(fiatstatus) + " fiatstatus"
          + "      , f.fin_factuur_key request_key"
          + "      , f.fin_factuur_statuses_key statuskey"
          + "      , f.fin_factuur_datum sortdate"
          + "      , NULL categorie"
          + (fiatstatus == "open"
            ? "    , ' '"
            : "    , pf2.prs_perslid_naam_full") + " fiatteur"
          + "      , NULL bes_bestelling_parentkey"
          + "      , NULL prefix"
          + "      , COALESCE((SELECT b.prs_bedrijf_naam FROM prs_bedrijf b WHERE prs_bedrijf_key = COALESCE (o.mld_uitvoerende_keys, c.cnt_prs_bedrijf_key, bo.prs_bedrijf_key)),"
            + "               (SELECT " + S("prs_dep_string") + " FROM prs_v_afdeling d WHERE d.prs_afdeling_key = c.cnt_prs_afdeling_key),"
            + "               (SELECT " + S("prs_pers_string") + " FROM prs_perslid p WHERE p.prs_perslid_key = c.cnt_prs_perslid_key)) uitvoerende"
          + "      , CASE"
          + "        WHEN f.bes_bestelopdr_key IS NOT NULL"
          + "        THEN (SELECT m.mld_adres_naam FROM mld_v_afleveradres m WHERE m.mld_adres_key IN (bo.mld_adres_key_lev))"
          + "        WHEN f.cnt_contract_key IS NOT NULL"
          + "        THEN CASE " + loc_count
            + "           WHEN 0"
            + "           THEN NULL"
            + "           WHEN 1"
            + "           THEN " + loc_oms
            + "           ELSE " + safe.quoted_sql(L("lcl_cnt_locatie_m")) + " || "
            + "                ' (' || TO_CHAR(" + loc_count + ") || ')'"  // Er kunnen meerdere locaties zijn (contract scope)
            + "           END"
          + "        WHEN f.mld_opdr_key IS NOT NULL"
          + "        THEN CASE "
            + "           WHEN l.alg_locatie_key IS NULL"
            + "           THEN NULL"
            + "           ELSE l.alg_locatie_omschrijving || ' (' || l.alg_locatie_code || ')'"
            + "           END"
          + "        END locatie"
          + "      , CASE"
          + "        WHEN f.bes_bestelopdr_key IS NOT NULL"
          + "        THEN NULL"
          + "        WHEN f.cnt_contract_key IS NOT NULL"
          + "        THEN CASE " + loc_count
            + "           WHEN 1"
            + "           THEN TO_CHAR (" + gebter_oms + ")"
            + "           ELSE NULL"
            + "           END"
          + "        WHEN f.mld_opdr_key IS NOT NULL"
          + "        THEN g.alg_gebouw_code || ' ' || g.alg_gebouw_naam"
          + "        END gebouw"
          + "      , CASE"
          + "        WHEN f.mld_opdr_key IS NOT NULL"
          + "        THEN t.alg_terreinsector_code || ' ' || alg_terreinsector_naam"
          + "        ELSE NULL" // f.bes_bestelopdr_key IS NOT NULL en f.cnt_contract_key IS NOT NULL
          + "        END terrein"
          + "   FROM (SELECT prs.getkpverantwoordelijke(prs_kostenplaats_key, " + S("prs_approvemethod") + ", -1) budgethouder,"
          + "        f.* FROM (select fin.getfactuurkostenplaats(f.fin_factuur_key) prs_kostenplaats_key, f.* from fin_factuur f) f) f"
          + "      , prs_v_perslid_fullnames_all pf"
          +  "     , bes_bestelopdr bo"
          +  "     , mld_opdr o"
          +  "     , mld_melding m"
          +  "     , cnt_contract c"
          +  "     , alg_locatie l"
          +  "     , alg_v_allonroerendgoed onrg"
          +  "     , alg_v_aanweziggebouw g"
          +  "     , alg_terreinsector t"
          + (filterlocatie
            ? ", cnt_contract_plaats cp"
            : "")
          + (fiatstatus != "open"
            ? "    , fac_tracking ft"
              + "  , fac_srtnotificatie fno"
              + "  , prs_v_perslid_fullnames_all pf2"
            : "")
          + "  WHERE f.prs_perslid_key_user = pf.prs_perslid_key(+)"
          + "    AND f.bes_bestelopdr_key = bo.bes_bestelopdr_key(+)"
          + "    AND f.mld_opdr_key = o.mld_opdr_key(+)"         //      vast staat in welke tak we zitten
          + "    AND o.mld_melding_key = m.mld_melding_key(+)"
          + "    AND f.cnt_contract_key = c.cnt_contract_key(+)"
          + "    AND f.fin_factuur_verwijder IS NULL"
          + "    AND budgethouder > 0"
          // Ik kan facturen fiatteren als: 1) Ik ben budgethouder van de BrOC-kostenplaats (BrOC = Bestelling, /*reservering*/, Opdracht, Contract)
          //                                2) ik heb ALG write rechten (WEB_FINBOF) op
          //                                   a) het afleveradres van de locatie van de bestelling
          //                                   b) de plaats van de bijbehorende melding van de opdracht OF
          //                                3) ik ben contracteigenaar van het contract
          // "AND (" + sql1a + " OR " + sql1b + " OR " + sql2 + " OR " + sql3 + ")"
          + " AND ("
          + (authparamsFINBOF && authparamsFINBOF.ALGwritelevel > -1
            ? // 1a) Heb ik ALG write rechten (WEB_FINBOF) op het afleveradres van de locatie van de bestelling?
              " (f.bes_bestelopdr_key IS NOT NULL "
                + " AND bo.mld_adres_key_lev IN (SELECT m.mld_adres_key"
                + "                              FROM mld_v_afleveradres ma"
                + "                             WHERE bo.mld_adres_key_lev = ma.mld_adres_key"
                + "                               AND ma.alg_locatie_key IN (SELECT alg_locatie_key"
                + "                                                           FROM fac_v_my_locations"
                + "                                                          WHERE prs_perslid_key IN (" + prsKeys + ")"
                + "                                                            AND niveau = " + authparamsFINBOF.ALGwritelevel + ")))"
                // 1b) Heb ik ALG write rechten (WEB_FINBOF) op de plaats van de bijbehorende melding van de opdracht?
                + " OR (f.mld_opdr_key IS NOT NULL "
                + "     AND EXISTS (SELECT m.mld_melding_key"
                + "                   FROM alg_v_onroerendgoed onrg"
                + "                  WHERE m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)"
                + "                    AND ((onrg.alg_type = 'R' "
                + "                          AND m.mld_alg_onroerendgoed_keys IN (SELECT alg_ruimte_key"
                + "                                                                 FROM fac_v_my_rooms"
                + "                                                                WHERE prs_perslid_key IN (" + prsKeys + ")"
                + "                                                                  AND niveau = " + authparamsFINBOF.ALGwritelevel + "))"
                + "                         OR (onrg.alg_type = 'V'"
                + "                             AND m.mld_alg_onroerendgoed_keys IN (SELECT alg_verdieping_key"
                + "                                                                    FROM fac_v_my_floors"
                + "                                                                   WHERE prs_perslid_key IN (" + prsKeys + ")"
                + "                                                                     AND niveau = " + authparamsFINBOF.ALGwritelevel + "))"
                + "                         OR (onrg.alg_type = 'G'"
                + "                             AND m.mld_alg_onroerendgoed_keys IN (SELECT alg_gebouw_key"
                + "                                                                    FROM fac_v_my_buildings"
                + "                                                                   WHERE prs_perslid_key IN (" + prsKeys + ")"
                + "                                                                     AND niveau = " + authparamsFINBOF.ALGwritelevel + "))"
                + "                         OR (m.mld_alg_onroerendgoed_keys IS NULL"
                + "                             AND m.mld_alg_locatie_key IN (SELECT alg_locatie_key"
                + "                                                             FROM fac_v_my_locations"
                + "                                                            WHERE prs_perslid_key IN (" + prsKeys + ")"
                + "                                                              AND niveau = " + authparamsFINBOF.ALGwritelevel + "))"
                + "                        )"
                + "                )"
                + "    )"
            : (authparamsFINBOF && authparamsFINBOF.ALGwritelevel == -1
              ? " 1 = 1"   // Volledige FINBOF rechten
              : " 1 = 0")) // Geen enkele FINBOF rechten
          // 2) Ben ik contracteigenaar van het contract?
          + " OR (f.cnt_contract_key IS NOT NULL"
          + "     AND c.prs_perslid_key_eig  IN (" + prsKeys + "))"
          // 3) Ben ik budgethouder van de BrOC-kostenplaats?
          + " OR (budgethouder IN (" + prsKeys + "))"
          + ")"
          + (params.opdrtype_key
            ? " AND o.mld_typeopdr_key = " + params.opdrtype_key
            : "")
          + (fiatstatus == "open"
             ? " AND f.fin_factuur_statuses_key IN (2)"
               //+ " AND f.prs_perslid_key_goedkeur IN (" + prsKeys + ")"
             : " AND ft.fac_tracking_refkey = f.fin_factuur_key"
               + " AND ft.prs_perslid_key = pf2.prs_perslid_key"
               + " AND ft.prs_perslid_key IN (" + prsKeys + ")" // Alleen die facturen die ik zelf (ook als vervanger) kon fiatteren/afkeuren.
               + " AND ft.fac_srtnotificatie_key = fno.fac_srtnotificatie_key"
               + " AND fno.fac_srtnotificatie_code IN"
               + (fiatstatus == "close"
                 ? " ('FINGOE')"
                 : " ('FINFNO')"))
          + "    AND m.mld_alg_locatie_key = l.alg_locatie_key(+)"
          + "    AND m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)"
          + "    AND onrg.alg_gebouw_key = g.alg_gebouw_key(+)"
          + "    AND onrg.alg_terreinsector_key = t.alg_terreinsector_key(+)"
          + (filterlocatie
            ? "    AND c.cnt_contract_key = cp.cnt_contract_key(+)"
              + "    AND cp.cnt_alg_plaats_code(+) IN ('G', 'L', 'T')"
            : "");

  // Locatie, Gebouw of Terrein filtering
  // Als bld_key een geldige waarde heeft, hebben loc_key en dist_key ook een geldige waarde
  if (params.dist_key)
  {
    var loc_key_arr = params.loc_key_arr;
    var bld_key = params.bld_key;
    // Als alleen dist_key bekend is dan zoeken voor alle loc_key bij deze dist_key.
    // 1) Het afleveradres van de locatie van de bestelling (bld_key is niet bekend/gedefinieerd)
    sql1 = " (f.bes_bestelopdr_key IS NOT NULL "
           + " AND bo.mld_adres_key_lev IN ("
                        + "SELECT m.mld_adres_key"
                        + "  FROM mld_v_afleveradres m"
                        + " WHERE m.alg_locatie_key IN (" + loc_key_arr.join(",") + ")))";

    // 2) De plaats van de bijbehorende melding van de opdracht
    sql2 = " (f.mld_opdr_key IS NOT NULL "
         + " AND EXISTS (SELECT m.mld_melding_key"
                 + "       FROM alg_v_allonroerendgoed onrg"
                 + "      WHERE m.mld_alg_onroerendgoed_keys = onrg.alg_onroerendgoed_keys(+)"
                 + "        AND onrg.alg_locatie_key IN (" + loc_key_arr.join(",") + ")"
                 + (bld_key
                   ? " AND (  (onrg.alg_gebouw_key = " + bld_key + ")"
                     + "   OR (onrg.alg_terreinsector_key = " + bld_key + ")"
                     + "   )"
                   : "")
                 + "    ))";

    // Locatie/gebouw scope van het contract
    sql3 = " (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 (" + loc_key_arr.join(",") + "))";
    if (bld_key)
    {
      sql3 += "     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
    {
      sql3 += "     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 (" + loc_key_arr.join(",") + "))"
            + "     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 (" + loc_key_arr.join(",") + ")))";
    }
    sql3 += "     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 (" + loc_key_arr.join(",") + ")"
          + "     UNION"
          + "    SELECT cnt_contract_key"
          + "      FROM cnt_v_contract_locatie_geg cl"
          + "    WHERE alg_locatie_key IN (" + loc_key_arr.join(",") + ")))";

    sql += "AND (" + sql1 + " OR " + sql2 + " OR " + sql3 + ")";
  }

  return " SELECT * FROM (" + sql + ")";
}

// Facturen die goedgekeurd moet worden nadat ze gefiatteerd zijn geworden
function getSqlGoedkeurFin(fiatstatus, prsKeys, params)
{ // Facturen: goedkeuren
  // Zonder WEB_FINGOE rechten kom ik hier al niet.
  var sql = " SELECT to_char(f.fin_factuur_key) aanvraagnummer"
          + "      , f.fin_factuur_datum datum"
          + "      , pf.prs_perslid_naam_full"
          + "      , (fin_factuur_totaal + fin_factuur_totaal_btw) bedrag"
          + "      , 'FIN2' module"
          + "      , CASE"
          + "        WHEN f.bes_bestelopdr_key IS NOT NULL"
          + "        THEN 'Bestelling'"
          + "        WHEN f.cnt_contract_key IS NOT NULL"
          + "        THEN 'Contract'"
          + "        WHEN f.mld_opdr_key IS NOT NULL"
          + "        THEN 'Opdracht'"
          + "        END type"
          + "      , " + safe.quoted_sql(fiatstatus) + " fiatstatus"
          + "      , f.fin_factuur_key request_key"
          + "      , f.fin_factuur_statuses_key statuskey"
          + "      , f.fin_factuur_datum sortdate"
          + "      , NULL categorie"
          + "      , pf2.prs_perslid_naam_full fiatteur"
          + "      , NULL bes_bestelling_parentkey"
          + "      , NULL prefix"
          + "      , NULL uitvoerende"
          + "      , NULL locatie"
          + "      , NULL gebouw"
          + "      , NULL terrein"
          + "   FROM fin_factuur f"
          + "      , prs_v_perslid_fullnames_all pf"
          + "      , prs_v_perslid_fullnames_all pf2"
          + (fiatstatus != "open"
            ? "    , fac_tracking ft"
              + "  , fac_srtnotificatie fno"
            : "")
          + "  WHERE f.prs_perslid_key_user = pf.prs_perslid_key"
          + "    AND f.prs_perslid_key_goedkeur = pf2.prs_perslid_key"
          + (fiatstatus == "open"
             ? " AND f.fin_factuur_statuses_key IN (5)"
               + " AND f.prs_perslid_key_goedkeur IN (" + prsKeys + ")"
             :  " AND ft.fac_tracking_refkey = f.fin_factuur_key"
               + " AND ft.prs_perslid_key IN (" + prsKeys + ")" // Alleen die facturen die ik zelf (ook als vervanger) kon goedkeuren/afkeuren.
               + " AND ft.fac_srtnotificatie_key = fno.fac_srtnotificatie_key"
               + " AND fno.fac_srtnotificatie_code IN"
               + (fiatstatus == "close"
                 ? " ('FINFOK')"
                 : " ('FINGNO')")
               + " AND f.prs_perslid_key_goedkeur = ft.prs_perslid_key"); // Goedkeurder heeft goedgekeurd/afgekeurd.

  return sql;
}

function fiattering_sql(params)
{
  var haveORDOAPrights = user.checkAutorisation("WEB_ORDOAP", true); // Heb ik WEB_ORDOAP rechten om offertes te accepteren/af te wijzen.
  var haveFINBOFrights = user.checkAutorisation("WEB_FINBOF", true); // Heb ik WEB_FINBOF rechten om facturen te fiatteren/af te wijzen.
  var haveFINGOErights = user.checkAutorisation("WEB_FINGOE", true); // Heb ik WEB_FINGOE rechten om facturen goed te keuren/af te wijzen.

  var prsKeys = user.collegakeylist();

  params.betreft = params.betreft || [];
  // Betreft hoofdletter onafhankelijk maken.
  for (var i = 0; i < params.betreft.length; i++)
  {
    params.betreft[i] = params.betreft[i].toUpperCase();
  }

  var sqls = [];
  if (params.opdrtype_key)
  { // Er wordt gezocht naar een opdrachttype, die bestaan alleen voor offertes, opdrachten en eventueel bij facturen van opdrachten.
    // Verwijder "BES" uit de betreft array.
    for (var i = 0; i < params.betreft.length; i++)
    {
      if (params.betreft[i] == "BES")
        params.betreft.splice(i, 1);
    }
    // Verwijder "CNT" uit de betreft array.
    for (var i = 0; i < params.betreft.length; i++)
    {
      if (params.betreft[i] == "CNT")
        params.betreft.splice(i, 1);
    }
  }

  // Ben ik budgedhouder van de kostenplaats of de kostenplaatsgroep?
  // Alleen als budgedhouder van de kostenplaats(groep) kan ik bestellingen en meldingsopdrachten fiatteren anders hoef ik niet eens te kijken.
  // Als budgethouder van de kostenplaats(groep) kan ik misschien ook facturen fiatteren.
  var sqlkp = "SELECT COUNT(*) aantal"
            + "  FROM prs_kostenplaats k"
            + " WHERE k.prs_perslid_key IN (" + prsKeys + ")";
  var sqlkpg = "SELECT COUNT(*) aantal"
             + "  FROM prs_kostenplaatsgrp kg"
             + " WHERE kg.prs_perslid_key IN (" + prsKeys + ")";
  var sqlbud = "SELECT SUM (aantal) aantal"
            + "  FROM (" + sqlkp + " UNION " + sqlkpg + ")";
  var oRsbud = Oracle.Execute(sqlbud);
  var benBudgethouder = oRsbud("aantal").Value > 0;

  var alleModules = params.betreft.length == 0;
  if (benBudgethouder && (inArray("BES", params.betreft) || alleModules))
  {
    // Sql gedeelte voor bestellingen (BES) ophalen.
    if (params.getopen)
      sqls.push(getSqlFiatBes("open", prsKeys, params));  // Te fiatteren

    if (params.getclosed)
      sqls.push(getSqlFiatBes("close", prsKeys, params)); // Gefiatteerd

    if (params.getrejected)
      sqls.push(getSqlFiatBes("reject", prsKeys, params)); // Afgewezen
  }

  if (inArray("CNT", params.betreft) || alleModules)
  {
    // Sql gedeelte voor contracten (CNT) ophalen.
    if (params.getopen)
      sqls.push(getSqlFiatCnt("open", prsKeys, params));  // Ter goedkeuring

    if (params.getclosed)
      sqls.push(getSqlFiatCnt("close", prsKeys, params)); // Goedgekeurd

    if (params.getrejected)
      sqls.push(getSqlFiatCnt("reject", prsKeys, params)); // Afgewezen
  }

  if (inArray("MLDOP", params.betreft) || alleModules)
  {
    if(benBudgethouder)
    {
      // Sql gedeelte voor meldingsopdrachten (MLD) ophalen.
      if (params.getopen)
        sqls.push(getSqlFiatMld("open", prsKeys, params));  // Te fiatteren

      if (params.getclosed)
        sqls.push(getSqlFiatMld("close", prsKeys, params)); // Gefiatteerd

      if (params.getrejected)
        sqls.push(getSqlFiatMld("reject", prsKeys, params)); // Afgewezen
    }

    // Heb ik enige goedkeur rechten anders hoef ik niet eens te kijken.
    var haveGOErights = user.checkAutorisation(["WEB_ORDGOE", "WEB_ORDGO2", "WEB_ORDGO3", "WEB_ORDGO4", "WEB_ORDGO5"], true); // Heb ik WEB_ORDOAP rechten om offertes te accepteren/af te wijzen.

    if (haveGOErights)
    {
      // Sql gedeelte voor goedkeur meldingen (MLD) ophalen.
      if (params.getopen)
        sqls.push(getSqlGoedkeurMld("open", prsKeys, params));  // Goed te keuren

      if (params.getclosed)
        sqls.push(getSqlGoedkeurMld("close", prsKeys, params)); // Gefiatteerd

      if (params.getrejected)
        sqls.push(getSqlGoedkeurMld("reject", prsKeys, params)); // Afgewezen
    }
  }

  if (inArray("MLDOF", params.betreft) || alleModules)
  { // Werken we uberhaubt met offeretes?
    var sqloff = "SELECT COUNT(*) aantal"
               + "  FROM mld_typeopdr"
               + " WHERE mld_typeopdr_isofferte = 1";
    var oRsoff = Oracle.Execute(sqloff);
    var haveOffertes = oRsoff("aantal").Value > 0;

    // Heb ik WEB_ORDOAP rechten? Zonder deze rechten kan ik offertes toch niet accepteren/afwijzen.
    if (haveOffertes && haveORDOAPrights && params.getopen)
      sqls.push(getSqlAccAfwOff(params)); // Te accepteren/Af te wijzen offertes (offerte opdrachten) van meldingen waarvoor nog geen uitvoeringsopdracht is aangemaakt.
  }

  if (inArray("FIN", params.betreft) || alleModules)
  { // Heb ik WEB_FINBOF rechten? Zonder deze rechten kan facturen ik toch niet fiatteren/afwijzen.
    if (haveFINBOFrights || benBudgethouder)
    {
      // Sql gedeelte voor fiatteren facturen (FIN) ophalen.
      if (params.getopen)
        sqls.push(getSqlFiatFin("open", prsKeys, params));  // Te fiatteren

      if (params.getclosed)
        sqls.push(getSqlFiatFin("close", prsKeys, params)); // Gefiatteerd

      if (params.getrejected)
        sqls.push(getSqlFiatFin("reject", prsKeys, params)); // Afgewezen
    }

    if (haveFINGOErights)
    {// Heb ik WEB_FINGOE rechten? Zonder deze rechten kan ik nooit als goedkeurder worden aangewezen/geselecteerd.
      // Sql gedeelte voor goedkeuren facturen (FIN) ophalen.
      if (params.getopen)
        sqls.push(getSqlGoedkeurFin("open", prsKeys, params));  // Ter goedkeuring

      if (params.getclosed)
        sqls.push(getSqlGoedkeurFin("close", prsKeys, params)); // Goedgekeurd

      if (params.getrejected)
        sqls.push(getSqlGoedkeurFin("reject", prsKeys, params)); // Afgewezen
    }
  }

  if (sqls.length == 0)
    sql = "SELECT '1' aanvraagnummer, '2' sortdate FROM DUAL WHERE 1=0 ORDER BY sortdate, aanvraagnummer ASC"; // Geen resultaat.
  else
    sql = "SELECT * FROM (" + sqls.join(" UNION ALL ") + ") ORDER BY sortdate, aanvraagnummer ASC";

  return sql;
}

%>