<% /*
     $Revision$
     $Id$

     File:               MLD/mld_flexkenmerk.inc
     Description:        Functie die html code genereert voor de presentatie van de flexvelden
     Parameters:         urole                Rol van de gebruiker (frontend, frontoffice, backoffice, management info)
                         opdr_type            Opdracht type
                         reado                Readonly
                         advanced             Geadvanceerd
                         prs_key              Perslid key
     Context:            Functie wordt aangeroepen door
                         1) load_kenmerk.asp
                         2) mld_melding.asp die initieel serverside deze html code invoegd.
    Note:
*/ %>

<!-- #include file="../Shared/kenmerk_common.inc" -->
<!-- #include file="../Shared/Suggest/persoonFilter.inc" -->
<%
function getFlexKenmerkBlockSql(params)
{
  // Merk op: alleen bij geavanceerd zoeken kunnen deze array's meerdere records bevatten
  //          in alle andere gevallen hebben te maken met één waarde.
  var stdm_arr = (params.stdm_arr? params.stdm_arr : []);
  var srtdisc  = (params.srtdisc? params.srtdisc : []);
  var disc_arr = (params.disc_arr? params.disc_arr : []);
  var disc = (params.disc? params.disc : -1);
  var prsautlevel = (params.prsautlevel? params.prsautlevel : 9);
  var canFlexChange = (params.canFlexChange? params.canFlexChange : false);
  var show_alg = (params.show_alg? params.show_alg : false);
  var loc_key = (params.loc_key? params.loc_key : -1);
  var mld_key = (params.mld_key? params.mld_key : -1);
  var melder_key = (params.melder_key? params.melder_key : -1);
  var opdr_type = (params.opdr_type? params.opdr_type : -1);
  var opdr_type_org = (params.opdr_type_org? params.opdr_type_org : -1);
  var opdr_key = (params.opdr_key? params.opdr_key : -1);
  var reado = (params.reado? params.reado : false);
  var canDeleteAttachment = ("canDeleteAttachment" in params ? params.canDeleteAttachment : true);
  var cancel = (params.cancel? params.cancel : false);
  var halt = (params.halt? params.halt : false);
  var close = (params.close? params.close : false);
  var finish = (params.finish? params.finish : false);
  var afgerond = 0;
  var showClose = (params.showClose? params.showClose : close);
  var copy = (params.copy? params.copy : false);
  var opdr_status = (params.opdr_status? params.opdr_status : -1);
  var advanced = (params.advanced? params.advanced : false); // Geavanceerd
  var niveau = params.niveau;
  var prs_key = (params.prs_key? params.prs_key : -1); // Perslid key
  var forward = params.forward;
  var hasfilter = params.hasfilter? params.hasfilter : null;
  var multiEdit = params.multiEdit? params.multiEdit : false;

  // userhasORDSUP true betekent: user mag opdracht flexkenmerken rolcode 4 (voorheen > 900) zien/editen
  var userhasORDSUP = user.has("WEB_ORDSUP");
  // heeft dit nog enige relatie met mresult.canWrite("WEB_MLDAFR") && S("mld_afrond_canflex")?


  var mld_status = -1;
  if (mld_key > 0)
  {
    var sqls = "SELECT mld_melding_status"
             + "  FROM mld_melding"
             + " WHERE mld_melding_key = " + mld_key;
    var oRss = Oracle.Execute(sqls);
    mld_status = oRss("mld_melding_status").Value;
    oRss.Close();
  }

  if (stdm_arr.length != 0 && disc_arr.length == 0)
  {
    var sql = "SELECT mld_ins_discipline_key"
            + "  FROM mld_stdmelding s"
            + " WHERE s.mld_stdmelding_key IN (" + stdm_arr.join(",") + ")";
    var oRs = Oracle.Execute(sql);
    disc_arr = [(oRs("mld_ins_discipline_key").Value)];
    oRs.Close();
  }

  var canViewConfidential = false;
  if (mld_key < 0 || copy || disc_arr.length > 1)
  { // Het is een nieuwe melding
    var my_mldrechten = user.func_enabled("MLD", disc_arr.join(",")); // mld.func_enabled_melding is nauwkeuriger maar overkill?
    my_mldrechten.canFEwrite = my_mldrechten.canWrite("WEB_MLDUSE"); // Er moet ook gelden dat het mijn melding is. Dat is het geval want het is een nieuwe melding die ik zelf invoer en aanmaak.
  }
  else
  {
    var my_mldrechten = params.this_mld || mld.func_enabled_melding(mld_key);
    // Bij het doorsturen van een melding wordt showConfidential (canViewConfidential) niet meegegeven. Dan hier maar canViewConfidential bepalen of ik vertrouwlijke waarden mag zien.
    canViewConfidential = opdr_type < 0 && opdr_key < 0 && stdm_arr.length != 0 && mld_key > 0 && my_mldrechten.canViewConfidential; // Wijzigen melding.
  }

  var otherKenmerkPath = "null";
  var sql_waarde = "";

  // Load existing or default values. Try to maintain values when changing type as well
  // Onderscheid vier gevallen:
  // 1) wijzigen opdracht of geavanceerd,
  // 2) wijzigen melding,
  // 3) aanmaken opdracht,
  // 4) aanmaken melding of geavanceerd.
  var changeOpdracht = false;
  var changeMelding = false;
  var newOpdracht = false;
  var newMelding = false;
  var advancedOpdracht = false;
  var advancedMelding = false;
  var advancedNoOpdrtype = false;
  var advancedNoFilter = false;

  if (opdr_type > 0 && opdr_key > 0)
    changeOpdracht = true;                   // Wijzigen opdracht
  else if (stdm_arr.length != 0 && mld_key > 0)
    changeMelding = true;                    // Wijzigen melding
  else if (opdr_type > 0 && mld_key > 0)
    newOpdracht = true;                      // Aanmaken opdracht
  else if (niveau == "O" && opdr_type > 0 && advanced && opdr_key < 0 && mld_key < 0)
    advancedOpdracht = true;                 // Opvragen opdracht kenmerken voor lijsten (Geavanceerd)
  else if (niveau == "O" && opdr_type < 0 && advanced && opdr_key < 0 && mld_key < 0)
    advancedNoOpdrtype = true;
  else if ((stdm_arr.length != 0 || disc_arr.length != 0 || srtdisc.length != 0) && advanced && opdr_key < 0 && mld_key < 0)
    advancedMelding = true;                  // Opvragen melding kenmerken voor lijsten (Geavanceerd)
  else if (stdm_arr.length == 0 && srtdisc.length == 0 && disc_arr.length == 0 && advanced && opdr_key < 0 && mld_key < 0)
    advancedNoFilter = true;
  else // (stdm_arr.length != 0 && mld_key < 0)
    newMelding = true;                       // Aanmaken melding

  var adv_arr = [];
  if (advanced)
  {
    var sql_adv = "SELECT distinct ins_discipline_key"
                + "  FROM fac_v_my_disciplines"
                + " WHERE fac_gebruiker_alg_level_read < 9"
                + "   AND fac_gebruiker_prs_level_read < 9"
                + "   AND fac_functie_code IN ('WEB_MLDBOF','WEB_MLDFOF','WEB_MLDBAC','WEB_ORDBOF')"
                + "   AND prs_perslid_key = " + user_key;
    var oRs_adv = Oracle.Execute(sql_adv);
    while (!oRs_adv.eof)
    {
        adv_arr.push(oRs_adv("ins_discipline_key").Value);
        oRs_adv.MoveNext();
    }
    oRs_adv.Close();
  }

  var sql_filter = "";
  // 1) Wijzigen opdracht of geavanceerd
  if (changeOpdracht || advancedOpdracht || advancedNoOpdrtype)
  { // Bestaande opdrachtkenmerk waarden of kopiëren
    if (copy || (opdr_type_org > 0 && opdr_type_org != opdr_type))
    { // Kopieeer eventueel flexfiles
      otherKenmerkPath = "(SELECT 'MLD/" + subfolderKey("O", opdr_key) + "/' || mld_kenmerk_key"
                       + "   FROM mld_kenmerk k2"
                       + "      , mld_srtkenmerk t2"
                       + "  WHERE (k2.mld_typeopdr_key = " + opdr_type_org + " OR k2.mld_typeopdr_key IS NULL)"
                       + "    AND k2.mld_kenmerk_niveau = k.mld_kenmerk_niveau"
                       + "    AND t2.mld_srtkenmerk_kenmerktype = 'M'"
                       + "    AND k2.mld_kenmerk_verwijder IS NULL"
                       + "    AND k2.mld_srtkenmerk_key = t2.mld_srtkenmerk_key"
                       + "    AND COALESCE(k2.mld_kenmerk_omschrijving, t2.mld_srtkenmerk_omschrijving) = "
                       + "        COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)"
                       + "    AND BITAND(t2.mld_srtkenmerk_systeem,4) = 0"  // niet als vertrouwelijk
                       + "    AND k2.mld_kenmerk_groep = k.mld_kenmerk_groep"
                       + "    AND t2.mld_srtkenmerk_verwijder IS NULL"
  	                   + "    AND t2.mld_srtkenmerk_key = t.mld_srtkenmerk_key)";
    }

    // Doordat we in de query controleren tegen opdr_type_org is er het gewenste
    // neveneffect dat de waardes behouden blijven bij (achteraf) wisselen
    // van type opdracht
    // Die check is trouwens redelijk redundant ware het niet dat er wat
    // datavervuiling is wat een 'subselect return more than one row' kan
    // geven in extreme situaties


    sql_waarde = " (SELECT mld_kenmerkopdr_waarde"
               + "   FROM mld_kenmerkopdr v"
               + "      , mld_kenmerk vk"
               + "      , mld_srtkenmerk vt"
               + "  WHERE v.mld_opdr_key = " + opdr_key
               + "    AND v.mld_kenmerk_key = vk.mld_kenmerk_key"
               + "    AND (vk.mld_typeopdr_key = " + opdr_type_org + " OR vk.mld_typeopdr_key IS NULL)"
               + "    AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key"
               + "    AND COALESCE(vk.mld_kenmerk_omschrijving, vt.mld_srtkenmerk_omschrijving) = "
               + "        COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)"
               + "    AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key"
               + "    AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep"
               + "    AND v.mld_kenmerkopdr_verwijder IS NULL"
               + "    AND vk.mld_kenmerk_niveau = k.mld_kenmerk_niveau"
               + "    AND mld_srtkenmerk_kenmerktype <> 'M'"
               + " )";

    sql_filter = "       mld_typeopdr s"
               + " WHERE " + (advancedNoOpdrtype ? "(1=1)" : "(s.mld_typeopdr_key = " + opdr_type + " OR s.mld_typeopdr_key IS NULL)")
               + "   AND (k.mld_typeopdr_key = s.mld_typeopdr_key(+)"
               + "   AND k.mld_kenmerk_niveau IN ('P', 'O'))";

  }
  // 2) Wijzigen melding
  else if (changeMelding)
  { // Existing melding kenmerk values. stdm_arr heeft nu 1 waarde
    // Doordat we in de query controleren tegen old_stdm is er het gewenste
    // neveneffect dat de waardes behouden blijven bij (achteraf) wisselen
    // van standaardmelding
    oRs = Oracle.Execute("SELECT mld_stdmelding_key, mld_melding_afgerond FROM mld_melding WHERE mld_melding_key = " + mld_key);
    old_stdm = oRs("mld_stdmelding_key").Value;
    afgerond = oRs("mld_melding_afgerond").Value;
    oRs.Close();
    if (old_stdm != stdm_arr)
    { // De stdmelding is gewijzigd. De kenmerken (keys) veranderen daardoor ook.
      __Log("Old MLD_STDMELDING_KEY: " + old_stdm + " New: " + stdm_arr.join(","));

      // Flexkenmerken kopiëren
      // Als wordt gekopieerd naar een ander type, dan komen de flexkenmerken mee
      // - als ze van hetzelfde srtkenmerk zijn
      // - en de kenmerkgroep overeenkomt, kan leeg zijn
      // - en het label overeenkomst, kan leeg zijn = die van srtkenmerk
      sql_waarde = "(SELECT v.mld_kenmerkmelding_waarde"
                 + "  FROM mld_kenmerkmelding v"
                 + "     , mld_kenmerk vk"
                 + "     , mld_srtkenmerk sk"
                 + " WHERE v.mld_melding_key = " + mld_key
                 + "   AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key"
                 + "   AND vk.mld_srtkenmerk_key = sk.mld_srtkenmerk_key"
                 // Maak het mogelijk hetzelfde soortkenmerk met hetzelfde label vaker te gebruiken in een andere groep
                 + "  AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep"
                 // Maak het mogelijk hetzelfde soortkenmerk met een ander label te hergebruiken
                 + "   AND COALESCE (vk.mld_kenmerk_omschrijving, sk.mld_srtkenmerk_omschrijving) = "
                 + "       COALESCE (k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)"
                 + "   AND v.mld_kenmerk_key = vk.mld_kenmerk_key)";

      if (forward)
        sql_filter = "    (SELECT mkn.mld_kenmerk_key"
                   + "          , mkn.mld_srtkenmerk_key"
                   + "          , COALESCE(mkn.mld_kenmerk_omschrijving, skn.mld_srtkenmerk_omschrijving) omschrijving"
                   + "       FROM mld_kenmerk mkn"
                   + "          , mld_srtkenmerk skn"
                   + "          , mld_stdmelding sn"
                   + "          , mld_discipline dn"
                   + "      WHERE sn.mld_ins_discipline_key = dn.ins_discipline_key"
                   + "        AND mkn.mld_srtkenmerk_key = skn.mld_srtkenmerk_key"
                   + "        AND ((mkn.mld_stdmelding_key IS NULL"
                   + "          AND mkn.mld_kenmerk_niveau = 'A')"
                   + "          OR (mkn.mld_stdmelding_key = sn.mld_stdmelding_key"
                   + "          AND mkn.mld_kenmerk_niveau = 'S')"
                   + "          OR (mkn.mld_stdmelding_key = sn.mld_ins_discipline_key"
                   + "          AND mkn.mld_kenmerk_niveau = 'D')"
                   + "          OR (mkn.mld_stdmelding_key = dn.ins_srtdiscipline_key"
                   + "          AND mkn.mld_kenmerk_niveau = 'T'))"
                   + "        AND mkn.mld_kenmerk_verwijder IS NULL"
                   + "        AND (sn.mld_stdmelding_key = " + old_stdm
                   + "          OR sn.mld_stdmelding_key IS NULL)) kenm_old,";
    }
    else
    { // Wijzigen van de melding waarbij de stdmelding niet wijzigt.
      sql_waarde = " (SELECT v.mld_kenmerkmelding_waarde"
                 + "     FROM mld_kenmerkmelding v"
                 + "    WHERE v.mld_melding_key = " + mld_key
                 + "      AND v.mld_kenmerk_key = k.mld_kenmerk_key"
                 + "      AND v.mld_kenmerkmelding_verwijder IS NULL)";

    }

    sql_filter += "       mld_stdmelding s"
                + "     , mld_discipline d"
                + " WHERE s.mld_stdmelding_key IN (" + stdm_arr.join(",") + ")"
                + "   AND s.mld_ins_discipline_key = d.ins_discipline_key"
                + "   AND ((k.mld_stdmelding_key IS NULL"
                + "         AND k.mld_kenmerk_niveau = 'A')"
                + "     OR (k.mld_stdmelding_key = s.mld_stdmelding_key"
                + "         AND k.mld_kenmerk_niveau = 'S')"
                + "     OR (k.mld_stdmelding_key = s.mld_ins_discipline_key"
                + "         AND k.mld_kenmerk_niveau = 'D')"
                + "     OR (k.mld_stdmelding_key = d.ins_srtdiscipline_key"
                + "         AND k.mld_kenmerk_niveau = 'T'))"
                + (cancel
                  ? " AND (k.mld_kenmerk_verplicht_status = 1)"
                  : "")
                + (old_stdm != stdm_arr && forward
                  ? " AND k.mld_srtkenmerk_key = kenm_old.mld_srtkenmerk_key(+)"
                    + " AND COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving) = kenm_old.omschrijving(+)"
                  : "");
                + (forward // Alle velden, behalve die met bestanden, tonen i.v.m. doorsturen melding.
                  ? " AND t.mld_srtkenmerk_kenmerktype NOT IN ('F', 'E', 'M')"
                  : "");
  }
  // 3) Aanmaken opdracht
  else if (newOpdracht)
  { // New opdr, copy parent's melding kenmerk values or take default
    // The kenmerk_key of an opdr-kenmerk is always different from the mld-kenmerk
    // To be copied, the srtkenmerk_key, mld_kenmerk_groep and mld_kenmerk_omschrijving must match
    // And the kenmerk must have a value (or it would be useless to copy)
    __Log("About to copy kenmerk values from parent: " + mld_key);
    sql_waarde = " COALESCE((SELECT v.mld_kenmerkmelding_waarde"
               + "              FROM mld_kenmerkmelding v"
               + "                 , mld_kenmerk vk"
               + "                 , mld_srtkenmerk vt"
               + "             WHERE v.mld_melding_key = " + mld_key
               + "               AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key"
               + "               AND COALESCE(vk.mld_kenmerk_omschrijving, vt.mld_srtkenmerk_omschrijving) = "
               + "                   COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)"
               + "               AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key"
               + "               AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep"
  	           // NIET! + "               AND vk.mld_kenmerk_niveau = k.mld_kenmerk_niveau"
  	           + "               AND v.mld_kenmerk_key = vk.mld_kenmerk_key"
               + "               AND v.mld_kenmerkmelding_verwijder IS NULL), " + lcl.xsql('k.mld_kenmerk_default','k.mld_kenmerk_key') + ")";

    // Kopieer eventueel flexfiles
    otherKenmerkPath = " (SELECT 'MLD/" + subfolderKey("M", mld_key) + "/' || mld_kenmerk_key "
                    + "     FROM mld_melding m"
                    + "        , mld_kenmerk k2"
                    + "        , mld_srtkenmerk t2"
                    + "        , mld_stdmelding s"
                    + "        , mld_discipline d"
                    + "    WHERE m.mld_melding_key = " + mld_key
                    + "      AND s.mld_stdmelding_key = m.mld_stdmelding_key"
                    + "      AND k2.mld_kenmerk_groep = k.mld_kenmerk_groep"
                    + "      AND s.mld_ins_discipline_key = d.ins_discipline_key"
                    + "      AND ((k2.mld_stdmelding_key IS NULL"
                    + "            AND k2.mld_kenmerk_niveau = 'A')"
                    + "        OR (k2.mld_stdmelding_key = s.mld_stdmelding_key"
                    + "            AND k2.mld_kenmerk_niveau = 'S')"
                    + "        OR (k2.mld_stdmelding_key = s.mld_ins_discipline_key"
                    + "            AND k2.mld_kenmerk_niveau = 'D')"
                    + "        OR (k2.mld_stdmelding_key = d.ins_srtdiscipline_key"
                    + "            AND k2.mld_kenmerk_niveau = 'T'))"
                    //+ "      AND k2.mld_kenmerk_niveau = k.mld_kenmerk_niveau"
                    + "      AND mld_srtkenmerk_kenmerktype IN ('E', 'F', 'M')"
                    + "      AND k2.mld_kenmerk_verwijder IS NULL"
                    + "      AND k2.mld_srtkenmerk_key = t2.mld_srtkenmerk_key"
                    + "      AND t2.mld_srtkenmerk_verwijder IS NULL"
                    + "      AND COALESCE(k2.mld_kenmerk_omschrijving, t2.mld_srtkenmerk_omschrijving) = "
                    + "          COALESCE(k.mld_kenmerk_omschrijving, t.mld_srtkenmerk_omschrijving)"
                    + "      AND t2.mld_srtkenmerk_key = t.mld_srtkenmerk_key)";

    sql_filter = "       mld_typeopdr s"
               + " WHERE (s.mld_typeopdr_key = " + opdr_type + " OR s.mld_typeopdr_key IS NULL)"
               + "   AND (k.mld_typeopdr_key = s.mld_typeopdr_key(+)"
               + "   AND k.mld_kenmerk_niveau IN ('P', 'O'))";
    if (newOpdracht && params.mobile)
      sql_filter += " AND t.mld_srtkenmerk_kenmerktype <> 'M'"
  }
  // 4) Aanmaken melding of of geavanceerd
  else
  { // Dan blijf een nieuwe melding over of geavanceerd meldingen: gebruik default waarden
    sql_waarde = " "+ lcl.xsql('k.mld_kenmerk_default','k.mld_kenmerk_key');

    if (stdm_arr.length != 0 || newMelding)
    {
      var x_key = "s.mld_stdmelding_key";
      if (stdm_arr.length)
          var x_arr = stdm_arr;
      else
          var x_arr = [-1]; // Vals spelen
    }
    else if (disc_arr.length != 0)
    {
      var x_key = "s.mld_ins_discipline_key";
      var x_arr = disc_arr;
    }
    else if (srtdisc.length != 0)
    {
      var x_key = "d.ins_srtdiscipline_key";
      var x_arr = srtdisc;
    }
    sql_filter = "       mld_stdmelding s, mld_discipline d"
               + " WHERE " + (advancedNoFilter ? "(1=1)" : x_key + " IN (" + x_arr.join(",") + ")" )
               + (adv_arr.length != 0
                 ? " AND s.mld_ins_discipline_key IN (" + adv_arr.join(",") + ")"
                 : "")
               + "   AND s.mld_ins_discipline_key = d.ins_discipline_key"
               + "   AND (  (   k.mld_stdmelding_key IS NULL"
               + "          AND k.mld_kenmerk_niveau = 'A')"
               + "       OR (   k.mld_stdmelding_key = d.ins_srtdiscipline_key"
               + "          AND k.mld_kenmerk_niveau = 'T')"
               + (advanced || disc_arr.length != 0 || stdm_arr.length != 0
                 ? "     OR (   k.mld_stdmelding_key = s.mld_ins_discipline_key"
                   + "      AND k.mld_kenmerk_niveau = 'D')"
                 : "")
               + (advanced || stdm_arr.length != 0
                 ? "     OR (   k.mld_stdmelding_key = s.mld_stdmelding_key"
                   + "      AND k.mld_kenmerk_niveau = 'S')"
                 : "")
               + "       )"
               + (multiEdit
                 ? "  AND t.mld_srtkenmerk_kenmerktype NOT IN ('Q','L','l','b','F','M','E','X')"
                 + "  AND k.mld_kenmerk_toonbaar IS NULL"
                 : ""
                 );
  }

  if (changeOpdracht || changeMelding)
  {
    // Een flexkenmerk mag niet gekopieerd worden als hiervoor het mld_kenmerk_wissen bit is gezet voor de betreffende actie.
    var sql_wissen = " CASE WHEN ((BITAND(k.mld_kenmerk_wissen, 1) = 1) AND (" + (params.copy?1:0)    + "=1))"
                   + "      THEN k.mld_kenmerk_default"
                   + "      WHEN ((BITAND(k.mld_kenmerk_wissen, 2) = 2) AND (" + (params.forward?1:0) + "=1))"
                   + "      THEN ''"
                   + "      ELSE {0}"
                   + "  END";

    sql_waarde = sql_wissen.format(sql_waarde);
    otherKenmerkPath = sql_wissen.format(otherKenmerkPath);
  }

  // Bij 'advanced' groeperen we op mld_srtkenmerk_key ipv mld_kenmerk_key
  // in de zoek-html komt uiteindelijk de srtkenmerk_key te staan
  // in getkenmerksql.inc wordt dat voor MLD weer intelligent opgepikt
  var afd_key = -1;
  if (melder_key > 0 && (changeMelding || newMelding))
    afd_key = new Perslid(melder_key).prs_afdeling_key(); // afdeling van de melder!

  var autfunction = mld_status == 0? "WEB_MLDFOF" : "WEB_MLDBOF";
  var sql_prs_in_team = "(SELECT p.prs_perslid_key"
                      + "   FROM prs_perslid p"
                      + "      , prs_v_afdeling d"
                      + "  WHERE p.prs_perslid_key IN"
                      + "            (SELECT prs_perslid_key"
                      + "               FROM fac_v_webgebruiker g"
                      + "              WHERE g.fac_functie_key = " + F(autfunction)
                      + "                AND g.ins_discipline_key = " + (mld_key > 0? "kbm.ins_discipline_key" : "k.ins_discipline_key") // Ingevulde tertaire behandelteam bij bestaande melding, anders het default behandelteam.
                      + "                AND (g.fac_gebruiker_prs_level_write = -1"
                      + "                  OR (g.fac_gebruiker_prs_level_write = 0"
                      + "                  AND d.prs_bedrijf_key ="
                      + "                      (SELECT aa.prs_bedrijf_key"
                      + "                         FROM prs_v_afdeling aa"
                      + "                        WHERE aa.prs_afdeling_key = " + afd_key + "))"
                      + "                  OR (g.fac_gebruiker_prs_level_write > 0"
                      + "                  AND p.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 = " + afd_key
                      + "                                          AND aa.niveau = g.fac_gebruiker_prs_level_write))"
                      + "                    )"
                      + "            )"
                      + (loc_key > 0
                        ? "  AND (g.fac_gebruiker_alg_level_write = -1"
                          + "  OR (g.fac_gebruiker_alg_level_write < 9"
                          + "      AND " + loc_key + " IN "
                          + "          (SELECT alg_locatie_key FROM fac_v_my_locations "
                          + "            WHERE prs_perslid_key = p.prs_perslid_key"
                          + "              AND niveau = fac_gebruiker_alg_level_write)"
                          + "     ))"
                        : "")
                      + "    AND prs_perslid_verwijder IS NULL"
                      + "    AND p.prs_afdeling_key = d.prs_afdeling_key"
                      + "    AND (prs_perslid_oslogin IS NULL OR prs_perslid_oslogin NOT LIKE '\\_%' ESCAPE '\\')"
                      + "    AND BITAND(prs_perslid_flags, 2) = 0)"
                      + ")";

  var behandelblok_select =
            (mld_key == -1
            // Nieuwe melding.
            // Waarde behandelblok voor nieuwe melding (mld_key == -1)
            // 0) Kenmerk valt niet onder een behandelbaar blok:          Afhankelijk van pvolgnummer. TODO nagaan
            // 3) Geen behandelteam ingevuld (default geen invloed):      Afhankelijk van rechten.
            ? "   CASE"
              + " WHEN t.mld_srtkenmerk_kenmerktype != 'b'"
              + " THEN 0"
              + " ELSE 3"
              + " END"
            : ((changeMelding || newMelding) && afd_key > 0)
              ? "   CASE"
              // Waarde behandelblok voor beataande melding (mld_key > 0)
              // 0) Kenmerk valt niet onder een behandelbaar blok:        Afhankelijk van pvolgnummer. TODO nagaan
              // 1) Behandelteam ingevuld en user zit in het team:        Blok altijd tonen.
              // 2) Behandelteam ingevuld en user zit NIET in het team:   Blok niet tonen.
              // 3) Geen behandelteam ingevuld:                           Afhankelijk van rechten.
                + " WHEN t.mld_srtkenmerk_kenmerktype != 'b'"
                + " THEN 0"
                + " WHEN kbm.ins_discipline_key IS NULL"
                + " THEN 3"
                + " WHEN " + user_key + " IN (" + sql_prs_in_team + ")"
                + " THEN 1"
                + " ELSE 2"
                + " END"
              : " 0");

  var sql = "SELECT DISTINCT k.mld_kenmerk_key kenmerk_key"
          + "     , 1                          kenmerk_key_count"
          + "     , k.mld_srtkenmerk_key       srtkenmerk_key"
          + "     , k.mld_typeopdr_key"
          + "     , k.mld_stdmelding_key"
          + "     , k.mld_kenmerk_niveau"
          + "     , " // Anders werkt Advance zoeken met logging soms niet goed: + (__Logging > 0? " k.mld_kenmerk_niveau || ':' ||" : "") // Lettertje ervoor bij logging
            + "       COALESCE (" + lcl.xsql("k.mld_kenmerk_omschrijving", "k.mld_kenmerk_key")
            + "              ,  " + lcl.xsql("t.mld_srtkenmerk_omschrijving", "t.mld_srtkenmerk_key") + ") kenmerk_omschrijving"
          + "     , t.mld_srtkenmerk_kenmerktype     kenmerk_kenmerktype"
          + "     , t.fac_kenmerkdomein_key          kenmerkdomein_key"
          + "     , t.mld_srtkenmerk_lengte          kenmerk_lengte"
          + "     , t.mld_srtkenmerk_dec             kenmerk_dec"
          + "     , t.mld_srtkenmerk_nmin            kenmerk_nmin"
          + "     , t.mld_srtkenmerk_nmax            kenmerk_nmax"
          + "     , t.mld_srtkenmerk_systeem         kenmerk_systeem"
          + "     , " + sql_waarde + "               kenmerk_waarde"
          + "     , k.mld_kenmerk_volgnummer         kenmerk_volgnr"
          + "     , k.mld_kenmerk_rolcode            kenmerk_rolcode"
          + "     , k.mld_kenmerk_groep              kenmerk_groep"
          + "     , " + lcl.xsql("t.mld_srtkenmerk_dimensie", "t.mld_srtkenmerk_key") + " kenmerk_dimensie"
          + "     , " + lcl.xsql("k.mld_kenmerk_hint", "k.mld_kenmerk_key") + " kenmerk_hint"
          + "     , " + lcl.xsql("k.mld_kenmerk_default", "k.mld_kenmerk_key") + " kenmerk_default"
          + "     , k.mld_kenmerk_show_expr          kenmerk_show_expr "
          + "     , CASE"
          + "       WHEN k.mld_kenmerk_verplicht = 1" // groepsverplichting blijft nog even buiten beschouwing
          + ((cancel || opdr_status == 1)
            ? "       OR (k.mld_kenmerk_verplicht_status = 1)"
            : "")
          + (close
            ? "       OR (k.mld_kenmerk_verplicht_status = 5)"
            : "")
          + (afgerond
            ? "       OR (k.mld_kenmerk_verplicht_status = 52)"
            : "")
          // Characteristic is required when 1) Order has characteristic-required-status 6 (=closed) and 2) order-status is 6 (=closed) or 9 (=completed)
          + (close || opdr_status == 6 || opdr_status == 9
            ? "       OR (k.mld_kenmerk_verplicht_status = 6)"
            : "")
          + (finish || opdr_status == 9
            ? "       OR (k.mld_kenmerk_verplicht_status = 9)"
            : "")
          + "       THEN 1 ELSE k.mld_kenmerk_verplicht END kenmerk_verplicht"
          + "     , k.mld_kenmerk_verplicht_status   kenmerk_verplicht_status"
          + "     , k.mld_kenmerk_obligation_fill    kenmerk_obligation"
          + "     , " + otherKenmerkPath + " otherpath"   // corresponderende pad voor copy/move folder
          + "     , k.mld_kenmerk_toonbaar           kenmerk_toonbaar"         //  1=Alleen toonbaar (readonly)
          + "     , k.mld_kenmerk_uniek              kenmerk_uniek"
          + "     , k.mld_kenmerk_regexp             kenmerk_regexp"
          + "     , k.fac_functie_key"
          + (mld_key == -1
            // Nieuwe melding.
            ? "   , k.ins_discipline_key blokbehandelteam"
              + " , NULL blokbehandelaar"
              + " , NULL blokafmelddatum"
              + " , " + behandelblok_select + " behandelblok"
            // Bestaande melding.
            : (changeMelding && old_stdm != stdm_arr && forward
                ? "     , (SELECT kbm2.ins_discipline_key"
                  + "        FROM mld_kenmerkblokmelding kbm2"
                  + "       WHERE kbm2.mld_melding_key = " + mld_key
                  + "         AND kbm2.mld_kenmerk_key = kenm_old.mld_kenmerk_key) blokbehandelteam"
                  + "   , (SELECT kbm2.prs_perslid_key"
                  + "        FROM mld_kenmerkblokmelding kbm2"
                  + "       WHERE kbm2.mld_melding_key = " + mld_key
                  + "         AND kbm2.mld_kenmerk_key = kenm_old.mld_kenmerk_key) blokbehandelaar"
                  + "   , (SELECT kbm2.mld_kenmerkblokmelding_afmelddatum"
                  + "        FROM mld_kenmerkblokmelding kbm2"
                  + "       WHERE kbm2.mld_melding_key = " + mld_key
                  + "         AND kbm2.mld_kenmerk_key = kenm_old.mld_kenmerk_key) blokafmelddatum"
                : "     , kbm.ins_discipline_key blokbehandelteam"
                  + "   , kbm.prs_perslid_key blokbehandelaar"
                  + "   , kbm.mld_kenmerkblokmelding_afmelddatum blokafmelddatum")
              + " , " + behandelblok_select + " behandelblok")
          + "  FROM mld_srtkenmerk t"
          + "     , mld_kenmerk k"
          + (mld_key > 0
            ? "     , mld_kenmerkblokmelding kbm"
            : "")
          + "     , " + sql_filter
          + "   AND k.mld_kenmerk_verwijder IS NULL"
          + "   AND k.mld_srtkenmerk_key = t.mld_srtkenmerk_key"
          + (mld_key > 0
            ? "   AND k.mld_kenmerk_key = kbm.mld_kenmerk_key(+)"
            + "   AND kbm.mld_melding_key(+) = " + mld_key
            : "")
          + "   AND t.mld_srtkenmerk_verwijder IS NULL"
          + "   AND (  (t.mld_srtkenmerk_kenmerktype = 'M'"   // bijlagen niet meenemen als deze gewist moeten worden
          + "          AND CASE WHEN ((BITAND(k.mld_kenmerk_wissen, 1) = 1) AND (" + (params.copy?1:0)    + "=1))"
                       + "      THEN k.mld_kenmerk_default"
                       + "      WHEN ((BITAND(k.mld_kenmerk_wissen, 2) = 2) AND (" + (params.forward?1:0) + "=1))"
                       + "      THEN ''"
                       + "      ELSE '1'"
                       + "  END = '1'"
          + "          )"
          + "       OR (t.mld_srtkenmerk_kenmerktype <> 'M')"
          + "       )";

  var sql1 = "";

  if (changeOpdracht || newOpdracht || advancedOpdracht || advancedNoOpdrtype)
  {
    // ** FLEXKENMERKEN VAN OPDRACHT **
    // Wat mag ik op basis van mijn autorisatie en deze situatie zien, bepaal mijn rolcode-masker
    // Bij een nieuwe opdracht mag ik geen afmeld-kenmerken zien, ook al heb ik daar rechten op.
    //
    // Merk op dat er een grote statusafhankelijkheid is, die in .canChange verwerkt zit.
    // en dat dit een nog niet zo fraaie vertaling is van de voormalige volgnummers
    // Semantisch zijn het (1) opdrachtkenmerken, (2) afmeldkenmerken en (4) financiele kenmerken

    var myreadrolcode = 0 + (true ? 1 : 0)  // lijkt me impliciet iets van canReadORDBOF
                          + ((showClose || opdr_status == 6 || opdr_status == 7) && changeOpdracht && !copy ? 2 : 0)
                          + (userhasORDSUP ? 4 : 0);

    sql1 = " AND BITAND(k.mld_kenmerk_rolcode, " + myreadrolcode + ") > 0";

    if (close || cancel)
    {
      var arrGroep = [];
      if (opdr_type > 0)
      { // select groups required for close
        var groepSql = "SELECT DISTINCT mld_kenmerk_groep "
                     + "  FROM mld_kenmerk "
                     + " WHERE     mld_kenmerk_verplicht_status = " + (cancel ? "1" : "6")
                     + "       AND mld_kenmerk_groep <> 0 "
                     + "       AND mld_kenmerk_verwijder IS NULL "
                     + "       AND mld_typeopdr_key = " + opdr_type;
        var oRsGroep = Oracle.Execute(groepSql);
        while (!oRsGroep.eof)
        {
          arrGroep.push(oRsGroep("mld_kenmerk_groep").Value);
          oRsGroep.MoveNext();
        }
        oRsGroep.Close();
      }

      // Bij "Afmelden" de verplichte, niet ingevulde, afmelden kenmerken tonen
      sql1 += " AND ((k.mld_kenmerk_verplicht_status = " + (cancel ? "1" : "6")
            + (arrGroep.length? "   OR k.mld_kenmerk_groep IN (" + arrGroep.join(",") + "))" : ")")
            + " AND " + sql_waarde + " IS NULL"
            + (close && S("mld_afmelden_popup_for_all_km") == 1 ?  // Tenzij bijlages optioneel zijn bij het opslaan
                  " OR BITAND(k.mld_kenmerk_rolcode, 2) > 0" : "")  // x1x
                  +")";
    }

    if (changeOpdracht || newOpdracht)
    {
        if (halt)
          sql1 += " AND k.mld_kenmerk_onderbreken > 0"; // Bij "Onderbreken" de onderbreken kenmerken tonen.
        else if (!reado)
          // Edit mode.
          sql1 += " AND k.mld_kenmerk_onderbreken = 0"; // In de edit mode GEEN onderbreken kenmerken tonen.
    }
  }
  else
  {
    // ** FLEXKENMERKEN VAN MELDING **
    // changeMelding || newMelding || advancedMelding

    // Hier worden conditities toegevoegd om kenmerken die ik op grond van autorisatie niet mag zien (laat staan editen)
    // helemaal achterwege te laten. Later wordt van het resultaat nog bepaald of en hoe deze gepresenteerd moeten worden.
    // Als je blokbehandelaar bent, dan mag je die kenmerken van de melding zien ongeacht de rolcode.
    // Bewerk-, en zichtbaarheid van behandelblokken regelen we verder in resp. isReadonly & isInvisible

    // Wat mag ik op basis van mijn autorisatie en deze situatie zien, bepaal mijn rolcode-masker
    var myreadrolcode = 0 + (my_mldrechten.canRead("WEB_MLDUSE") ? 1 : 0)
                          + (my_mldrechten.canRead("WEB_MLDFOF") || my_mldrechten.canRead("WEB_MLDBO2") || my_mldrechten.canRead("WEB_MLDBO3") || my_mldrechten.canRead("WEB_MLDORD") || my_mldrechten.canRead("WEB_MLDBAC") ? 2 : 0)
                          + (my_mldrechten.canRead("WEB_MLDBOF") || my_mldrechten.canRead("WEB_MLDBAC") ? 4 : 0);

    // dit onderscheid heeft geen functioneel effect, maar bespaart de moeite als je niks met kenmerkblok doet.
    if (my_mldrechten.canChangeKenmerkBlok)
    {
      sql1 += " AND (" + behandelblok_select + " <> 0"
            + "      OR BITAND(k.mld_kenmerk_rolcode, " + myreadrolcode + ") > 0)";
    } else {
      sql1 = " AND BITAND(k.mld_kenmerk_rolcode, " + myreadrolcode + ") > 0";
    }

    if (close || cancel)
    {
      sql1 += " AND CASE"
          + "       WHEN k.mld_kenmerk_verplicht = 1" // groepsverplichting blijft nog even buiten beschouwing
          + (cancel
            ? "       OR (k.mld_kenmerk_verplicht_status = 1)"
            : "")
          + (close
            ? "       OR (k.mld_kenmerk_verplicht_status = 5)"
            : "")
          + "       THEN 1 ELSE k.mld_kenmerk_verplicht END = 1";
      sql1 += " AND " + sql_waarde + " IS NULL"; // Bij "Afmelden" en "Annuleren" de verplichte, niet ingevulde, afmelden kenmerken tonen.
    }
  }

  sql = sql + sql1;

  if (advanced) // Nog harder de dubbelen er uit filteren. Een kenmerk kan bijvoorbeeld bij verschillende
  {             // objectsoorten een ander volgnummer hebben en dat interesseert ons echt niet.
                // Kenmerken van dezelfde kenmerksoort kunnen afwijkende labels (benamingen) hebben (FCLT#57667). Daarom niet het MIN nemen van kenmerk_omschrijving.
    sql = "SELECT MIN(kenmerk_key) kenmerk_key"
        + "     , count(kenmerk_key) kenmerk_key_count"
        + "     , srtkenmerk_key"
        + "     , MIN(mld_kenmerk_niveau)        mld_kenmerk_niveau"
        + "     , kenmerk_omschrijving           kenmerk_omschrijving"
        + "     , MIN(kenmerk_kenmerktype      ) kenmerk_kenmerktype"
        + "     , MIN(kenmerkdomein_key        ) kenmerkdomein_key"
        + "     , MIN(kenmerk_lengte           ) kenmerk_lengte"
        + "     , MIN(kenmerk_dec              ) kenmerk_dec"
        + "     , MIN(kenmerk_nmin             ) kenmerk_nmin"
        + "     , MIN(kenmerk_nmax             ) kenmerk_nmax"
        + "     , MIN(kenmerk_systeem          ) kenmerk_systeem"
        + "     , MIN(kenmerk_waarde           ) kenmerk_waarde"
        + "     , MIN(kenmerk_volgnr           ) kenmerk_volgnr"
        + "     , MIN(kenmerk_rolcode          ) kenmerk_rolcode"
        + "     , MIN(kenmerk_groep            ) kenmerk_groep"
        + "     , MIN(kenmerk_dimensie         ) kenmerk_dimensie"
        + "     , MIN(kenmerk_hint             ) kenmerk_hint"
        + "     , MIN(kenmerk_default          ) kenmerk_default"
        + "     , MIN(otherpath                ) otherpath"
        + "     , MIN(kenmerk_verplicht        ) kenmerk_verplicht"
        + "     , MIN(kenmerk_toonbaar         ) kenmerk_toonbaar"
        + "     , MIN(kenmerk_uniek            ) kenmerk_uniek"
        + "     , MIN(kenmerk_regexp           ) kenmerk_regexp"
        + "     , MIN(kenmerk_show_expr        ) kenmerk_show_expr"
        + "     , MIN(fac_functie_key          ) fac_functie_key"
        + "     , MIN(blokbehandelteam         ) blokbehandelteam"
        + "     , MIN(blokbehandelaar          ) blokbehandelaar"
        + "     , MIN(blokafmelddatum          ) blokafmelddatum"
        + (changeMelding || newMelding
          ? "     , MIN(behandelblok           ) behandelblok"
          : "")
        + "  FROM (" + sql + ")"
        + " GROUP BY srtkenmerk_key"
        + "        , kenmerk_omschrijving";
  }
	// Specifieke kenmerk_keys opgevraagd?
  if (params.kenmerk_keys && params.kenmerk_keys.length)
  {
    sql += " AND k.mld_kenmerk_key IN (" + params.kenmerk_keys.join(",") + ")"
  }
  sql = sql + " ORDER BY kenmerk_volgnr, UPPER(kenmerk_omschrijving), DECODE(mld_kenmerk_niveau, 'A', 0, 'T', 1, 'D', 2, 'S', 3)";
  // ik hoef hierna dus nooit kenmerken te onderdrukken, hooguit readonly maken

  if (changeOpdracht || newOpdracht || advancedOpdracht)
  {
    var kenmerk_module = "O";
    var key = opdr_key;
  }
  else
  {
    var kenmerk_module = "M";
    var key = mld_key;
  }

 /**
 * Bepaalt of een gegeven kenmerk in de UI alleen-lezen (readonly) moet zijn.
 * @param {object} oRs            Recordset-object met eigenschappen van het kenmerk.
 * @returns {boolean}             true als het kenmerk readonly moet zijn, anders false.
 */
  function isReadonly (oRs)
  {
    var prolcode = oRs("kenmerk_rolcode").value;
    var isBijlage = inArray(oRs("kenmerk_kenmerktype").Value, ["E", "F", "M"]);

    // Als "reado" meegegeven is dan altijd readonly (mobile bijlagen uitgezonderd)
    if (reado && !(params.mobile && isBijlage))
      return true;

    if (changeMelding || newMelding) // Advanced zoeken (advancedOpdracht) is nooit readonly
    { // Als de user een behandelaar van het blok is dat niet is afgemeld, dan zijn de kenmerken van dat blok altijd door de user te wijzigen.

      // Waarde [globale] behandelblok.
      // 0) Kenmerk valt niet onder een behandelbaar blok:        Afhankelijk van prolcode. TODO nagaan
      // 1) Behandelteam ingevuld en user zit in het team:        Blok altijd tonen.
      // 2) Behandelteam ingevuld en user zit NIET in het team:   Blok niet tonen.
      // 3) Geen behandelteam ingevuld:                           Afhankelijk van rechten.

      if (behandelblok > 0) {
        if (behandelblok == 1 && !blokisafgemeld)
          return false;
        // Als de user een behandelaar van het blok is dat is afgemeld, dan de kenmerken van dat blok readonly tonen.
        else if (blokisafgemeld)
          return true;
        // als ik alleen rechten op een kenmerkenblok had en geen canFlexChange rechten heb, dan het kenmerk readonly tonen.
        // die canFlexChange zit nu besloten in de rolcode, is dit dan nog goed zo?
        else if (!copy && mld_key > 0 && !(my_mldrechten.canFlexChange))
          return true;
        // else gelden de rechten.
      }
      // Dat was het behandelblok. Nu voor de normale kenmerken

      // Omgeschreven naar prolcode: wie mag zien en wijzigen:
      // prolcode & 1 : FE
      // prolcode & 2 : FO
      // prolcode & 4 : BO en AFR
      // dus wanneer is een kenmerk readonly? Precies andersom

      var canWrite = (  ((prolcode  & 1) && my_mldrechten.canFEwrite)) // het statusafhankelijke my_mldrechten.canFlexChange is hierboven al geregeld
                     || ((prolcode & 2) && my_mldrechten.canWrite("WEB_MLDFOF"))
                     || ((prolcode  & 4) && (my_mldrechten.canWrite("WEB_MLDBOF") || (my_mldrechten.canWrite("WEB_MLDAFR")&& S("mld_afrond_canflex")))
                     )
      return !canWrite;
    }
    // && my_mldrechten.canFoChangeBelow800 geelimineerd.

    if (changeOpdracht || newOpdracht) // Advanced zoeken (advancedOpdracht) is nooit readonly
    {
      if (opdr_status == 7)
        return true; // bij AV mag je nooit wijzigen

      // status 7 is nu dus sowieso weg

      // deze kenmerken mag je met de juiste (true/false) autorisatie sowieso bewerken
      if ((prolcode & 4) && userhasORDSUP)
        return false;

      // (Exclusief) afmeld-kenmerken mag je alleen tijdens het afmelden wijzigen
      if (prolcode == 2)
        return !showClose;

       // Wijzigen is verder mogelijk bij afwijzen (cancel) en afronden (close)
       // en in de statussen "Afgewezen(1)" en "Afgerond/Kosten Voltooid(9)"
      if (!cancel && !close)
        return (oRs("kenmerk_obligation").Value == 1 && opdr_status != 1 && opdr_status != 9)

      // uiteindelijk dan nog de overige flexkenmerken (<= 100) conform mijn opdrachtautorisatie
      if ((prolcode & 1))
        return !(my_mldrechten.canWrite("WEB_EXTORD") || my_mldrechten.canWrite("WEB_ORDBO2") || my_mldrechten.canWrite("WEB_ORDBOF"));
    }

    return false; // 'k vind het wel best
  }

  // Deze functie bepaalt of kenmerken invisible moeten zijn,
  // omdat ze onder een blok vallen waar ik niets binnen mag muteren.
  function isInvisible (oRs)
  {
    var ktype = oRs("kenmerk_kenmerktype").value;
    // Labels altijd tonen. Deze worden wel hidden gemaakt als het blok geen kenmerken bevat.
    if (ktype == "b" || ktype == "l" || ktype == "Q")
      return false; // visible

    var hasFOBO = my_mldrechten.canRead("WEB_MLDBOF") || my_mldrechten.canRead("WEB_MLDFOF") ||
                  my_mldrechten.canRead("WEB_MLDBO2") || my_mldrechten.canRead("WEB_MLDBO3") ||
                  my_mldrechten.canRead("WEB_MLDORD") || my_mldrechten.canRead("WEB_MLDBAC");
    if ((newMelding || changeMelding) &&
        behandelblok >= 2 && !hasFOBO)
    {
      return true;  // invisible
    }
    return false;
  }

  function setClassname(poRs)
  {
    var classname = "";
    if (!advanced && !poRs("kenmerk_verplicht").Value && poRs("kenmerk_verplicht_status").Value == 5) {
        classname = (close? "required" : "reqafm");
    }
    return classname;
  }

  var treatable = { mld_key: mld_key,
                    melder_key: melder_key,
                    srtdisc: (srtdisc.length? srtdisc[0] : -1),       // Bij blokheaders in een melding hebben we maar 1 vakgroeptype.
                    disc: disc,                                       // Initiele waarde primaire Vakgroep/Behandelteam.
                    prsautlevel: prsautlevel,
                    canChange: my_mldrechten.canWrite("WEB_MLDBOF") || my_mldrechten.canWrite("WEB_MLDFOF"),
                    show_alg: show_alg,
                    loc_key: loc_key,
                    readodisc: (mld_key > 0 && !canFlexChange) || (mld_status != 4 && mld_status != 7),
                    readoprs: mld_status != 4 && mld_status != 7,
                    readocompl: mld_status != 4 && mld_status != 7
                  };

  var listkenmerk_params = { kenmerk_search: advanced,
                             kenmerk_extraTD: (changeOpdracht || newOpdracht), // Voor opdrachten een extra TD erachter TODO: (MGE) klopt dit nog
                             stdm_key: (advanced ? null : stdm_arr[0]),
                             fnIsReadonly: isReadonly,
                             fnIsInvisible: isInvisible,
                             fnClassname: setClassname,
                             prs_key: prs_key, // Wordt alleen gebruikt als geldt (!kenmerk_search && !multiMode)
                             parentKey: key,
                             parent_list: params.parent_list,
                             reado: reado,
                             canDeleteAttachment: canDeleteAttachment,
                             copy: copy,
                             mobile: params.mobile,
                             nameprefix: params.nameprefix,
                             serie: params.serie,
                             extraserie:params.extraserie,
                             sqldefaultnotrequired: params.act_key > 0,
                             hideVervallen: newMelding||newOpdracht,
                             niveau: kenmerk_module,
                             opdr_type: opdr_type,
                             wfbuilder: params.wfbuilder,
                             showConfidential: params.showConfidential || newMelding || newOpdracht || canViewConfidential,
                             forceRequired: !changeOpdracht && close, // force required flexfields in case of close confirm because only required flexfields are shown on that form
                             hasfilter: hasfilter,
                             multiEdit: multiEdit,
                             treatable: (changeMelding || newMelding? treatable : null)
                           };

  return { sql: sql
         , key: key
         , list_params: listkenmerk_params
         };
}


function generateFlexKenmerkBlock(params)
{
  var block_params = getFlexKenmerkBlockSql(params);

  listKenmerk(block_params.sql,
              "MLD",
              block_params.key,
              block_params.list_params
             );
} %>
