<% /*
     $Revision$
     $Id$

     File:          fin/fin.inc
*/
%>
<!-- #include file="../Shared/status.inc" -->
<!-- #include file="../mld/mld.inc" -->
<%
var rowIndex = 0;

fin = { func_enabled_factuur: // Wat mag ik zoal op deze specifieke factuur?
          function _func_enabled_factuur(pfin_key)
          {
            var fin_status = -1;
            var kpverantwoordelijke = -1;
            var goedkeurder = -1;
            if (pfin_key > 0)
            {
              var fsql = "SELECT f.fin_factuur_statuses_key"
                       + "     , prs.getkpverantwoordelijke(fin.getfactuurkostenplaats(f.fin_factuur_key), "+S("prs_approvemethod")+", -1) kpverantwoordelijke"
                       + "     , prs_perslid_key_goedkeur"
                       + "  FROM fin_factuur f"
                       + " WHERE fin_factuur_key = " + pfin_key
              var foRs = Oracle.Execute(fsql);
              fin_status = foRs("fin_factuur_statuses_key").Value;
              kpverantwoordelijke = foRs("kpverantwoordelijke").Value;
              goedkeurder = foRs("prs_perslid_key_goedkeur").Value;
              foRs.Close();
            }

            var alg_key = -1;
            var loc_key = -1;
            if (pfin_key > 0)
            {
              // Bepaal de alg key als deze er is (Mogelijk alleen aanwezig voor BES en RES)
              var fin_factuur = fin.factuur_info(pfin_key); // Globale variabele met alle fin_factuur informatie
              // Haal de referentie gegevens op: Deze bevat ook de eventuele alg key
              var ref_info = fin.getreferentieinfo(fin_factuur, fin_factuur.fin_nr);
              alg_key = ref_info.alg_key;
              loc_key = ref_info.loc_key
            }

            var fresult = user.func_enabled2("FIN", { alg_key: alg_key, loc_key: loc_key, prs_key: user_key,
                                                      isOptional: user.isCollega(kpverantwoordelijke) }); // optional als ik hier budgethouder

            fresult.fin_key = pfin_key;
            if (pfin_key > 0)
            {
              fresult.factuur_info = fin_factuur;
              fresult.referentieinfo = ref_info;
            }
            // WEB_RELMAN is onderdeel van de PRS module
            var presult = user.func_enabled2("PRS", { prs_key: user_key, isOptional: true });
            // Als ik een contactpersoon ben dan heb ik alleen rechten om facturen van mijn eigen bedrijf te zien/wijzigen.
            fresult.iamContact = user.isContactpersoon(); // Ben ik een contactpersoon?
            fresult.iamBedrijfContact = false; // Aan bedrijf toegekend en ik ben contactpersoon van dat bedrijf?
            // Bij het aanmaken van een nieuwe melding is er nog geen bedrijf gekozen. Dan alleen kijken naar de rechten.
            if (pfin_key > 0 && !ref_info.lev_uit_intern)
            { // Ik ga er van uit dat je NIET als vervanger van een contactpersoon van een ander bedrijf wordt aangewezen.
              fresult.iamBedrijfContact = user.isContactpersoon(ref_info.lev_uit_key); // Ben ik contactpersoon van het uitvoerende bedrijf?
            }
            fresult.canFEwrite  =(pfin_key > 0 && fresult.iamContact? (fresult.canWrite("WEB_FINUSE") && fresult.iamBedrijfContact) : fresult.canWrite("WEB_FINUSE"));
            fresult.canFOwrite  = fresult.canWrite("WEB_FINFOF");
            fresult.canBOwrite  = fresult.canWrite("WEB_FINBOF");
            fresult.canGOEwrite  = fresult.canWrite("WEB_FINGOE");
            fresult.canWriteAny = fresult.canWrite("WEB_FINUSE") && fresult.iamContact || fresult.canWrite("WEB_FINFOF") || fresult.canWrite("WEB_FINBOF");
            fresult.canFEread  = (pfin_key > 0 && fresult.iamContact? (fresult.canRead("WEB_FINUSE") && fresult.iamBedrijfContact) : fresult.canRead("WEB_FINUSE"));
            fresult.canReadAny  = fresult.canFEread ||
                                  fresult.canRead("WEB_FINFOF") ||
                                  fresult.canRead("WEB_FINBOF") ||
                                  user.isCollega(kpverantwoordelijke);
            fresult.canFOread  = fresult.canRead("WEB_FINFOF");
            fresult.canBOread  = fresult.canRead("WEB_FINBOF");
            fresult.canGOEread  = fresult.canRead("WEB_FINGOE");

            // Op button niveau
            fresult.canChange = false;   // Wijzig knop tonen
            fresult.canAccept = false;   // Accepteren Fiatteren
            fresult.canGoedkeur = false // Goedkeuren.
            fresult.canUnapprove = false; // Ongedaan maken Fiattering
            fresult.canUnReject = false; // Ongedaan maken Afwijzing
            fresult.canDelete = false;   // Accepteren Fiatteren

            // Op invoerveld niveau
            fresult.canDateChange   = false; // Wijzigen van de datum
            fresult.canRemarkChange = false; // Wijzigen van de opmerking
            fresult.canInvLinChange = false; // Wijzigen van de factuurregels

            // Nu canRead("WEB_RELMAN") van presult pakken!
            fresult.canReqRelDetails = presult.canRead("WEB_RELMAN");  // Mag de relatie details (uitvoerder) opvragen

            fresult.canReadNotes = fresult.canRead("WEB_FINFOF") || fresult.canRead("WEB_FINBOF");
            fresult.canWriteNotes = fresult.canReadNotes;

            switch (fin_status)
            {
                case 3:  // Incompleet
                         fresult.canChange         = fresult.canFEwrite ||
                                                     fresult.canWrite("WEB_FINFOF") ||
                                                     (fresult.canWrite("WEB_FINBOF") && S("fin_bof_mag_editen") == 1);
                         fresult.canDelete         = fresult.canWrite("WEB_FINFOF") || fresult.canWrite("WEB_FINUSE");
                         fresult.canDateChange     = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canRemarkChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canInvLinChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         break;
                case 1:  // Afgewezen
                         fresult.canUnReject       = fresult.canWrite("WEB_FINFOF") || fresult.canWrite("WEB_FINBOF") || (user.isCollega(kpverantwoordelijke) && (kpverantwoordelijke > 0));
                         break;
                case -1: // Nieuwe factuur
                case 2:  // Ingevoerd
                         fresult.canChange         = fresult.canFEwrite ||
                                                     fresult.canWrite("WEB_FINFOF") ||
                                                     (fresult.canWrite("WEB_FINBOF") && S("fin_bof_mag_editen") == 1);
                         fresult.canAccept         = fresult.canWrite("WEB_FINBOF") || (user.isCollega(kpverantwoordelijke) && (kpverantwoordelijke > 0));
                         fresult.canDelete         = fresult.canWrite("WEB_FINFOF") || fresult.canWrite("WEB_FINUSE");
                         fresult.canDateChange     = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canRemarkChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canInvLinChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         break;
                case 5:  // Financieel goedgekeurd
                         fresult.canUnapprove      = fresult.canWrite("WEB_FINGOE") || fresult.canWrite("WEB_FINFOF") || fresult.canWrite("WEB_FINBOF") || (user.isCollega(kpverantwoordelijke) && (kpverantwoordelijke > 0));
                         // Maar na wijzigen moet er opnieuw gefiatteed worden door BO.
                         fresult.canChange         = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canDateChange     = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canRemarkChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canInvLinChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canGoedkeur       = fresult.canWrite("WEB_FINGOE") && user.isCollega(goedkeurder) && S("fin_enable_goedkeuren") != 0;
                         break;
                case 6:  // Akkoord
                         fresult.canUnapprove      = fresult.canWrite("WEB_FINFOF") || fresult.canWrite("WEB_FINBOF") || (user.isCollega(kpverantwoordelijke) && (kpverantwoordelijke > 0));
                         // Maar na wijzigen moet er opnieuw gefiatteed worden door BO.
                         fresult.canChange         = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canDateChange     = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canRemarkChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         fresult.canInvLinChange   = fresult.canFEwrite || fresult.canWrite("WEB_FINFOF");
                         break;
                case 7:  // Verwerkt
                         break;
            }

            return fresult;
          },

        analysereferentie:
          function _analysereferentie(ref, ascontactpers)
          { // Levert info op van de meegegeven referentie
            //   {
            //        ref_type: "O", "B" of "C",
            //  M:      mld_key
            //  M:      opdr_volgnr
            //  M:      mld_prefix
            //  M:      mldopdr_key
            //  C:      cnt_nr
            //  C:      cnt_versie
            //  C:      cnt_key
            //  B:      bes_key
            //  B:      besopdr_key
            //  B:      bes_volgnr
            //   }
            // Levert null op indien geen geldig referentie type gevonden
            // Dat kan ook daardat een opdracht of bestelling geen factuur verwacht agv geen kosten of annulering

            // Functie die spaties aan het begin en eind van een string verwijderd.
            function trim_all(str)
            {
              while (str.charAt(0) == (" "))
              {
                str = str.substring(1);
              }
              while (str.charAt(str.length - 1) == " ")
              {
                str = str.substring(0, str.length - 1);
              }
              return str;
            }

            var result = {mldopdr_key: -1, besopdr_key: -1, cnt_key: -1};
            ref = trim_all(ref);

            var ref_type = "";
            if (ref.length > 0) {
              var prefix = ref.substr(0,1)

              if ((((prefix.charCodeAt(0) >= 65 && prefix.charCodeAt(0) <= 90) ||
                    (prefix.charCodeAt(0) >= 97 && prefix.charCodeAt(0) <= 122)) &&
                   prefix.charCodeAt(0) != 67 &&
                   prefix.charCodeAt(0) != 99))
              {
                ref_type = "O";  // Opdracht (Melding)
              } else if (prefix.charCodeAt(0) >= 48 && prefix.charCodeAt(0) <= 57) {
                ref_type = "B";  // Bestelling
              } else if (prefix.charCodeAt(0) == 67 || prefix.charCodeAt(0) == 99) {
                ref_type = "C";  // Contract
              } else {
                return result;
              }
            }
            result.ref_type = ref_type;

            ref_s = ref.split("/");     // array met het deel voor en na de /, voor mld en bes

            if (ref_type == "O")
            {
              var opdr = ref;
              var find = false;
              var findi = -1;
              var opdr_s = ref_s;
              var refnr_prefix;

              if (!isNaN(opdr_s[1]) && (prefix.charCodeAt(0) >= 48 && prefix.charCodeAt(0) <= 57))
              { // Er is geen prefix maar het is wel een opdracht
                // Afgedwongen door /
                refnr_prefix = "";  // prefix
                find = true;
              }
              else
              {
                // Bepaal prefix
                // Welke srtdiscipline prefixen hebben we
                sql = "SELECT sd.ins_srtdiscipline_prefix"
                    + " FROM ins_srtdiscipline sd"
                    + " WHERE sd.ins_srtdiscipline_module = 'MLD'"
                    + " AND sd.ins_srtdiscipline_verwijder IS NULL"
                    + " AND sd.ins_srtdiscipline_prefix IS NOT NULL"
                    + " ORDER BY sd.ins_srtdiscipline_key"
                oRs = Oracle.Execute(sql);
                while (!oRs.eof)
                {
                  var srtdisc = oRs("ins_srtdiscipline_prefix").Value;
                  if (srtdisc.toUpperCase() == opdr.substr(0, srtdisc.length).toUpperCase() &&
                      opdr.substr(srtdisc.length, 1).charCodeAt(0) >= 48 && opdr.substr(srtdisc.length, 1).charCodeAt(0) <= 57)
                  {
                    find = true;
                    break;
                  }
                  oRs.MoveNext();
                }
                oRs.close();

                if (find)
                {
                  refnr_prefix = opdr.substr(0, srtdisc.length);  // prefix
                  opdr = opdr.substr(srtdisc.length);  // haal prefix eraf
                  opdr_s = opdr.split("/"); // Nu zonder prefix
                }
              }

              if (!find || opdr_s[0] == null || !shared.isGoodNumber(opdr_s[0],true,false,6,-1) || (opdr_s[1] && !shared.isGoodNumber(opdr_s[1],true,false,6,-1)))
              {
                result.message = L("lcl_fin_invalid_ref");
                return result;
              }
              else
              {
                result.mld_key = opdr_s[0];
                result.opdr_volgnr = opdr_s[1];
                result.mld_prefix = refnr_prefix;
              }
            }
            else if (ref_type == "C")
            {
              var cnt_nr;
              var cnt_versie;
              var cnt_key;
              cnt_nr = ref.substr(1);  // haal prefix 'C' of 'c' eraf

              if (cnt_nr.indexOf(".") > 0)
              { // er wordt een expliciete versie aangegeven, separeer
                cnt_versie = cnt_nr.substr(cnt_nr.indexOf(".")+1);    // alleen het versienr
                cnt_nr = cnt_nr.substr(0,cnt_nr.indexOf("."));  // resteert het contractnummer
              }

              // Bepaal nu lekker de contract_key. Werking is:
              // Als expliciet een versie wordt meegegeven, dan wordt die gebruikt, anders
              // wordt de nieuwste bestaande versie gebruikt.
              // Het contract moet altijd actief zijn om nog een factuur te kunnen ontvangen
              result.cnt_nr = cnt_nr;
              result.cnt_versie = cnt_versie;
              sql = "SELECT MAX(cnt_contract_key) cnt_contract_key"
                  + "  FROM cnt_v_aanwezigcontract c"
                  + " WHERE c.cnt_contract_nummer_intern = " + safe.quoted_sql(cnt_nr)
                  + "   AND c.cnt_contract_status = 0"
                  + (cnt_versie ? " AND c.cnt_contract_versie = "+ safe.quoted_sql(cnt_versie) : "")
                  + (ascontactpers
                    ? " AND c.cnt_prs_bedrijf_key IN (SELECT cp.prs_bedrijf_key"
                      + "                               FROM prs_contactpersoon cp"
                      + "                              WHERE cp.prs_perslid_key = " + user_key
                      + "                                AND cp.prs_contactpersoon_verwijder IS NULL)"
                      : "");
              oRs = Oracle.Execute(sql);
              if (!oRs.eof) {
                result.cnt_key = oRs("cnt_contract_key").Value;
              }
            }
            else if (ref_type == "B")
            {
              var besopdr = ref;
              var besopdr_s = ref_s;
              // check of het nummer voor de / en eventueel erachter een geldig nummer is. Bestelnummer bevatten geen prefix.
              if (!shared.isGoodNumber(besopdr_s[0],true,false,6,-1) || (besopdr_s[1] && !shared.isGoodNumber(besopdr_s[1],true,false,6,-1)))
              {
                result.message = L("lcl_fin_invalid_ref");
                return result;
              }
              else
              {
                // Controleren of het echt een bestelling is. Het kan ook nog een opdracht van een melding zijn zonder prefix.
                var likechar = "";
                if (!besopdr_s[1]) // niets achter slash opgegeven
                {
                  likechar = "%";
                }
                sql = "SELECT bo.bes_bestelopdr_key"
                    + ", bbi.bes_bestelling_key"
                    + " FROM bes_bestelopdr bo"
                    + ", bes_bestelopdr_item boi"
                    + ", bes_bestelling_item bbi"
                    + " WHERE bo.bes_bestelopdr_key = boi.bes_bestelopdr_key"
                    + " AND boi.bes_bestelopdr_item_key = bbi.bes_bestelopdr_item_key"
                    + " AND bo.bes_bestelopdr_status NOT IN (1,3,8)"  // Dat zijn echte bestellingen
                    + " AND bbi.bes_bestelling_key = " +  parseInt(besopdr_s[0],10)
                    + " AND UPPER(bo.bes_bestelopdr_id) LIKE " + safe.quoted_sql_wild(ref + likechar) // Volgnummer kan bij bestellingen ook leeg zijn ('1234' of '1234/1')
                    + (ascontactpers
                      ? " AND bo.prs_bedrijf_key IN (SELECT cp.prs_bedrijf_key"
                        + "                            FROM prs_contactpersoon cp"
                        + "                           WHERE cp.prs_perslid_key = " + user_key
                        + "                             AND cp.prs_contactpersoon_verwijder IS NULL)"
                        : "");
                oRs = Oracle.Execute(sql);

                if (!oRs.eof)
                { // Het is een bestelopdracht
                  result.bes_key = besopdr_s[0]; // bestelling / volgnr //oRs("bes_bestelling_key").Value;
                  result.besopdr_key = oRs("bes_bestelopdr_key").Value; //besopdr_s[0];
                  result.bes_volgnr = besopdr_s[1];
                }
                else
                { // Het kan toch nog een mldopdracht zijn zonder prefix
                  result.ref_type = "O";  // toch nog
                  result.mld_key = besopdr_s[0];
                  result.opdr_volgnr = besopdr_s[1];
                  result.mld_prefix = "";
                }
              }
            }

            if (result.ref_type == "O")
            { // dan wil ik nog graag de opdrkey

              if (!result.opdr_volgnr)
              {
                // geen expliciet volgnummer gegeven, dan de nieuwste hanteren
                sql = "SELECT COALESCE(MAX(o.mld_opdr_bedrijfopdr_volgnr), 0) opdr_volgnr"
                    + " FROM mld_opdr o"
                    + " WHERE o.mld_melding_key = " + result.mld_key;
                oRs = Oracle.Execute(sql);

                // altijd 1 resultaat
                if (oRs("opdr_volgnr").Value > 0)
                  result.opdr_volgnr = oRs("opdr_volgnr").Value;
                else
                  result.opdr_volgnr = 1;
              }

              sql = "SELECT o.mld_opdr_key"
                  + " FROM mld_opdr o, mld_typeopdr mto"
                  + " WHERE o.mld_typeopdr_key = mto.mld_typeopdr_key"
                  + "   AND mto.mld_typeopdr_kosten = 1"   // AADS#17542
                  + "   AND o.mld_statusopdr_key NOT IN (1, 2, 3, 10)"   // Dat zijn echte opdrachten
                  + "   AND o.mld_melding_key = " + result.mld_key
                  + "   AND o.mld_opdr_bedrijfopdr_volgnr = " + result.opdr_volgnr
                  + (ascontactpers
                    ? " AND o.mld_uitvoerende_keys IN (SELECT cp.prs_bedrijf_key"
                      + "                                FROM prs_contactpersoon cp"
                      + "                               WHERE cp.prs_perslid_key = " + user_key
                      + "                                 AND cp.prs_contactpersoon_verwijder IS NULL)"
                      : "");
              oRs = Oracle.Execute(sql);
              if (!oRs.eof)
                result.mldopdr_key = oRs("mld_opdr_key").Value;
              //else geen opdracht gevonden.
            };
            result.valid = result.mldopdr_key > 0 || result.besopdr_key > 0 || result.cnt_key > 0;

            return result;
          },

        factuur_info:
          function (fin_key)
          {
            // Get info of existing opdracht, bestelling or contract, gegeven een factuur_key
            var sql = "SELECT f.mld_opdr_key"
                    + "     , f.cnt_contract_key cnt_key"
                    + "     , f.bes_bestelopdr_key"
                    + "     , f.fin_factuur_totaal"
                    + "     , f.fin_factuur_totaal_btw"
                    + "     , f.fin_factuur_gbedrag"
                    + "     , f.prs_perslid_key_user"
                    + "     , f.prs_perslid_key_goedkeur"
                    + "     , f.fin_factuur_opmerking"
                    + "     , f.fin_factuur_bron"
                    + "     , f.fin_factuur_statuses_key"
                    + "     , (SELECT " + S("prs_pers_string")
                      +      "   FROM prs_perslid p"
                      +      "  WHERE p.prs_perslid_key = f.prs_perslid_key_user) name_user"
                    + "     , (SELECT " + S("prs_pers_string")
                      +      "   FROM prs_perslid p"
                      +      "  WHERE p.prs_perslid_key = f.prs_perslid_key_goedkeur) name_goedkeur"
                    + "     , f.fin_factuur_datum"
                    + "     , f.fin_factuur_nr"
                    + "     , f.fin_factuur_boekmaand"
                    + "     , f.fin_factuur_debiteur_nr"
                    + "     , f.prs_kostensoort_key"
                    + "     , ks.prs_kostensoort_oms || '-' || "+lcl.xsql('ks.prs_kostensoort_opmerking','ks.prs_kostensoort_key')+" kostensoort"
                    + "     , fin_factuur_verwijder"
                    + " FROM fin_factuur f"
                    + "    , prs_kostensoort ks"
                    + " WHERE f.prs_kostensoort_key = ks.prs_kostensoort_key(+)"
                    + " AND f.fin_factuur_key = " + fin_key;
            var oRs = Oracle.Execute(sql);

            var ref_type;

            if (oRs("bes_bestelopdr_key").Value)
                ref_type = "B";
            if (oRs("cnt_key").Value)
                ref_type = "C";
            if (oRs("mld_opdr_key").Value)
                ref_type = "O";

            var fin_boekm = oRs("fin_factuur_boekmaand").Value;

            var fin_factuur = { fin_key: fin_key,
                                ref_type: ref_type,
                                mldopdr_key: oRs("mld_opdr_key").Value,
                                cnt_key: oRs("cnt_key").Value,
                                besopdr_key: oRs("bes_bestelopdr_key").Value,
                                fin_totaal: oRs("fin_factuur_totaal").Value,
                                fin_totaal_btw: oRs("fin_factuur_totaal_btw").Value,
                                fin_gbedrag: oRs("fin_factuur_gbedrag").Value,
                                perslid_key_user: oRs("prs_perslid_key_user").Value,
                                perslid_key_goedkeur: oRs("prs_perslid_key_goedkeur").Value,
                                fin_opm: oRs("fin_factuur_opmerking").Value,
                                fin_status_key: oRs("fin_factuur_statuses_key").Value,
                                fin_status_oms: fin.getfinstatustext(oRs("fin_factuur_statuses_key").Value),
                                fin_bron_key: oRs("fin_factuur_bron").Value,
                                fin_bron_oms: fin.getfinbrontext(oRs("fin_factuur_bron").Value),
                                fin_perslid_user: oRs("name_user").Value,
                                fin_perslid_goedkeur: oRs("name_goedkeur").Value,
                                fin_date: new Date(oRs("fin_factuur_datum").Value),
                                fin_nr: oRs("fin_factuur_nr").Value,
                                fin_boekm: fin_boekm,
                                fin_boekm_jaar: fin_boekm.substr(0, 4),
                                fin_debiteur: oRs("fin_factuur_debiteur_nr").Value,
                                fin_costsrt_key: oRs("prs_kostensoort_key").Value,
                                fin_costsrt: oRs("kostensoort").Value,
                                fin_verwijder: oRs("fin_factuur_verwijder").Value
                              }
            oRs.Close();

            switch (ref_type)
            {
                case "O": //  (melding)opdracht
                    var sql = "SELECT o.mld_melding_key"
                            + "     , o.mld_opdr_bedrijfopdr_volgnr"
                            + "     , sd.ins_srtdiscipline_prefix prefix"
                            + "     , COALESCE(sm.prs_kostensoort_key, itd.prs_kostensoort_key) prs_kostensoort_key"
                            + "     , o.prs_kostenplaats_key"
                            + "  FROM mld_opdr o"
                            + "     , ins_srtdiscipline sd"
                            + "     , ins_tab_discipline itd"
                            + "     , mld_stdmelding sm"
                            + "     , mld_melding m"
                            + " WHERE sd.ins_srtdiscipline_key = itd.ins_srtdiscipline_key"
                            + "   AND itd.ins_discipline_key = sm.mld_ins_discipline_key"
                            + "   AND m.mld_stdmelding_key = sm.mld_stdmelding_key"
                            + "   AND m.mld_melding_key = o.mld_melding_key"
                            + "   AND o.mld_opdr_key = " + fin_factuur.mldopdr_key;
                    oRs = Oracle.Execute(sql);

                    fin_factuur.mld_key = oRs("mld_melding_key").Value;
                    fin_factuur.opdr_volgnr = oRs("mld_opdr_bedrijfopdr_volgnr").Value;
                    fin_factuur.mld_prefix = oRs("prefix").Value;
                    fin_factuur.fin_costsrt_default = oRs("prs_kostensoort_key").Value;
                    fin_factuur.kostenplaats_key = oRs("prs_kostenplaats_key").Value;
                    oRs.Close();

                    break;

                case "B": //  (bestel)opdracht
                // bes_bestelopdr_key
                    var sql = "SELECT MAX(COALESCE(isg.prs_kostensoort_key, bd.prs_kostensoort_key)) prs_kostensoort_key"
                            + "     , MAX(b.prs_kostenplaats_key) prs_kostenplaats_key"
                            + "     , MAX(bes_bestelopdr_id) bes_bestelopdr_id"
                            + " FROM bes_bestelopdr bo"
                            + "    , bes_bestelopdr_item boi"
                            + "    , bes_bestelling_item bi"
                            + "    , bes_bestelling b"
                            + "    , bes_srtdeel isd"
                            + "    , bes_srtgroep isg"
                            + "    , bes_discipline bd"
                            + " WHERE bo.bes_bestelopdr_key = boi.bes_bestelopdr_key"
                            + "  AND boi.bes_bestelopdr_item_key = bi.bes_bestelopdr_item_key"
                            + "  AND bi.bes_srtdeel_key = isd.bes_srtdeel_key"
                            + "  AND b.bes_bestelling_key = bi.bes_bestelling_key"
                            + "  AND isd.bes_srtgroep_key = isg.bes_srtgroep_key"
                            + "  AND isg.ins_discipline_key = bd.ins_discipline_key"
                            + "  AND bo.bes_bestelopdr_key = " + fin_factuur.besopdr_key
                    oRs = Oracle.Execute(sql);
                    fin_factuur.fin_costsrt_default = oRs("prs_kostensoort_key").Value;
                    fin_factuur.kostenplaats_key = oRs("prs_kostenplaats_key").Value;

                    var bes_bestelopdr_id = oRs("bes_bestelopdr_id").Value;

                    var bes_bestelopdr_id_s = bes_bestelopdr_id.split("/");
                    fin_factuur.bes_key = bes_bestelopdr_id_s[0];
                    if (bes_bestelopdr_id_s.length == 2)
                        fin_factuur.bes_volgnr = bes_bestelopdr_id_s[1];

                    fin_factuur.bes_id = oRs("bes_bestelopdr_id").Value;
                    oRs.Close();
                  break;

                case "C": //  Contract
                    var sql = "SELECT c.cnt_contract_nummer_intern"
                            + "     , c.cnt_contract_versie"
                            + "     , COALESCE(c.prs_kostensoort_key, cd.prs_kostensoort_key) prs_kostensoort_key"
                            + "     , prs_kostenplaats_key"
                            + "  FROM cnt_contract c"
                            + "     , cnt_discipline cd"
                            + " WHERE c.ins_discipline_key = cd.ins_discipline_key"
                            + "   AND cnt_contract_key = " + fin_factuur.cnt_key
                    oRs = Oracle.Execute(sql);
                    fin_factuur.cnt_nr = oRs("cnt_contract_nummer_intern").Value;
                    fin_factuur.cnt_versie = oRs("cnt_contract_versie").Value;
                    fin_factuur.fin_costsrt_default = oRs("prs_kostensoort_key").Value;
                    fin_factuur.kostenplaats_key = oRs("prs_kostenplaats_key").Value;
                    oRs.Close();

                    sql = "SELECT SUM(fin_factuur_totaal) totaal"
                        + "  FROM fin_factuur f"
                        + " WHERE cnt_contract_key = " + fin_factuur.cnt_key
                        + "   AND fin_factuur_statuses_key <> 1"
                        + "   AND fin_factuur_datum <= " + fin_factuur.fin_date.toSQL();
                    oRs = Oracle.Execute(sql);
                    fin_factuur.totaalgefactureerd = oRs("totaal").Value;
                    oRs.Close();

                    break;
            }
            fin_factuur.default_costsrt_selected = ((fin_factuur.fin_costsrt_key == fin_factuur.fin_costsrt_default) && (fin_factuur.fin_costsrt_key != null));

            if (fin_factuur.kostenplaats_key > 0)
            {
                var sql = "SELECT k.prs_perslid_key"
                        + "  FROM prs_kostenplaats k"
                        + " WHERE k.prs_kostenplaats_key = " + fin_factuur.kostenplaats_key;
                oRs = Oracle.Execute(sql);
                fin_factuur.fin_budgethouder = oRs("prs_perslid_key").Value;
                oRs.Close();
            }

            // Retrieve info about the invoice lines
            sql = "SELECT SUM(fr.fin_factuurregel_btw + fr.fin_factuurregel_totaal) sumBTW"
                + " FROM fin_factuurregel fr"
                + " WHERE fr.fin_factuur_key = " + fin_key;
            oRs = Oracle.Execute(sql);
            fin_factuur.totaal = oRs("sumBTW").Value;

            oRs.close();

            return fin_factuur;
          },


        getnomatchreasoncontract:
          function _getnomatchreasoncontract(contract_info, totaalgefactureerd, factuurbedrag)
          {
            // Evenetuele oorzaak van het niet automatisch matchen.
            // tolerantiematch (discipline, ftype, totaalgefactureerd, contractkosten)
            // tolerantiematch (discipline, ftype, factuurbedrag, contracttermijnkosten)
            sql = "SELECT fin.tolerantiematch(" + contract_info.disc_key + ", 'C', " + totaalgefactureerd + ", " + contract_info.totbedrag + ") totaal"
                + "     , fin.tolerantiematch(" + contract_info.disc_key + ", 'C', " + factuurbedrag + ", " + contract_info.termbedrag + ") termijn"
                + " FROM DUAL";
            oRs = Oracle.Execute(sql);
            // Return waarde result:
            // 00 (0): No match
            // 01 (1): Termijn kosten matchen
            // 10 (2): Totaal kosten matchen
            // 11 (3): Termijn kosten en totaal kosten matchen
            var result = 0;
            result = (oRs("totaal").Value? 2 : 0) + (oRs("termijn").Value? 1 : 0);
            return result;
          },

        getreferentieinfo:
          function _getreferentieinfo(fin_factuur, fin_factuur_nr)
          {
            // fin_factuur is een object met allerlei factuurgegevens (fin.analysereferentie())
            // wat bij een bestaande vrij compleet is, maar het kan ook een nieuwe zijn
            // en dan is lang niet alles bekend en bruikbaar.

            // Wat is het type van de referentie
            var referentie = "";
            var ref_type = "";

            // Bepaal meer informatie van de referentie
            switch (fin_factuur.ref_type)
            {
              case "O": // Opdracht (Melding)
                        var opdr_volgnr = fin_factuur.opdr_volgnr;
                        // Vind informatie van de opdracht
                        sql = "SELECT 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"
                            + "   , COALESCE ((SELECT 'P' pbtype"
                              + "                FROM prs_perslid p"
                              + "               WHERE p.prs_perslid_key = o.mld_uitvoerende_keys),"
                              + "             (SELECT 'B' pbtype"
                              + "                FROM prs_bedrijf d"
                              + "               WHERE d.prs_bedrijf_key = o.mld_uitvoerende_keys)) pbtype"
                            + "   , COALESCE ((SELECT 1 intern"
                              + "                FROM prs_perslid p"
                              + "               WHERE p.prs_perslid_key = o.mld_uitvoerende_keys),"
                              + "             (SELECT prs_bedrijf_intern intern"
                              + "                FROM prs_bedrijf d"
                              + "               WHERE d.prs_bedrijf_key = o.mld_uitvoerende_keys)) intern"
                            + "     , COALESCE(o.mld_uitvoerende_keys, -1) uitvoerende_key"
                            + "     , (SELECT b.prs_bedrijf_opmerking"
                              + "        FROM prs_bedrijf b"
                              + "       WHERE b.prs_bedrijf_key = o.mld_uitvoerende_keys) lev_opm"
                            + "     , (SELECT rt.prs_relatietype_omschrijving"
                              + "        FROM prs_bedrijf b"
                              + "           , prs_relatietype rt"
                              + "       WHERE b.prs_relatietype_key = rt.prs_relatietype_key"
                              + "         AND b.prs_bedrijf_key = o.mld_uitvoerende_keys) reltype_oms"
                            + "     , COALESCE(o.prs_kostenplaats_key, m.prs_kostenplaats_key) prs_kostenplaats_key"
                            + "     , o.mld_statusopdr_key"
                            + "     , o.mld_opdr_datumbegin startdatum"
                            + "     , o.mld_opdr_einddatum einddatum"
                            + "     , TO_CHAR (o.mld_opdr_datumbegin, 'YYYY-MM') periode"
                            + "     , COALESCE(o.mld_opdr_kosten, 0) totaalbedrag"
                            + "     , COALESCE((SELECT SUM(f.fin_factuur_totaal)"
                              + "                 FROM fin_factuur f"
                              + "                WHERE f.mld_opdr_key = o.mld_opdr_key"
                              + "                  AND f.fin_factuur_statuses_key <> 1"
                              + "                  AND f.fin_factuur_verwijder IS NULL), 0) gefactureerd" // fin_factuur_statuses_key = 1 (afgewezen) niet meenemen in totaal (AADS#17716)
                            + "     , COALESCE((SELECT SUM(f.fin_factuur_totaal)"
                              + "                 FROM fin_factuur f"
                              + "                WHERE f.mld_opdr_key = o.mld_opdr_key"
                              + "                  AND UPPER(f.fin_factuur_boekmaand) LIKE " + safe.quoted_sql_wild(fin_factuur.fin_boekm_jaar + "%")
                              + "                  AND f.fin_factuur_statuses_key <> 1"
                              + "                  AND f.fin_factuur_verwijder IS NULL), 0) gefactureerd_jaar" // fin_factuur_statuses_key = 1 (afgewezen) niet meenemen in totaal (AADS#17716)
                            + "     , COALESCE(std.prs_kostensoort_key, itd.prs_kostensoort_key) kostensoort_key"
                            + "     , COALESCE((SELECT a.alg_locatie_code"
                              + "                 FROM mld_adres ma"
                              + "                    , alg_locatie a"
                              + "                WHERE ma.alg_locatie_key = a.alg_locatie_key"
                              + "                  AND ma.mld_adres_key = m.mld_adres_key)"
                              + "   , (SELECT a.alg_locatie_code"
                              + "        FROM alg_locatie a"
                              + "       WHERE a.alg_locatie_key = m.mld_alg_locatie_key)) loc_code"
                            + "     , COALESCE((SELECT ma.alg_locatie_key"
                              + "                 FROM mld_adres ma"
                              + "                WHERE ma.mld_adres_key = m.mld_adres_key)"
                              + "   , m.mld_alg_locatie_key) loc_key"
                            + "     , m.mld_alg_onroerendgoed_keys alg_key"
                            + "     , sd.ins_srtdiscipline_prefix"
                            + "     , o.mld_opdr_omschrijving"
                            + "     , o.mld_opdr_id"
                            + "     , COALESCE((SELECT DISTINCT 1"
                              + "                 FROM ins_tab_discipline itd"
                              + "                    , ins_srtdiscipline sd"
                              + "                WHERE sd.ins_srtdiscipline_key = itd.ins_srtdiscipline_key"
                              + "                  AND itd.ins_discipline_key = std.mld_ins_discipline_key), 0) show_omschr" // Omschrijving alleen tonen als referentie een meldingopdracht is
                            + "     , o.mld_opdr_key"
                            + "     , " + lcl.xsqla('t.mld_typeopdr_omschrijving', 't.mld_typeopdr_key')
                            + "     , COALESCE((SELECT b.fin_btwtabel_key"
                              + "                 FROM prs_bedrijf b"
                              + "                WHERE b.prs_bedrijf_key = o.mld_uitvoerende_keys),"
                              + "              (SELECT fin_btwtabel_key"
                              + "                 FROM fin_btwtabel"
                              + "                WHERE fin_btwtabel_verwijder is null and fin_btwtabel_default = 1)) btwtabel_key"
                            + " FROM mld_opdr o"
                            + "    , ins_srtdiscipline sd"
                            + "    , ins_tab_discipline itd"
                            + "    , mld_stdmelding std"
                            + "    , mld_melding m"
                            + "    , alg_locatie a"
                            + "    , mld_typeopdr t"
                            + " WHERE sd.ins_srtdiscipline_key = itd.ins_srtdiscipline_key"
                            + " AND itd.ins_discipline_key = std.mld_ins_discipline_key"
                            + " AND m.mld_melding_key = o.mld_melding_key"
                            + " AND m.mld_stdmelding_key = std.mld_stdmelding_key"
                            + " AND o.mld_typeopdr_key = t.mld_typeopdr_key"
                            + " AND o.mld_opdr_key = " + fin_factuur.mldopdr_key
                            + " AND m.mld_alg_locatie_key = a.alg_locatie_key(+)";

                        var oRs = Oracle.Execute(sql);

                        if (!oRs.eof)
                        {
                          var result = { ref_key: oRs("mld_opdr_key").Value, // mldopdr_key
                                         ref_type: "O",
                                         ref_volgnr: opdr_volgnr,
                                         referentie: (oRs("ins_srtdiscipline_prefix").Value||"") + fin_factuur.mld_key + "/" + opdr_volgnr,
                                         lev_uit: oRs("uitvoerende").Value,
                                         lev_uit_key: oRs("uitvoerende_key").Value,
                                         lev_uit_type: oRs("pbtype").Value,
                                         lev_uit_intern: oRs("intern").Value == 1,
                                         lev_opm: oRs("lev_opm").Value,
                                         reltype_oms: oRs("reltype_oms").Value,
                                         status: status.getopdrstatustext(oRs("mld_statusopdr_key").Value),
                                         startdatum: toDateString(oRs("startdatum").Value),
                                         einddatum: toDateString(oRs("einddatum").Value),
                                         periode: oRs("periode").Value,
                                         totbedrag: oRs("totaalbedrag").Value,
                                         gefactureerd: oRs("gefactureerd").Value,
                                         gefactureerd_jaar: oRs("gefactureerd_jaar").Value,
                                         kostensoort_key: oRs("kostensoort_key").Value,
                                         kostenplaats_key: oRs("prs_kostenplaats_key").Value,
                                         loc_code: oRs("loc_code").Value,
                                         loc_key: oRs("loc_key").Value,
                                         alg_key: oRs("alg_key").Value,
                                         opdr_omschr: oRs("mld_opdr_omschrijving").Value,
                                         opdr_id: oRs("mld_opdr_id").Value,
                                         show_omschr: (oRs("show_omschr").Value == 1),
                                         typeopdr_omschr: oRs("mld_typeopdr_omschrijving").Value,
                                         btwtabel_key: oRs("btwtabel_key").Value
                                       };
                        }
                        else
                        {
                          var result = { message: L("lcl_fin_not_exist") };
                        }
                        oRs.close();
                        break;
              case "B": // Bestelling opdracht
                        // Vind informatie van de bestelling opdracht
                        sql = "SELECT DISTINCT COALESCE((SELECT b.prs_bedrijf_naam FROM prs_bedrijf b WHERE b.prs_bedrijf_key = bo.prs_bedrijf_key),"
                              + "                       COALESCE((SELECT " + S("prs_pers_string") + " FROM prs_perslid p WHERE p.prs_perslid_key = bo.prs_bedrijf_key),"
                              + "                                '')) uitvoerende"
                            + "     , 'B' pbtype"
                            + "     , (SELECT b.prs_bedrijf_intern"
                              + "        FROM prs_bedrijf b"
                              + "       WHERE b.prs_bedrijf_key = bo.prs_bedrijf_key) intern"
                            + "     , COALESCE(bo.prs_bedrijf_key, -1) uitvoerende_key"
                            + "     , (SELECT b.prs_bedrijf_opmerking"
                              + "        FROM prs_bedrijf b"
                              + "       WHERE b.prs_bedrijf_key = bo.prs_bedrijf_key) lev_opm"
                            + "     , (SELECT rt.prs_relatietype_omschrijving"
                              + "        FROM prs_bedrijf b"
                              + "           , prs_relatietype rt"
                              + "       WHERE b.prs_relatietype_key = rt.prs_relatietype_key"
                              + "         AND b.prs_bedrijf_key = bo.prs_bedrijf_key) reltype_oms"
                            + "     , bo.bes_bestelopdr_status"
                            + "     , bo.bes_bestelopdr_datum startdatum"
                            + "     , bo.bes_bestelopdr_leverdatum einddatum"
                            + "     , TO_CHAR (bo.bes_bestelopdr_datum, 'YYYY-MM') periode"
                            + "     , COALESCE((SELECT SUM(boi.bes_bestelopdr_item_aantal "
                            + "                            * COALESCE(boi.bes_bestelopdr_item_inkprijs, boi.bes_bestelopdr_item_prijs))"
                              + "                 FROM bes_bestelopdr_item boi"
                              + "                WHERE boi.bes_bestelopdr_key = bo.bes_bestelopdr_key), 0) totaalbedrag"
                            + "     , COALESCE((SELECT SUM(f.fin_factuur_totaal)"
                              + "                 FROM fin_factuur f"
                              + "                WHERE f.fin_factuur_statuses_key <> 1"
                              + "                  AND f.bes_bestelopdr_key = bo.bes_bestelopdr_key"
                              + "                  AND f.fin_factuur_verwijder IS NULL), 0) gefactureerd"
                            + "     , COALESCE((SELECT SUM(f.fin_factuur_totaal)"
                              + "                 FROM fin_factuur f"
                              + "                WHERE f.bes_bestelopdr_key = bo.bes_bestelopdr_key"
                              + "                  AND f.fin_factuur_statuses_key <> 1"
                              + "                  AND f.fin_factuur_verwijder IS NULL"
                              + "                  AND UPPER(f.fin_factuur_boekmaand) LIKE " + safe.quoted_sql_wild(fin_factuur.fin_boekm_jaar + "%") + "), 0) gefactureerd_jaar"
                            + "     , COALESCE(isg.prs_kostensoort_key, itd.prs_kostensoort_key) kostensoort_key" // per bestelling toch maar 1 discipline
                            + "     , (SELECT a.alg_locatie_code"
                              + "        FROM mld_adres ma"
                              + "           , alg_locatie a"
                              + "       WHERE ma.alg_locatie_key = a.alg_locatie_key"
                              + "         AND ma.mld_adres_key = bo.mld_adres_key_lev) loc_code"
                            + "     , (SELECT ma.alg_locatie_key"
                              + "        FROM mld_adres ma"
                              + "       WHERE ma.mld_adres_key = bo.mld_adres_key_lev) alg_key"
                            + "     , bo.bes_bestelopdr_id"
                            + "     , bo.bes_bestelopdr_key"
                            + "     , COALESCE((SELECT b.fin_btwtabel_key"
                              + "                 FROM prs_bedrijf b"
                              + "                WHERE b.prs_bedrijf_key = bo.prs_bedrijf_key),"
                              + "              (SELECT fin_btwtabel_key"
                              + "                 FROM fin_btwtabel"
                              + "                WHERE fin_btwtabel_default = 1)) btwtabel_key"
                            + "     , b.prs_kostenplaats_key"
                            + "     , b.bes_bestelling_levkosten"
                            + "     , b.bes_bestelling_korting"
                            + "     , b.bes_bestelling_key"
                            + "  FROM bes_bestelopdr bo"
                            + "     , bes_bestelopdr_item boi"
                            + "     , bes_bestelling_item bi"
                            + "     , bes_bestelling b"
                            + "     , bes_srtdeel isd"
                            + "     , bes_srtgroep isg"
                            + "     , ins_tab_discipline itd"
                            + " WHERE b.bes_bestelling_key = " + fin_factuur.bes_key
                            + (fin_factuur.bes_volgnr > 0
                              ? " AND bo.bes_bestelopdr_id = " + safe.quoted_sql(fin_factuur.bes_key + "/" + fin_factuur.bes_volgnr)
                              : "")
                            + "   AND bo.bes_bestelopdr_key = boi.bes_bestelopdr_key"
                            + "   AND boi.bes_bestelopdr_item_key = bi.bes_bestelopdr_item_key"
                            + "   AND b.bes_bestelling_key = bi.bes_bestelling_key"
                            + "   AND bi.bes_srtdeel_key = isd.bes_srtdeel_key"
                            + "   AND isd.bes_srtgroep_key = isg.bes_srtgroep_key"
                            + "   AND isg.ins_discipline_key = itd.ins_discipline_key"
                            + " ORDER BY bo.bes_bestelopdr_id";  // Er kan een id zijn met '1234' en '1234/1' als bes_volgnr leeg is. Dan '1234' uitlezen.

                        var oRs = Oracle.Execute(sql);

                        if (!oRs.eof)
                        {
                          var bes_bestelopdr_id = oRs("bes_bestelopdr_id").Value;
                          bo_id = bes_bestelopdr_id.split("/")
                          var result = { ref_key: oRs("bes_bestelopdr_key").Value, // besopdr_key
                                         ref_type: "B",
                                         ref_volgnr: bo_id[1],
                                         referentie: oRs("bes_bestelopdr_id").Value,
                                         lev_uit: oRs("uitvoerende").Value,
                                         lev_uit_key: oRs("uitvoerende_key").Value,
                                         lev_uit_type: oRs("pbtype").Value,
                                         lev_uit_intern: oRs("intern").Value == 1,
                                         lev_opm: oRs("lev_opm").Value,
                                         reltype_oms: oRs("reltype_oms").Value,
                                         status: status.getbesopdrstatustext(oRs("bes_bestelopdr_status").Value),
                                         startdatum: toDateString(oRs("startdatum").Value),
                                         einddatum: toDateString(oRs("einddatum").Value),
                                         periode: oRs("periode").Value,
                                         levkosten: oRs("bes_bestelling_levkosten").Value,
                                         korting: oRs("bes_bestelling_korting").Value,
                                         totbedrag: oRs("totaalbedrag").Value,
                                         gefactureerd: oRs("gefactureerd").Value,
                                         gefactureerd_jaar: oRs("gefactureerd_jaar").Value,
                                         kostensoort_key: oRs("kostensoort_key").Value,
                                         kostenplaats_key: oRs("prs_kostenplaats_key").Value,
                                         loc_code: oRs("loc_code").Value,
                                         alg_key: oRs("alg_key").Value,
                                         bes_bestelopdr_id: oRs("bes_bestelopdr_id").Value,
                                         btwtabel_key: oRs("btwtabel_key").Value,
                                         bestelling_key: oRs("bes_bestelling_key").Value
                                       };
                          oRs.MoveNext();
                          if (!oRs.eof && result.kostensoort_key != oRs("kostensoort_key").Value)
                          {
                            // Er zijn meerdere regels resultaat met verschillende kostensoorten.
                            // Er zijn meerdere kostensoorten onder de verschillende artikelen binnen de bestelling.
                            // Ik kan geen goede keuze maken. Laat kostensoort leeg.
                            result.kostensoort_key = null;
                            result.multi_kostensoort = true;
                          }
                        }
                        else
                        {
                          var result = { message: L("lcl_fin_not_exist") };
                        }
                        oRs.close();
                        break;
              case "C": // Contract
                        // Vind informatie van het contract gegeven de contract_key
                        sql = "SELECT COALESCE((SELECT b.prs_bedrijf_naam FROM prs_bedrijf b WHERE b.prs_bedrijf_key = c.cnt_prs_bedrijf_key),"
                              + "              (SELECT " + S("prs_pers_string") + " FROM prs_perslid p WHERE p.prs_perslid_key = c.cnt_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"
                            + "     , COALESCE ((SELECT 'A' pbtype"
                              + "                  FROM prs_afdeling a"
                              + "                 WHERE a.prs_afdeling_key = c.cnt_prs_afdeling_key),"
                              + "               (SELECT 'P' pbtype"
                              + "                  FROM prs_perslid p"
                              + "                 WHERE p.prs_perslid_key = c.cnt_prs_perslid_key),"
                              + "               (SELECT 'B' pbtype"
                              + "                  FROM prs_bedrijf d"
                              + "                 WHERE d.prs_bedrijf_key = c.cnt_prs_bedrijf_key)) pbtype"
                            + "     , COALESCE ((SELECT 1 intern"
                              + "                  FROM prs_afdeling a"
                              + "                 WHERE a.prs_afdeling_key = c.cnt_prs_afdeling_key),"
                              + "               (SELECT 1 intern"
                              + "                  FROM prs_perslid p"
                              + "                 WHERE p.prs_perslid_key = c.cnt_prs_perslid_key),"
                              + "               (SELECT prs_bedrijf_intern intern"
                              + "                  FROM prs_bedrijf d"
                              + "                 WHERE d.prs_bedrijf_key = c.cnt_prs_bedrijf_key)) intern"
                            + "     , COALESCE(c.cnt_prs_bedrijf_key, c.cnt_prs_afdeling_key, c.cnt_prs_perslid_key, -1) uitvoerende_key"
                            + "     , (SELECT b.prs_bedrijf_opmerking"
                              + "        FROM prs_bedrijf b"
                              + "       WHERE b.prs_bedrijf_key = c.cnt_prs_bedrijf_key) lev_opm"
                            + "     , (SELECT rt.prs_relatietype_omschrijving"
                              + "        FROM prs_bedrijf b"
                              + "           , prs_relatietype rt"
                              + "       WHERE b.prs_relatietype_key = rt.prs_relatietype_key"
                              + "         AND b.prs_bedrijf_key = c.cnt_prs_bedrijf_key) reltype_oms"
                            + "     , cnt_contract_versie cnt_versie"
                            + "     , c.cnt_contract_looptijd_van startdatum"
                            + "     , c.cnt_contract_looptijd_tot einddatum"
                            + "     , TO_CHAR (SYSDATE, 'YYYY-MM') periode"
                            + "     , COALESCE(c.cnt_contract_kosten, 0) totaalbedrag"
                            + "     , COALESCE (c.cnt_contract_termijnkosten, 0) termijnbedrag"
                            + "     , COALESCE((SELECT SUM(f.fin_factuur_totaal)"
                              + "                 FROM fin_factuur f"
                              + "                WHERE f.fin_factuur_key <> " + fin_factuur.fin_key
                              + "                  AND f.fin_factuur_statuses_key <> 1"
                              + "                  AND f.fin_factuur_verwijder IS NULL"
                              + "                  AND f.cnt_contract_key = c.cnt_contract_key), 0) gefactureerd"
                            + "     , COALESCE((SELECT SUM(f.fin_factuur_totaal)"
                              + "                 FROM fin_factuur f"
                              + "                WHERE f.cnt_contract_key = c.cnt_contract_key"
                              + "                  AND f.fin_factuur_key <> " + fin_factuur.fin_key
                              + "                  AND f.fin_factuur_statuses_key <> 1"
                              + "                  AND f.fin_factuur_verwijder IS NULL"
                              + "                  AND UPPER(f.fin_factuur_boekmaand) LIKE " + safe.quoted_sql_wild(fin_factuur.fin_boekm_jaar + "%") + "), 0) gefactureerd_jaar"
                            + "     , COALESCE(c.prs_kostensoort_key, (SELECT id.prs_kostensoort_key"
                              + "                                        FROM ins_tab_discipline id"
                              + "                                       WHERE id.ins_discipline_key = c.ins_discipline_key)) kostensoort_key"
                            + "     , COALESCE((SELECT b.fin_btwtabel_key"
                              + "                 FROM prs_bedrijf b"
                              + "                WHERE b.prs_bedrijf_key = cnt_prs_bedrijf_key),"
                              + "              (SELECT fin_btwtabel_key"
                              + "                 FROM fin_btwtabel"
                              + "                WHERE fin_btwtabel_default = 1)) btwtabel_key"
                            + "     , c.ins_discipline_key"
                            + "     , c.cnt_contract_status"
                            + "     , c.prs_kostenplaats_key"
                            + "     , (SELECT dp.cnt_srtcontract_type"
                            + "          FROM cnt_disc_params dp"
                            + "         WHERE dp.cnt_ins_discipline_key = c.ins_discipline_key) cnt_srtcontract_typ"
                            + "  FROM cnt_v_aanwezigcontract c"
                            + " WHERE c.cnt_contract_key = " + fin_factuur.cnt_key;

                        var oRs = Oracle.Execute(sql);

                        if (!oRs.eof)
                        {
                          var result = { ref_key: fin_factuur.cnt_key,
                                         ref_type: "C",
                                         ref_volgnr: oRs("cnt_versie").Value,
                                         referentie: 'C' + fin_factuur.cnt_nr+(oRs("cnt_versie").Value ? '.'+oRs("cnt_versie").Value:''),
                                         lev_uit: oRs("uitvoerende").Value,
                                         lev_uit_key: oRs("uitvoerende_key").Value,
                                         lev_uit_type: oRs("pbtype").Value,
                                         lev_uit_intern: oRs("intern").Value == 1,
                                         lev_opm: oRs("lev_opm").Value,
                                         reltype_oms: oRs("reltype_oms").Value,
                                         status: status.getcntstatustext(oRs("cnt_contract_status").Value),
                                         startdatum: toDateString(oRs("startdatum").Value),
                                         einddatum: toDateString(oRs("einddatum").Value),
                                         periode: oRs("periode").Value,
                                         totbedrag: oRs("totaalbedrag").Value,
                                         termbedrag: oRs("termijnbedrag").Value,
                                         gefactureerd: oRs("gefactureerd").Value,
                                         gefactureerd_jaar: oRs("gefactureerd_jaar").Value,
                                         kostensoort_key: oRs("kostensoort_key").Value,
                                         kostenplaats_key: oRs("prs_kostenplaats_key").Value,
                                         btwtabel_key: oRs("btwtabel_key").Value,
                                         disc_key: oRs("ins_discipline_key").Value,
                                         srtcontract_type: oRs("cnt_srtcontract_typ").Value
                                       };
                        }
                        else
                        {
                          var result = { message: L("lcl_fin_not_exist")
                                       };
                        }
                        oRs.close();

                        // Locations + Buildings
                        sql = "SELECT 0"
                            + ", cnt_alg_plaats_code"
                            + ", l.alg_locatie_omschrijving"
                            + ", cnt_alg_plaats_key"
                            + " FROM cnt_contract_plaats"
                            + ", alg_locatie l"
                            + " WHERE cnt_alg_plaats_key = l.alg_locatie_key"
                            + " AND cnt_alg_plaats_code = 'L'"
                            + " AND cnt_contract_plaats_verwijder IS NULL"
                            + " AND cnt_contract_key = " + fin_factuur.cnt_key
                            + " UNION ALL "
                            + " SELECT 1"
                            + ", cnt_alg_plaats_code"
                            + ", l.alg_locatie_omschrijving"
                            + ", cnt_alg_plaats_key"
                            + " FROM cnt_contract_plaats"
                            + ", alg_locatie l"
                            + ", alg_gebouw g "
                            + " WHERE cnt_alg_plaats_code = 'G'"
                            + " AND cnt_alg_plaats_key=g.alg_gebouw_key"
                            + " AND g.alg_locatie_key=l.alg_locatie_key"
                            + " AND cnt_contract_plaats_verwijder IS NULL"
                            + " AND cnt_contract_key = "+ fin_factuur.cnt_key
                            + " UNION ALL "
                            + " SELECT 1"
                            + ", cnt_alg_plaats_code"
                            + ", l.alg_locatie_omschrijving"
                            + ", cnt_alg_plaats_key"
                            + " FROM cnt_contract_plaats"
                            + ", alg_locatie l"
                            + ", alg_terreinsector t"
                            + " WHERE cnt_alg_plaats_code = 'T'"
                            + " AND cnt_alg_plaats_key=t.alg_terreinsector_key"
                            + " AND t.alg_locatie_key=l.alg_locatie_key"
                            + " AND cnt_contract_plaats_verwijder IS NULL"
                            + " AND cnt_contract_key = " + fin_factuur.cnt_key
                            + " ORDER BY 3";
                        oRs = Oracle.Execute(sql);

                        if (!oRs.eof)
                        {
                          result.show_loc = 1;
                          result.loc_geg = [];
                        }

                        while (!oRs.eof)
                        {
                          result.loc_geg.push({ loc_key: oRs("cnt_alg_plaats_key").Value,
                                                loc_desc: oRs("alg_locatie_omschrijving").Value
                                              });
                          oRs.MoveNext();
                        }
                        oRs.close();
                        break;
              default:  // Geen bekend type gevonden
                        var result = { message: L("lcl_fin_not_exist")
                                     };
                        break;
            }

            if (result.kostensoort_key > 0)
            {
                sql = "SELECT ks.prs_kostensoort_oms || '-' || " + lcl.xsql("ks.prs_kostensoort_opmerking", "ks.prs_kostensoort_key") + " kostensoort_oms"
                    + "  FROM prs_kostensoort ks"
                    + " WHERE ks.prs_kostensoort_key = " + result.kostensoort_key;
                oRs = Oracle.Execute(sql);
                result.kostensoort_oms = oRs("kostensoort_oms").Value;
                oRs.close();
            }

            if (result.kostenplaats_key > 0)
            {
                var sql = "SELECT k.prs_perslid_key,"
                        +    S("prs_kpn_string") + " kostenplaats_naam"
                        + "  FROM prs_kostenplaats k"
                        + " WHERE k.prs_kostenplaats_key = " + result.kostenplaats_key;
                oRs = Oracle.Execute(sql);
                result.fin_budgethouder = oRs("prs_perslid_key").Value;
                result.kostenplaats_naam = oRs("kostenplaats_naam").Value;
                oRs.Close();
            }

            if (result.btwtabel_key > 0)
            {
              result.btwtabel = fin.btwtabel_info(result.btwtabel_key);
            }

            if (result.lev_uit_key > 0)
            {
              var result_getfe = fin.getfactuurexist(fin_factuur_nr, result.lev_uit_key, -1);
              result.aantalfacturen = result_getfe.aantal;
              result.totaalbedrag = result_getfe.totaalbedrag;
              result.totaalbtwbedrag = result_getfe.totaalbtwbedrag;
            }

            if (fin_factuur.mldopdr_key > 0)
            {
                result.opdr_materiaal = fin.opdr_materiaal_info(fin_factuur.mldopdr_key);
            }

            return result;
          },

        opdr_materiaal_info: function (mldopdr_key)
        {
          var this_opdr = mld.func_enabled_opdracht(mldopdr_key); // wat mag ik zoal op deze opdracht
          var sql = "SELECT ud.mld_opdr_materiaal_key"
                  + "     , fu.fac_usrdata_key"
                  + "     , ud.mld_opdr_materiaal_aantal"
                  + "     , ud.mld_opdr_materiaal_eenheid"
                  + "     , ud.mld_opdr_materiaal_prijs"
                  + "     , (ud.mld_opdr_materiaal_aantal * ud.mld_opdr_materiaal_prijs) totaal"
                  + "     , " + lcl.xsqla("fu.fac_usrdata_omschr", "fu.fac_usrdata_key")
                  + "     , ud.mld_opdr_materiaal_omschr"
                  + "     , ud.mld_opdr_materiaal_info"
                  + "     , b.fin_btwtabelwaarde_oms"
                  + "     , (ud.mld_opdr_materiaal_aantal * ud.mld_opdr_materiaal_prijs * (100+b.fin_btwtabelwaarde_perc)/100) totaalincbtw"
                  + "     , b.fin_btwtabelwaarde_key"
                  + " FROM mld_opdr_materiaal ud"
                  + "    , fac_usrdata fu"
                  + "    , fin_btwtabelwaarde b"
                  + " WHERE ud.fac_usrdata_key = fu.fac_usrdata_key (+)"
                  + "   AND ud.fin_btwtabelwaarde_key = b.fin_btwtabelwaarde_key (+)"
                  + "   AND ud.mld_opdr_key = " + mldopdr_key
                  + " ORDER BY fu.fac_usrdata_volgnr"
                  + "        , UPPER(" + lcl.xsql("fu.fac_usrdata_omschr", "fu.fac_usrdata_key" )+ ")";

          var opdr_materiaal = {readonly: !this_opdr.canChange,
                                list: []
                               };
          var oRs = Oracle.Execute(sql);
          while (!oRs.eof)
          {
            opdr_materiaal.list.push({ key:         oRs("mld_opdr_materiaal_key").Value,
                                  aantal:      oRs("mld_opdr_materiaal_aantal").Value,
                                  eenheid:     oRs("mld_opdr_materiaal_eenheid").Value,
                                  prijs:       oRs("mld_opdr_materiaal_prijs").Value,
                                  totaal:      oRs("totaal").Value,
                                  totaalincl:  oRs("totaalincbtw").Value,
                                  oms:         oRs("mld_opdr_materiaal_omschr").Value,
                                  info:        oRs("mld_opdr_materiaal_info").Value,
                                  usrdata_oms: oRs("fac_usrdata_omschr").Value,
                                  btw_key:     oRs("fin_btwtabelwaarde_key").Value,
                                  btw_oms:     oRs("fin_btwtabelwaarde_oms").Value
                                });
            oRs.MoveNext();
          }
          oRs.Close();
          return opdr_materiaal;
        },

        btwtabel_info: function (btw_tabel_key)
        {
          var sql = "SELECT fin_btwtabelwaarde_key"
                  + "     , fin_btwtabelwaarde_perc"
                  + "     , " + lcl.xsqla('fin_btwtabelwaarde_oms', 'fin_btwtabelwaarde_key')
                  + "     , fin_btwtabelwaarde_verlegd"
                  + " FROM fin_btwtabelwaarde"
                  + " WHERE fin_btwtabel_key = " + btw_tabel_key
                  + "   AND fin_btwtabelwaarde_verwijder IS NULL"
                  + " ORDER BY fin_btwtabelwaarde_perc"
                  + ", UPPER("+lcl.xsql('fin_btwtabelwaarde_oms', 'fin_btwtabelwaarde_key')+")";
          var btwtabel = []
          var oRs = Oracle.Execute(sql);
          while (!oRs.eof)
          {
            btwtabel.push({ key:     oRs("fin_btwtabelwaarde_key").Value,
                            perc:    oRs("fin_btwtabelwaarde_perc").Value,
                            oms:     oRs("fin_btwtabelwaarde_oms").Value,
                            verlegd: oRs("fin_btwtabelwaarde_verlegd").Value == 1
                         });
            oRs.moveNext();
          }
          oRs.close();
          return btwtabel;
        },

        sendNeedApprovalNotification: function (factuur_key, approver_key)
        {
          var lsender;
          if (approver_key == null || approver_key == -1)
            return false;

          // These notifications are now sent on behalf of the system, what might be the local FM organisation
          // Afhankelijk van waar de factuur voor is (Bestelling (B), Contract (C) of Opdracht (O)) de sender bepalen.
          var lsender = null;
          var fin_factuur = fin.factuur_info(factuur_key); // Globale variabele met alle fin_factuur informatie.
          if (fin_factuur.ref_type == 'B')
          {
            var sql = "SELECT l.alg_locatie_email"
                    + "  FROM mld_adres ma"
                    + "     , alg_locatie l"
                    + "     , bes_bestelling b"
                    + " WHERE b.mld_adres_key_lev = ma.mld_adres_key"
                    + "   AND ma.alg_locatie_key = l.alg_locatie_key"
                    + "   AND b.bes_bestelling_key = " + fin_factuur.besopdr_key;
            var oRs = Oracle.Execute(sql);
            if (!oRs.eof)
              var lsender = oRs("alg_locatie_email").Value;
            else
              var lsender = null;
            oRs.Close();
          }
          else if (fin_factuur.ref_type == 'C')
          {
            var lsender = cnt.findSenderForNotifications(fin_factuur.cnt_key);
          }
          else if (fin_factuur.ref_type == 'O')
          {
             var sql = "SELECT COALESCE (l1.alg_locatie_email, l2.alg_locatie_email)"
                     + "  FROM mld_opdr o"
                     + "     , mld_melding m"
                     + "     , mld_adres ma"
                     + "     , alg_locatie l1"
                     + "     , alg_locatie l2"
                     + " WHERE m.mld_adres_key = ma.mld_adres_key(+)"
                     + "   AND ma.alg_locatie_key = l1.alg_locatie_key(+)"
                     + "   AND m.mld_alg_locatie_key = l2.alg_locatie_key(+)"
                     + "   AND m.mld_melding_key = o.mld_melding_key"
                     + "   AND o.mld_opdr_key = " + fin_factuur.mldopdr_key;
             var oRs = Oracle.Execute(sql);
             if (!oRs.eof)
               lsender = oRs(0).Value;
             else
               lsender = null;
          }

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

          Oracle.Execute("BEGIN fac.putnotificationsrtprio(NULL"
                                                      + ", " + approver_key
                                                      + ", 'FIN2GO'"
                                                      + ", " + factuur_key
                                                      + ", fin.sprintf(" + safe.quoted_sql(oms) + ", " + factuur_key + ")"
                                                      + ",  NULL, NULL, NULL, NULL, 2"
                                                      + ", " + (lsender ?  safe.quoted_sql(lsender) : "NULL") + "); END;");

          var sql = "SELECT prs_perslid_naam_full FROM prs_v_perslid_fullnames_all WHERE prs_perslid_key = " + approver_key;
          var oRs = Oracle.Execute(sql);
          var prsname = oRs("prs_perslid_naam_full").Value;
          oRs.Close();
          return L("lcl_fin_reggoedkeuren") + prsname;
        },

        getfactuurexist:
          function _getfactuurexist(fac_nr, lev_uit_key, fin_key)
          { // Controle op het Factuurnr (van de leverancier) en of dat dan van dezelfde leverancier(!) al bestaat.
            var sql = "SELECT COUNT(f.fin_factuur_key) aantal_facturen"
                    + ", COALESCE (SUM (f.fin_factuur_totaal), 0) totaal_bedrag"
                    + ", COALESCE (SUM (f.fin_factuur_totaal_btw), 0) totaal_bedrag_btw"
                    + " FROM fin_factuur f"
                    + ", mld_opdr o"
                    + " WHERE f.mld_opdr_key = o.mld_opdr_key"
                    + " AND f.fin_factuur_verwijder IS NULL"
                    + " AND f.fin_factuur_nr = " + safe.quoted_sql(fac_nr)
                    + " AND o.mld_uitvoerende_keys = " + lev_uit_key
                    + (fin_key > 0
                      ? " AND f.fin_factuur_key != " + fin_key
                      : "")
                    + " UNION ALL"
                    + " SELECT COUNT(f.fin_factuur_key) aantal_facturen"
                    + ", COALESCE (SUM (f.fin_factuur_totaal), 0) totaal_bedrag"
                    + ", COALESCE (SUM (f.fin_factuur_totaal_btw), 0) totaal_bedrag_btw"
                    + " FROM fin_factuur f"
                    + ", bes_bestelopdr bo"
                    + " WHERE f.bes_bestelopdr_key = bo.bes_bestelopdr_key"
                    + " AND f.fin_factuur_verwijder IS NULL"
                    + " AND f.fin_factuur_nr = " + safe.quoted_sql(fac_nr)
                    + " AND bo.prs_bedrijf_key = " + lev_uit_key
                    + (fin_key > 0
                      ? " AND f.fin_factuur_key != " + fin_key
                      : "")
                    + " UNION ALL"
                    + " SELECT COUNT(f.fin_factuur_key) aantal_facturen"
                    + ", COALESCE (SUM (f.fin_factuur_totaal), 0) totaal_bedrag"
                    + ", COALESCE (SUM (f.fin_factuur_totaal_btw), 0) totaal_bedrag_btw"
                    + " FROM fin_factuur f"
                    + ", cnt_contract c"
                    + " WHERE f.cnt_contract_key = c.cnt_contract_key"
                    + " AND f.fin_factuur_verwijder IS NULL"
                    + " AND f.fin_factuur_nr = " + safe.quoted_sql(fac_nr)
                    + " AND c.cnt_prs_bedrijf_key = " + lev_uit_key
                    + (fin_key > 0
                      ? " AND f.fin_factuur_key != " + fin_key
                      : "");
            sql = "SELECT SUM(aantal_facturen) aantal_facturen"
                + ", SUM(totaal_bedrag) totaal_bedrag"
                + ", SUM(totaal_bedrag_btw) totaal_btw_bedrag"
                + " FROM (" + sql + ")";

            var oRs = Oracle.Execute(sql);
            var result = { fac_nr: fac_nr,
                           aantal: oRs("aantal_facturen").Value? oRs("aantal_facturen").Value : 0,
                           totaalbedrag: oRs("totaal_bedrag").Value? oRs("totaal_bedrag").Value : 0,
                           totaalbtwbedrag: oRs("totaal_btw_bedrag").Value
                         };
            oRs.close();
            return result;
          },

        getfinstatustext:
          function (p) {
             var statustekst = "??";
             var s = parseInt(p, 10);
             switch (s) {
                 case 3: { statustekst = L("lcl_fin_incompleet"); break; }
                 case 1: { statustekst = L("lcl_fin_afgewezen"); break; }
                 case 2: { statustekst = L("lcl_fin_ingevoerd"); break; }
                 case 5: { statustekst = L("lcl_fin_ter_goedgekeuring"); break; }
                 case 6: { statustekst = L("lcl_fin_akkoord"); break; }
                 case 7: { statustekst = L("lcl_fin_verwerkt"); break; }
             }
             if (Session("logging")>0)
               statustekst += " ("+String(s)+")";
             return statustekst;
          },

        getfinbrontext:
          function (p) {
              var brontekst = "??";
              var s = parseInt(p,10);
              switch (s) {
                  case 0: { brontekst = L("lcl_fin_source_manual"); break; }
                  case 1: { brontekst = L("lcl_fin_source_excel"); break; }
                  case 2: { brontekst = L("lcl_fin_source_mail"); break; }
              }
              if (Session("logging")>0)
                brontekst += " ("+String(s)+")";
              return brontekst;
          },

        deleteFactuurregel:
          function _deleteFactuurregel(pFinregel_key)
          {
            var lmessage;
            // Eerst de kenmerken van de regel verwijderen.
              sql = "DELETE FROM fin_kenmerkfactregel"
                  + " WHERE fin_factuurregel_key =  " + pFinregel_key;
            oRs = Oracle.Execute(sql);

            // Verwijderen factuurregel.
            sql = "DELETE FROM fin_factuurregel"
                + " WHERE fin_factuurregel_key = " + pFinregel_key;
            Oracle.Execute(sql);
          },

          CreateEditRow: function _CreateEditRow(rowIndex, params) // als je hieronder iets aanpast controleer dan ook fin_edit_factuur.js/AddItem
          { // Let op: er staan geen individuele events op de velden, die worden in fin_edit_factuur/ $.ready
            //         op de de hele tabel gezet
            var html = ["\n<tr id='trfin" + rowIndex + "' class='" + (rowIndex & 1? "O " : "E ") + "' ROWKEY='" + (params.copy? -1 : params.regel_key) + "'>"];

            // Create drop button
            html.push("<td><i class='fa fa-fw fa-trash-o fa-lg' OnClick='DeleteOrderLine(" + rowIndex + ")' style='cursor:pointer'></i></td>");

            // Create description field
            html.push("<td id='tdfin" + rowIndex + "'>"
                    + "<input type='text' class='fldnotresponsive' id='descript" + rowIndex + "' name='descript" + rowIndex + "' maxlength='60' value='" + safe.htmlattr(params.descr) + "'>"
                    + "</td>");

            // Create reference field
            html.push("<td><input type='text' class='fldfinref'"
                    + " id='ref" + rowIndex + "' name='ref" + rowIndex + "' maxlength='30' value='" + safe.htmlattr(params.ref) + "'></td>");

            if (S("fin_enable_kostensoort") != 0)
            { // Create kostensoort field
              // In fin_edit_factuur.asp wordt er clientside een suggest van gemaakt
              html.push("<td>"
                      + "<input id='fincostsrt" + rowIndex + "_show' class='fldfincostsrt fldnotresponsive' value='" + safe.htmlattr(params.ksrt_oms) + "'>"
                      + "<input type='hidden' id='fincostsrt" + rowIndex + "' name='fincostsrt" + rowIndex + "' value='" + (params.ksrt_key||-1) + "'>"
                      + "</td>");
            }

            // Create sum field
            html.push("<td align='right'><input type='text' class='fldfinbedrag'"
                           + " id='sum" + rowIndex + "' name='sum" + rowIndex + "' maxlength='10' value='" + safe.curreditable(params.sum) + "'></td>");

            // Create BTW field
            var thisBTW = {};

            var htmlText = "<select type='text' class='fldfinbtw' id='BTW" + rowIndex
                     + "' name='BTW" + rowIndex + "'>"
            for (var j = 0; j < params.btwtabel.length; j++)
            {
              if (params.btwkey == params.btwtabel[j].key)
                thisBTW = params.btwtabel[j];
              htmlText += "<option value='" + params.btwtabel[j].key + "'"
                        + (params.btwkey == params.btwtabel[j].key? " selected='1'" : "") + ">"
                        + safe.html(params.btwtabel[j].oms) + "</option>"
            }
            htmlText += "</select>";
            html.push("<td align='right'>" + htmlText + "</td>");

            // Sum incl. tax + hidden regel_key input veld.
            html.push("<td align='right'>"
                    + "<input type='text' class='fldfinbedrag' readonly='1' id='sumBTW" + rowIndex + "' "
                    + "value='" + S("currency_pref") + safe.curreditable(params.sumBTW) + "'>"
                    + '<input type="hidden" id="regel_key' + rowIndex + '"  name="regel_key' + rowIndex + '" value="' + (params.copy? -1 : params.regel_key) + '">'
                    + '<input type="hidden" id="regel_id' + rowIndex + '"  name="regel_id' + rowIndex + '" value="trfin' + rowIndex + '">'
                    + "</td>");

            html.push("</tr>");

            if (params.hasAnyFlex) // Alleen tonen indien er flexkenmerken zijn.
            {
              html.push("\n<tr id='trfin" + rowIndex + "inline' class='" + (rowIndex & 1? "O " : "E ") + "'>");
              html.push("<td></td>");
              html.push("<td id='tdinline" + rowIndex + "'>"
                      + "<table id='flextable' cellpadding='0' cellspacing='0'>");
              Response.Write(html.join(""));
              generateFlexKenmerkCode ({ fin_key: -1,
                                         regel_key: params.regel_key,
                                         kenmerk_niveau: 'R',
                                         nameprefix: (params.regel_key == -1 || params.copy? "trfin" + rowIndex : "flex" + params.regel_key)
                                       });
              html = [];
              html.push("</table>");
              html.push("</td>");
              html.push("<td></td><td></td><td></td><td></td>");
              html.push("</tr>");
            }
            Response.Write(html.join(""));
          },

          hasAnyRegelFlex: function()
          {
            var sql = "SELECT k.fin_kenmerk_key"
                    + "  FROM fin_kenmerk k"
                    + " WHERE k.fin_kenmerk_verwijder IS NULL"
                    + "   AND k.fin_kenmerk_type LIKE 'R'"
            var oRs = Oracle.Execute(sql);
            var hasAnyFlex = !oRs.eof;
            oRs.Close();
            return hasAnyFlex;
          },

          regelSQL: function(fin_key)
          {
            return   "SELECT fr.fin_factuurregel_key"
                   + "     , fr.fin_factuurregel_nr"
                   + "     , fr.fin_factuurregel_totaal"
                   + "     , (SELECT btw.fin_btwtabelwaarde_perc"
                     + "        FROM fin_btwtabelwaarde btw"
                     + "       WHERE btw.fin_btwtabelwaarde_key = fr.fin_btwtabelwaarde_key) BTW" // Geef de huidige waarde terug ook al is de BTW waarde verwijderd.
                   + "     , fr.fin_btwtabelwaarde_key"
                   + "     , fr.fin_factuurregel_btw + fr.fin_factuurregel_totaal sumBTW"
                   + "     , fr.fin_factuurregel_omschrijving"
                   + "     , fr.fin_factuurregel_referentie"
                   + "     , fr.prs_kostensoort_key"
                   + "     , NVL2(ks.prs_kostensoort_key, ks.prs_kostensoort_oms || '-' || " + lcl.xsql("ks.prs_kostensoort_opmerking", "ks.prs_kostensoort_key") + ", NULL) kostensoort"
                   + "     , (SELECT btw.fin_btwtabelwaarde_verlegd"
                     + "        FROM fin_btwtabelwaarde btw"
                     + "       WHERE btw.fin_btwtabelwaarde_key = fr.fin_btwtabelwaarde_key"
                     + "         AND fin_btwtabelwaarde_verwijder IS NULL) verlegd"
                     + "   , (SELECT COUNT(f.fin_kenmerk_key)"
                     + "        FROM fin_kenmerkfactregel f"
                     + "           , fin_kenmerk k"
                     + "       WHERE k.fin_kenmerk_key = f.fin_kenmerk_key"
                     + "         AND f.fin_kenmerkfactregel_verwijder IS NULL"
                     + "         AND k.fin_kenmerk_type = 'R'"
                     + "         AND f.fin_factuurregel_key = fr.fin_factuurregel_key) aantalkenmerken"
                   + "  FROM fin_factuurregel fr"
                   + "     , prs_kostensoort ks"
                   + " WHERE fr.prs_kostensoort_key = ks.prs_kostensoort_key(+)"
                   + "   AND fr.fin_factuur_key = " + fin_key
                   + " ORDER BY fr.fin_factuurregel_nr, fr.fin_factuurregel_key ";
          },

          generateFINregels: function _generateFINregels(this_fin, btwtabel)
          {
            var rowIndex = 0;

            var oRs = Oracle.Execute(fin.regelSQL(this_fin.factuur_info.fin_key));
            while (!oRs.eof)
            {
                rowIndex ++;
                fin.CreateEditRow(rowIndex,
                                  { hasAnyFlex: fin.hasAnyRegelFlex(),
                                    regel_key: oRs("fin_factuurregel_key").Value,
                                    regel_nr: oRs("fin_factuurregel_nr").Value,
                                    sum: oRs("fin_factuurregel_totaal").Value,
                                    BTW: oRs("BTW").Value,
                                    btwkey: oRs("fin_btwtabelwaarde_key").Value,
                                    btwtabel: btwtabel,
                                    sumBTW: oRs("sumBTW").Value,
                                    descr: oRs("fin_factuurregel_omschrijving").Value,
                                    ref: oRs("fin_factuurregel_referentie").Value,
                                    ksrt_key: oRs("prs_kostensoort_key").Value,
                                    ksrt_oms: oRs("kostensoort").Value,
                                    verlegd: oRs("verlegd").Value,
                                    copy: this_fin.fin_key != this_fin.factuur_info.fin_key // Bij kopiëren factuur zijn de waarden niet identiek.
                                 });
                oRs.moveNext();
            }
            oRs.close();
            return rowIndex
          },

          // Bewerkbare regels
          showEditableFINregels: function _showEditableFINregels(this_fin, btwtabel)
          {
           var fin_factuur = this_fin.factuur_info;
           var hasMateriaal = this_fin.referentieinfo && this_fin.referentieinfo.opdr_materiaal && this_fin.referentieinfo.opdr_materiaal.list.length;
           var html = [];
            // SELECTED ITEMS
            html.push("<tr><td>"
                    + "<table class='finrtable' id='sel_items'>"
                    + "<tr>"
                    + "<th>"
                    + (this_fin.canInvLinChange
                      ? "<span class='fa fa-plus button' title='" + L("lcl_add") + "' OnClick='AddItem();FcltMgr.resized();'></span>"
                      : "")
                    + "&nbsp;<span id='imp_materiaal' title='" + L("lcl_import") + "'"
                      + (hasMateriaal ? "" :  " style='display: none'")
                      + " class='fa fa-file-text-o button' OnClick='AddOpdrMaterial();FcltMgr.resized();'></span>"
                    + "</th>"
                    + "<th>" + L("lcl_descr") + "</th>"
                    + "<th>" + L("lcl_location") + "</th>"
                    + (S("fin_enable_kostensoort") != 0
                      ? "<th>" + L("lcl_shared_charge_type") + "</th>"
                      : '')
                    + "<th style='text-align:right'>" + L("lcl_fin_total_sum_exBTW") + " (" + L("lcl_valutasign") + ")" + "</th>"
                    + "<th style='text-align:right'>" + L("lcl_fin_btwtarief") + "</th>"
                    + "<th style='text-align:right'>" + L("lcl_fin_total_sum_inBTW") + "</th>"
                    + '</tr>'
                    + '<tbody>');
            Response.Write(html.join(""));

            var rowIndex = 0
            if (!this_fin.copy)
              var rowIndex = fin.generateFINregels(this_fin, serversidebtwtabel);

            html = [];
            html.push("</tbody>"
                    + "</table>"
                    + "<div id='total_list' align='right'>"
                    + "<table>"
                    + "<input type='hidden' id='rowIndex' name='rowIndex' value='" + rowIndex + "'>"
                    + "<tr>"
                    + "<td class='label'><label>" + L("lcl_fin_totaal_bedrag") + ":</label></td>"
                    + "<td id='totalEXC_txt'>" + S("currency_pref") + " " + safe.curr(fin_factuur.fin_totaal) + " " + S("currency_suff") + "</td>"
                    + "</tr>"
                    + "<tr>"
                    + "<td class='label'><label>" + L("lcl_fin_totaal_bedrag_btw") + ":</label></td>"
                    + "<td id='totalBTW_txt'>" + S("currency_pref") + " " + safe.curr(fin_factuur.fin_totaal + fin_factuur.fin_totaal_btw) + " " + S("currency_suff") + "</td>"
                    + "</tr>"
                    + "</table>"
                    + '</div>'
                    + '</td></tr>');
            Response.Write(html.join(""));
          },

          showReadableFINregels: function _showReadableFINregels()
          {
            // Zijn er kenmerken bij deze factuur regels
            var sql = "SELECT k.fin_kenmerk_key kenmerk_key"
                    + "     , kfr.fin_kenmerkfactregel_waarde"
                    + "  FROM fin_factuurregel fr"
                    + "     , fin_kenmerkfactregel kfr"
                    + "     , fin_kenmerk k"
                    + " WHERE fr.fin_factuurregel_key = kfr.fin_factuurregel_key"
                    + "   AND kfr.fin_kenmerk_key = k.fin_kenmerk_key"
                    + "   AND fr.fin_factuur_key = " + fin_key
                    + "   AND k.fin_kenmerk_verwijder IS NULL"
                    + "   AND k.fin_kenmerk_type LIKE 'R'";

            function fnBTW(oRs)
            {   // TODO: rekening houden met verlegd
                if (oRs("BTW").Value == null)
                    return "";

                return oRs("BTW").Value + "%";
            }

            var rst = new ResultsetTable({ sql: fin.regelSQL(fin_key),
                                           keyColumn: "fin_factuurregel_key",
                                           noPrint: true,
                                           ID: "fintable",
                                           buttons: null,
                                           //title: L("lcl_fin_invoicerows"),
                                           flexModule: fin.hasAnyRegelFlex()?"FINR":null,
                                           flexId: "fin_factuurregel_key",
                                           showProperties: true,
                                           propertiesColumn: 4,
                                           //outputmode: outputmode,
                                           showAll: true
                                           //emptySetString : L("lcl_fin_note_emptyset")
                                         });

            rst.addColumn(new Column({caption: "", content: null, hidden: true })); // Lege kolom i.v.m. inline regel. Deze begint in de derde kolom.
            rst.addColumn(new Column({caption: L("lcl_descr"), content: "fin_factuurregel_omschrijving" }));
            rst.addColumn(new Column({caption: L("lcl_location"), content: "fin_factuurregel_referentie" }));
            if (S("fin_enable_kostensoort") != 0)
                rst.addColumn(new Column({caption: L("lcl_shared_charge_type"), content: "kostensoort" }));
            rst.addColumn(new Column({caption: L("lcl_fin_total_sum_exBTW")+ " (" + L("lcl_valutasign") + ")", content: "fin_factuurregel_totaal", datatype: "currency", total: true }));
            rst.addColumn(new Column({caption: L("lcl_fin_btwtarief"), content: fnBTW, align: "right" }));
            rst.addColumn(new Column({caption: L("lcl_fin_total_sum_inBTW"), content: "sumBTW", datatype: "currency", total: true }));

            var cnt = rst.processResultset();
          }
  }


%>
