<%@ LANGUAGE = JavaScript %>
<% /*
     $Revision$
     $Id$

    File:               mld_edit_melding_save.asp
    Description:        Sla de wijzigingen van mld_edit_melding op
    Parameters:         submit van mld/mld_edit_melding.asp en pda/melding.asp
    Note:               Eventueel maken we uiteindelijk een print-scherm aan!
                        Als backo opslaat dan wordt impliciet de status op 4 (geaccepteerd) gezet
                        Uiteindelijk willen we deze general purpose hebben, waarbij bv zo weinig mogelijk
                        velden verplicht zijn en zeker niet onnodig meegegeven hoeven te worden; vandaar
                        de introductie van de savewhen parameter in de save2db
*/
var JSON_Result = true;
%>

<!--  #include file="../Shared/common.inc" -->
<!--  #include file="../shared/save2db.inc" -->
<!--  #include file="../Shared/json2.js" -->
<!--  #include file="../Shared/kenmerk_common.inc" -->
<!--  #include file="mld.inc" -->

<%
function validReferenceKey(mldkey, refkey)
{
    // Is de opgegeven referentie een geldige melding?
    var result = false;
    if (refkey && refkey > 0)
    {
        var sql_r = "SELECT m.mld_melding_key"
                  + "  FROM mld_melding m"
                  + "     , mld_stdmelding sm"
                  + "  WHERE m.mld_melding_key = " + refkey
                  + "    AND m.mld_stdmelding_key = sm.mld_stdmelding_key"
                  + "    AND sm.mld_ins_discipline_key IN"
                    + " (SELECT ins_discipline_key"
                    + "    FROM fac_v_webgebruiker g"
                    + "       , fac_functie f"
                    + "   WHERE g.prs_perslid_key = " + user_key
                    + "     AND f.fac_functie_key = g.fac_functie_key"
                    + "     AND f.fac_functie_code IN ('WEB_MLDFOF', 'WEB_MLDBOF')"
                    + "     AND g.fac_gebruiker_alg_level_read < 9)"
                  + (mldkey==-1
                    ? ""
                    : "     AND m.mld_melding_key != " + mldkey  // niet naar jezelf refereren
                    )
                  + "   AND TRUNC(m.mld_melding_einddatum, 'DD') >= SYSDATE - " + S("mld_reference_days");
        var oRs_r = Oracle.Execute(sql_r);
        if (!oRs_r.eof)
            result = true;
        oRs_r.Close();
    }
    else
        result = true; // Geen referentie is altijd geldig.

    return result;
}

// AUTORISATIEPARAMETERS
var urole = getFParam("urole");
var fronto = urole == "fo";
var backo  = urole == "bo";
var frontend = (!fronto & !backo);

var mld_key = getFParamInt("mld_key", -1);
var parent_key = getFParamInt("parent_key", -1);
var isNew = (mld_key <= 0); // dan gaan we S("mld_melding_autoprint") beschouwen

var locatiekey = getFParamInt("locatiekey", -1);
var sBehandel = getFParamInt("sBehandel", -2);
var prio = getFParamInt("prio", mld_key>0?-1:3); // Default 3 voor nieuwe. Bij readonly bestaande meldingen de prio niet aanpassen.

// Bepaal de nieuwe waarde voor de checkbox afgerond.
var newvalafgerond = Request.Form("afgerond").count == 1? 1: 0;

// Als we geen locatiekey hebben maar wel een afleveradres, kunnen we mogelijk ook een locatiekey bepalen
var del_address = getFParamInt("del_address", -1);
if (locatiekey == -1 && hasFParam("del_address") && del_address != -1)
{
  oRs = Oracle.Execute('SELECT alg_locatie_key FROM mld_adres WHERE mld_adres_key = ' + del_address);
  if (!oRs.eof && oRs("alg_locatie_key").Value)
  {
    locatiekey = oRs("alg_locatie_key").Value;
  }
  oRs.Close();
}

// Objects...
var obj_arr = getFParamIntArray("r_objs", []);
var one_object = (obj_arr.length == 1); // Is er 1 object geselecteerd?

var forcesave = (getFParamInt("forcesave", 0) == 1);
var stdm_key = getFParamInt("stdm");
var stdm_info = mld.mld_stdmeldinginfo(stdm_key);

var meldbron_key = getFParamInt("meldbronkey", S("mld_meldbron_key"));


// Onroerendgoed_keys wordt de verfijnste van de opgegeven plaats
var gebouwkey     = getFParamInt("gebouwkey", -1);
var verdiepingkey = getFParamInt("verdiepingkey", -1);
var ruimtekey     = getFParamInt("ruimtekey", -1);

var alg_onroerendgoed_keys = -1;

if (stdm_info.ins_srtdiscipline_alglevel > 2)
{
  // Wis de onroerendgoed keys die op basis van alglevel niet van belang zijn.
  if (stdm_info.ins_srtdiscipline_alglevel < 3) gebouwkey = -1
  else if (stdm_info.ins_srtdiscipline_alglevel < 4) verdiepingkey = -1
  else if (stdm_info.ins_srtdiscipline_alglevel < 5) ruimtekey = -1;

  // die specifiekere plaats moet dan leegblijven
  if (ruimtekey != -1)
    alg_onroerendgoed_keys = ruimtekey;
  else if (verdiepingkey != -1)
    alg_onroerendgoed_keys = verdiepingkey;
  else if (gebouwkey != -1)
    alg_onroerendgoed_keys = gebouwkey;
}


var savemode = true;
if (!forcesave && (fronto || frontend) && isNew)
{
  // mld_stdmelding_doublecheck: 00 (0) Geen controle uitvoeren
  //                             01 (1) Controle dubbel bij invoer nieuwe melding (door FE, FO (of BO))
  //                             10 (2) Controle dubbel bij accpteren melding (door BO)
  //                             11 (3) Controle zowel bij invoer als bij accepteren
  if (stdm_info.doublecheck == 1 || stdm_info.doublecheck == 3)
  {
    // In facmgt moet altijd een verplicht niveau gekozen worden. stdm_info.alg_onrgoed_niveau heeft dus een waarde (R, V, G, L).
    var where_alg = "AND m.mld_alg_onroerendgoed_keys = org.alg_onroerendgoed_keys";
    if (!stdm_info.ins_srtdiscipline_alg)
        where_alg = "";
    else if (stdm_info.alg_onrgoed_niveau == "R")
        where_alg += " AND org.alg_ruimte_key = " + ruimtekey;
    else if (stdm_info.alg_onrgoed_niveau == "V")
        where_alg += " AND org.alg_verdieping_key = " + verdiepingkey;
    else if (stdm_info.alg_onrgoed_niveau == "G")
        where_alg += " AND org.alg_gebouw_key = " + gebouwkey;
    else if (stdm_info.alg_onrgoed_niveau == "L")
        where_alg += " AND org.alg_locatie_key = " + locatiekey;

    // Als er exact 1 object is geselecteerd beschouwen
    // we alleen meldingen op dat object

    sql = "SELECT DISTINCT m.mld_melding_key"
        + "  FROM mld_melding m"
        + (where_alg?
          "     , alg_v_allonroerendgoed org": "")
        + (one_object?
          "     , mld_melding_object mo" : "")
        + " WHERE m.mld_melding_status IN (0, 2, 3, 4, 7)"
        + (one_object
          ? "   AND m.mld_melding_key = mo.mld_melding_key"
            + " AND mo.ins_deel_key = " + obj_arr
          : "")
        + "   AND m.mld_melding_parentkey IS NULL" // Geen child meldingen tonen
        + "   AND m.mld_stdmelding_key = " + stdm_key
        + where_alg;
    oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    { // Er is mogelijk een dubbele melding aanwezig
      savemode = false;
    }
    oRs.Close();
  }
}

if (savemode)
{ // Verder met opslaan van de gegevens
  var sql = "SELECT ms.mld_ins_discipline_key"
          + "     , mld_stdmelding_vereisdienst"
          + "     , mld_stdmelding_autoorder"
          + "     , ms.prs_dienst_key"
          + "     , ms.mld_stdmelding_prseigen"
          + "     , ms.mld_typeopdr_key"
          + "     , " + lcl.xsqla('pd.prs_dienst_omschrijving', 'pd.prs_dienst_key')
          + "     , COALESCE(ms.mld_stdmelding_directklaar, dp.mld_disc_params_directklaar, 0) mld_directklaar"
          + "  FROM mld_stdmelding ms"
          + "     , prs_dienst pd"
          + "     , mld_disc_params dp"
          + " WHERE mld_stdmelding_key = " + stdm_key
          + "   AND pd.prs_dienst_key(+) = ms.prs_dienst_key"
          + "   AND ms.mld_ins_discipline_key = dp.mld_ins_discipline_key";
  var oRs = Oracle.Execute(sql);
  var discipline_key = oRs("mld_ins_discipline_key").Value;
  var vereisdienst = oRs("mld_stdmelding_vereisdienst").Value == 1;
  var eigenprs = oRs("mld_stdmelding_prseigen").Value == 1;
  var prs_dienst_key = oRs("prs_dienst_key").Value;
  var prs_dienst_desc = oRs("prs_dienst_omschrijving").Value; // 'Schoonmaken'
  var autoorder = oRs("mld_stdmelding_autoorder").Value == 1;
  var mld_typeopdr_key = oRs("mld_typeopdr_key").Value;
  var directNaarFO = oRs("mld_directklaar").Value == 2;
  oRs.Close();

  var old_ref_key = -1;
  if (mld_key > 0)
  {
    var sql_m = "SELECT m.mld_melding_kto_key"
              + "     , m.mld_melding_spoed"
              + "  FROM mld_melding m"
              + " WHERE m.mld_melding_key = " + mld_key;
    var oRs_m = Oracle.Execute(sql_m);
    old_ref_key = oRs_m("mld_melding_kto_key").Value;
    var old_prio = oRs_m("mld_melding_spoed").Value;
    oRs_m.Close();
  }

  // Als de setting niet is gezet is "Melding voor" gelijk aan contactpersoon. Invoerveld "Melding voor" was dan ook niet aanwezig.
  // Kolommen prs_perslid_key en prs_perslid_key_voor zijn dan identiek.
  if (S("mld_allow_for_others") == 1)
    prs_key_voor = getFParamInt("personFor", -1);
  else
  {
    prs_key_voor = getFParamInt("person", -1);
  }

  // Als we geen locatiekey hadden dan is hierboven al via afleveradres naar locatiekey gezocht.
  var prs_bedrijf_key = mld.dienst_controle(stdm_key, locatiekey, gebouwkey, ruimtekey, prs_key_voor);

  lcl.set_dialect(stdm_info.ins_srtdiscipline_key, "MLD_SRTDISCIPLINE_KEY");

  var kpkey = getFParamInt("account", -1);
  if (stdm_info.kpnverplicht && kpkey < 0)
  { // Kostenplaats is verplicht, maar is niet meegegeven. Bepaal default kostenplaats.
    kpkey = (user.afdeling().prs_kostenplaats_key() || -1); // User kostenplaats key
    if (kpkey < 0)
      // We kunnen geen default kostenplaats bepalen. We kunnen de melding niet aanmaken.
      // Alert geven en terug.
      shared.simpel_page("Melding niet automatisch aangemaakt omdat kostenplaats niet bepaald kon worden");
  }

  // Deze velden altijd opslaan
  var fields =  [ { dbs: "mld_melding_onderwerp",           typ: "varchar",  frm: "melding_onderwerp",    track: L("lcl_mld_subject"), len: 60 },
                  { dbs: "mld_melding_omschrijving",        typ: "varchar",  frm: "melding_omschrijving", track: L("lcl_mld_inf_Omschrijving"), len: 4000 },
                  { dbs: "mld_kosten_klant",                typ: "check",    frm: "kostenklant"           /* notrack: */ },
                  { dbs: "mld_melding_ordernr",             typ: "varchar",  frm: "ordernr",              track: L("lcl_mld_inf_Ordernr")},
                  { dbs: "prs_perslid_key",                 typ: "key",      frm: "person",               track: L("lcl_mld_name"),             foreign: "prs_perslid" },
                  { dbs: "prs_perslid_key_voor",            typ: "key",      val: prs_key_voor,
                                                                             savewhen: "personFor",       track: L("lcl_mld_call_for"),         foreign: "prs_perslid" },
                  { dbs: "prs_kostenplaats_key",            typ: "key",      val: kpkey,                  track: L("lcl_mld_inf_Kostenplaats"), foreign: "prs_kostenplaats" },
                  { dbs: "mld_melding_opmerking",           typ: "varchar",  frm: "remark",               track: L("lcl_mld_inf_Opmerking"),    len: 4000 },
                  { dbs: "mld_stdmelding_key",              typ: "key",      frm: "stdm",                 track: L("lcl_complain"),             foreign: "mld_stdmelding" },
                  { dbs: "mld_alg_onroerendgoed_keys",      typ: "key",      val: alg_onroerendgoed_keys,
                                                                             savewhen: "locatiekey",
                                                                                                          track: true /* afzonderlijke tracking, wel oldjsval */ },
                  { dbs: "mld_alg_locatie_key",             typ: "key",      val: locatiekey,
                                                                             savewhen: "locatiekey",      track: true /* afzonderlijke tracking, wel oldjsval */ },
                  { dbs: "mld_adres_key",                   typ: "key",      frm: "del_address",          track: L("lcl_delivery_address"),     foreign: "mld_v_afleveradres" },
                  { dbs: "mld_melding_behandelaar_key",     typ: "key",      frm: "sBehandel",            track: true /* afzonderlijke tracking, wel oldjsval */ },
                  { dbs: "mld_melding_indult",              typ: "check0",   frm: "indult",               track: L("lcl_mld_indult") },
                  { dbs: "mld_melding_afgerond",            typ: "check0",   frm: "afgerond",             track: L("lcl_mld_afgerond") }
                ];

  // Checken of een geldige respijt aanwezig was.
  // De eenheid van respijt wordt gelijk genomen aan de eenheid van de stdmelding en is dus altijd readonly.
  // Als respijt niet aanwezig was dan ook eenheid niet opslaan (val wordt altijd opgeslagen, maar frm niet).
  var respijtpresent = Request.Form("respijt").count > 0 && getFParamInt("respijt") > 0;
  if (respijtpresent)
    fields.push({ dbs: "mld_melding_t_respijt.tijdsduur",
                  obj: "MLD_T_UITVOERTIJD",               typ: "number",   frm: "respijt",    track: L("lcl_mld_respijt") },
                { dbs: "mld_melding_t_respijt.eenheid",
                  obj: "MLD_T_UITVOERTIJD",               typ: "varchar",  val: stdm_info.prioriteiten[(prio > 0? prio : old_prio)].eenheid, track: L("lcl_mld_respijt_eenheid") });
  else // Leegmaken
    fields.push({ dbs: "mld_melding_t_respijt.tijdsduur",
                  obj: "MLD_T_UITVOERTIJD",               typ: "number",   val: null,         track: L("lcl_mld_respijt") },
                { dbs: "mld_melding_t_respijt.eenheid",
                  obj: "MLD_T_UITVOERTIJD",               typ: "varchar",  val: null,         track: L("lcl_mld_respijt_eenheid") });

  if (S("mld_melding_flags") > 0)
    fields.push({ dbs: "mld_melding_flag",            typ: "number",   frm: "mldflag" /* notrack */ });

  var rsv_ruimte_key = getFParamInt("rsv_ruimte_key", -1);
  if (rsv_ruimte_key > 0)
    fields.push({ dbs: "res_rsv_ruimte_key",          typ: "key",      frm: "rsv_ruimte_key", track: L("lcl_mld_with_res"), foreign: "res_rsv_ruimte" }); // Alleen bij aanmaken wordt deze eventueel gezet.

  // Er zijn twee situaties te onderscheiden voor startdatum:
  // 1) Als startdatum zichtbaar/wijzigbaar (vakgroep setting "Startdatum te bepalen" (mld_disc_params_startdatum))
  //    De tijd van de startdatum is altijd de begintijd van de dag (setting "fac_t_startofworkday" bijvoorbeeld 8:00 uur)
  //    => Startdatum = TRUNC(startdatum) + 8:00 uur
  //    Uitzondering: Echter als de startdatum de registratiedatum (bij nieuwe melding dus sysdate) is moet wel voor de begintijd de registratietijd (registratiedatum) genomen worden tijdens het opslaan.
  //                  Anders geldt de acceptatietijd (in uren) onterecht al vanaf het begin van de dag.
  // 2) Startdatum is niet zichtbaar/wijzigbaar
  //    De tijd van de startdatum is de tijd van de huidige waarde of van de sysdate, COALESCE(huidige waarde, sysdate).
  //    => Startdatum = COALESCE(huidige waarde, sysdate)

  // Startdatum: indien niet meegegeven, neem dan sysdate
  var startdate = getFParamDate("startdate", new Date);

  var startwerkdag = parseFloat(S("fac_t_startofworkday"));
  var startwerkdag_uur = Math.floor(startwerkdag);
  var startwerkdag_min = (startwerkdag - Math.floor(startwerkdag)) * 60;
  var startdatebegin = new Date(startdate.getFullYear(), startdate.getMonth(), startdate.getDate(), startwerkdag_uur, startwerkdag_min);
  var sysdate = new Date();

  if (stdm_info.startdatum)
  { // Situatie 1: Einddatum = TRUNC(startdatum) + 8:00 uur + SLA
    // LET OP!!!: Als setting "mld_disc_params_startdatum" is gezet dan wordt eigenlijk verondersteld dat de SLA in dagen is en niet in uren.
    //            Echter als de startdatum de registratiedatum (bij nieuwe melding dus sysdate) is moet wel voor de begintijd de registratietijd (registratiedatum) genomen worden tijdens het opslaan.
    //            Anders geldt de acceptatietijd (in uren) onterecht al vanaf het begin van de dag.
    if (mld_key < 0)
    { // Nieuwe melding.
      // Startdatum is vandaag: starttijd is huidige tijd.
      // Startdatum is niet vandaag: starttijd is begin werkdag.
      var startdate_is_today = (startdate.midnight().getTime() == sysdate.midnight().getTime());
      startdate = (startdate_is_today? sysdate : startdatebegin);
    }
    else
    { // Bestaande melding
      sql = "SELECT mld_melding_datum"
          + "  FROM mld_melding"
          + " WHERE mld_melding_key = " + mld_key;
      oRs = Oracle.Execute(sql);
      var oldstartdate = new Date(oRs("mld_melding_datum").Value);

      // Alleen als datum veranderd is moet de starttijd worden aangepast.
      if (startdate.midnight().getTime() != oldstartdate.midnight().getTime())
      { // Startdatum is aangepast.
        // Als de startdatum is aangepast in registratiedatum, dan wel weer de registratietijd (registratiedatum) pakken.
        // In alle andere gevallen begin van de werkdag pakken.
        sql = "SELECT fac.gettrackingdate('MLDNEW', " + mld_key + ") registratiedatum FROM DUAL"
        oRs_1 = Oracle.Execute(sql);
        var registratiedatum = new Date(oRs_1("registratiedatum").Value);
        oRs_1.Close();

        var startdatum_is_registratiedatum = (startdate.midnight().getTime() == registratiedatum.midnight().getTime());
        startdate = (startdatum_is_registratiedatum? registratiedatum : startdatebegin);
      }
      else
      { // else startdatum niet aanpassen.
        startdate = oldstartdate;
      }
      oRs.Close();
    }
    fields.push({ dbs: "mld_melding_datum", typ: "datetime", val: startdate, track: L("lcl_mld_startdate") }); // Begin werkdag
  }
  else
  { // Situatie 2: Einddatum = COALESCE(huidige waarde, sysdate) + SLA
    if (mld_key < 0)
    {
      fields.push({ dbs: "mld_melding_datum", typ: "sql", val: "SYSDATE" }); // Nieuwe melding, nu/sysdate
      startdate = new Date();
    }
    else
    {
      fields.push({ dbs: "mld_melding_datum", typ: "datetime", frm: "startdate", track: L("lcl_mld_startdate") }); // Wijziging melding, huidige opgeslagen waarde
    }
  }

  // enddate_std wordt m.b.v. trigger en database functie mld.geteinddatum(startdate, stdm_key, prio, geb_key) berekend.
  // mld_melding_acceptdatum_std wordt ook in de trigger bepaald

  // De einddatum is de meegegeven einddatum (zoals mogelijk bepaald en aangepast), maar als die niet wordt meegegeven is het
  // gewoon enddate_std en dat regelt de trigger wel, dus DAN MOET IK HEM NIET MEEGEVEN
  // De tijd van de einddatum wordt nu altijd opgeslagen onafhankelijk of de tijd getoond wordt.
  if (Request.Form("enddate").count > 0)
    fields.push({ dbs: "mld_melding_einddatum", typ: "datetime", frm: "enddate", track: L("lcl_mld_enddate") });

  if (!isNew)
  { // Update an existing mld_melding record

    if (stdm_info.kanverwijzen)
    {
        var ref_key = getFParamInt("ref_key", -1);
        if (!stdm_info.is_kto_antwoord && stdm_info.kanverwijzen == 128 && ref_key != old_ref_key)
        {
            if (!validReferenceKey(mld_key, ref_key))
                abort_with_warning(L("lcl_mld_invalid_reference"));
        }

        function ref_foreign (pval, oldjsvals) // bij oldval krijgen we oldjsvals tot nu toe mee
        {
            if (!pval)
                return "";
            var ref_type = oldjsvals?oldjsvals.mld_melding_kto_type:getFParam("ref_type");
            return mld.referentielabel(ref_type, pval);
        }
        fields.push({ dbs: "mld_melding_kto_type",    typ: "varchar",  frm: "ref_type", track: true /* afzonderlijke tracking, wel oldjsval */ });
        fields.push({ dbs: "mld_melding_kto_key",     typ: "key",      val: ref_key, track: L("lcl_reference"), foreign: ref_foreign });
    }
    fields.push({ dbs: "mld_melding_kto",         typ: "check",    frm: "ktoself",              track: L("lcl_mld_kto_invite") });

    // Hardness controle schrijfrechten
    var this_mld = mld.func_enabled_melding(mld_key); // Wat heb ik zoal aan rechten op deze specifieke melding
    user.auth_required_or_abort(this_mld.canChange);

    // Controleer soms of er geen lopende opdrachten zijn die buiten de (gewijzigde) meldingsperiode vallen
    if (S("mld_enforce_orderdates") == 1)
    { // Einddatum: indien niet meegegeven, neem dan sysdate.
      var enddate = getFParamDate("enddate", new Date);

      sql = "SELECT COUNT (*) aantal FROM mld_opdr"
          + " WHERE mld_statusopdr_key IN (3, 4, 5, 8)"
          + (stdm_info.startdatum == 1
            ? " AND (TRUNC(mld_opdr_datumbegin) < " + startdate.beginToSQL()
              + "    OR TRUNC(mld_opdr_einddatum) >" + enddate.beginToSQL()+")"
            : " AND TRUNC(mld_opdr_einddatum) > " + enddate.beginToSQL())
          + " AND mld_melding_key = " + mld_key;
      oRs = Oracle.Execute(sql);
      if (oRs("aantal") > 0)
          abort_with_warning(L("lcl_mld_meldingbuitenopdracht"));
      oRs.Close();
    }

    fields.push({ dbs: "mld_melding_spoed",  typ: "key",      frm: "prio",      track: L("lcl_mld_urg"), foreign: mld.getpriotext });

    /* mldUpd heeft na afloop handige oldjsvals */
    var mldUpd = buildTrackingUpdate("mld_melding", " mld_melding_key = " + mld_key, fields);

    /* SUBMIT THE CHANGED DATA */
    var err = Oracle.Execute(mldUpd.sql, true);
    if (err.friendlyMsg)
      abort_with_warning(err.friendlyMsg);

    /* SET STATUS AND SUBMIT ADDITIONAL TRACKING */
    if (sBehandel != -2 && (mldUpd.oldjsvals["mld_melding_behandelaar_key"] || -1) != (sBehandel || -1))
    { // Anders is-ie niet meegegeven of niet veranderd
      mld.trackbehandelaar(mld_key, sBehandel);
    }

    if (S("mld_rejected_is_open") && mldUpd.oldjsvals["mld_melding_status"] == 1) {
      // Aanpassen van een afgewezen melding werpt die weer opnieuw de molen in.
      mld.setmeldingstatus(mld_key, 2);
    }

    // tracking plaats is ingewikkelder (twee keys maar slechts één track gewenst), die doen we handmatig
    // alg_onroerendgoed_keys en locatiekey bevatten reeds de nieuwe waardes
    if (stdm_info.ins_srtdiscipline_alg && hasFParam("locatiekey")) // dan kan de plaats gewijzigd zijn
    {
      if (alg_onroerendgoed_keys > 0)
        newsql = "SELECT alg_plaatsaanduiding FROM alg_v_plaatsaanduiding_all WHERE alg_onroerendgoed_keys = " + alg_onroerendgoed_keys;
      else
        newsql = "SELECT alg_locatie_code FROM alg_locatie WHERE alg_locatie_key = " + locatiekey;
      var og_key = mldUpd.oldjsvals["mld_alg_onroerendgoed_keys"];
      var loc_key = mldUpd.oldjsvals["mld_alg_locatie_key"];
      if (og_key>0)
        oldsql = "SELECT alg_plaatsaanduiding FROM alg_v_plaatsaanduiding_all WHERE alg_onroerendgoed_keys = " + og_key;
      else if (loc_key > 0)
        oldsql = "SELECT alg_locatie_code FROM alg_locatie WHERE alg_locatie_key = " + loc_key;
      else
        oldsql = "SELECT '' FROM DUAL";
      var oldtxt = Oracle.Execute(oldsql)(0).Value;
      var newtxt = Oracle.Execute(newsql)(0).Value;
      if (oldtxt != newtxt)
        mldUpd.trackarray.push(L("lcl_plaatsgegevens") + ": " + buildTrackText("varchar", oldtxt, newtxt, { nodiff: true }));
    }

    // tracking doen we gelijk met de flexkenmerken

    mld.keepFlexDocuments(mld_key, mldUpd.oldjsvals["mld_stdmelding_key"], stdm_key);
  }
  else
  { // A new mld_melding record

    // We hebben de melding en dus de discipline. Autorisatie controle kan al redelijk scherp
    var this_mld = mld.func_enabled_mld(stdm_info.ins_discipline_key, "D");
    user.auth_required_or_abort(this_mld.canFEwrite || this_mld.canFOwrite);

    if (stdm_info.is_kto_antwoord || stdm_info.kanverwijzen == 0)
      var ref_key = getFParamInt("kto_key", null);
    else
      var ref_key = getFParamInt("ref_key", -1);

    if (!stdm_info.is_kto_antwoord && stdm_info.kanverwijzen==128 && !validReferenceKey(-1, ref_key) )
        abort_with_warning(L("lcl_mld_invalid_reference"));
    fields = fields.concat(
                    [ { dbs: "mld_melding_key",         typ: "key",      seq: "mld_s_mld_melding_key" },
                      { dbs: "mld_meldbron_key",        typ: "key",      val: meldbron_key },
                      { dbs: "mld_melding_start_key",   typ: "key",      frm: "start_key" },
                      { dbs: "mld_melding_module",      typ: "varchar",  val: "MLD" },
                      { dbs: "mld_melding_spoed",       typ: "key",      val: (prio > 0? prio : 3) }, // default (frontend) 3
                      { dbs: "fac_activiteit_key",      typ: "key",      frm: "fac_activiteit_key" },
                      { dbs: "mld_melding_kto_type",    typ: "varchar",  frm: (stdm_info.is_kto_antwoord || stdm_info.kanverwijzen == 0)? "kto_type" : "ref_type" },
                      { dbs: "mld_melding_kto_key",     typ: "key",      val: ref_key },
                      { dbs: "mld_melding_kto",         typ: "number",   val: (stdm_info.stdmelding_kto & 1)? 1 : 0 }
                    ]);

    var mldIns = buildInsert("mld_melding", fields);
    var mld_key = mldIns.sequences["mld_melding_key"];

    var err = Oracle.Execute(mldIns.sql, true);
    if (err.friendlyMsg)
      abort_with_warning(err.friendlyMsg);

    if (parent_key > 0)
    {
        mld.link_child_to_parent(mld_key, parent_key);
    }
    else
    {   // Zetten van de status op ingevoerd en afhandelen van de tracking.
        mld.setmeldingstatus(mld_key, (directNaarFO? 0 : 2)); // Zorgt ook voor tracking & daarmee notificatie
    }

    if (stdm_info.is_kto_antwoord) // die direct afmelden
      mld.setmeldingstatus(mld_key, 5);
  }

  if (getFParamInt("has_r_objs", 0) == 1) // voorkom dat we wissen vanuit mobile-save die helemaal geen listbox heeft
  { // Objecten verwijderen of toevoegen.
    var objtrack = mld.saveobjects(mld_key, obj_arr);
    // Tracken van de objectwijzigingen.
    if (!isNew && objtrack != "")
      mldUpd.trackarray.push(objtrack);
  }

  // Eventuele (gewijzigde) objecten zijn nu ook opgeslagen.
  // Nu kan de definitieve mld_melding.mld_melding_einddatum_std en mld_melding.mld_melding_t_uitvoertijd bepaald en gezet worden.
  mld.finishmeldingiu(mld_key);

  // Sql met de huidige kenmerken rekening houdend met de juiste vakgroep en melding.
  // Ander kenmerken worden door de functie saveFlexKenmerken verwijderd (FSN#18613)
  currentKenmerkenSQL = "SELECT vk.mld_kenmerk_key"
                      + "     , mld_kenmerkmelding_waarde"
                      + "  FROM mld_kenmerkmelding km"
                      + "     , mld_kenmerk vk"
                      + "     , mld_melding m"
                      + "     , mld_stdmelding s"
                      + "     , mld_discipline d"
                      + " WHERE km.mld_kenmerk_key = vk.mld_kenmerk_key"
                      + "   AND km.mld_kenmerkmelding_verwijder IS NULL"
                      + "   AND km.mld_melding_key = m.mld_melding_key"
                      + "   AND m.mld_melding_key = " + mld_key
                      + "   AND s.mld_stdmelding_key = m.mld_stdmelding_key"
                      + "   AND s.mld_ins_discipline_key = d.ins_discipline_key"
                      + "   AND ((vk.mld_stdmelding_key = s.mld_stdmelding_key     AND vk.mld_kenmerk_niveau = 'S')"
                      + "     OR (vk.mld_stdmelding_key = s.mld_ins_discipline_key AND vk.mld_kenmerk_niveau = 'D')"
                      + "     OR (vk.mld_stdmelding_key = d.ins_srtdiscipline_key  AND vk.mld_kenmerk_niveau = 'T'))";

  allKenmerkenSQL     = "SELECT "+lcl.xsql('t.mld_srtkenmerk_omschrijving', 't.mld_srtkenmerk_key') +" kenmerk_omschrijving"
                      + ",      m.mld_srtkenmerk_key srtkenmerk_key"
                      + ",      fac_kenmerkdomein_key"
                      + "  FROM mld_kenmerk m, "
                      + "       mld_srtkenmerk t"
                      + " WHERE m.mld_srtkenmerk_key = t.mld_srtkenmerk_key"
                      + "   AND m.mld_kenmerk_key = "; /* wordt in saveFlexkenmerken uitgebreid */

  var flextrack =
      saveFlexKenmerken(mld_key, { kenmerkTable: "mld_kenmerkmelding",
                                   kenmerkParentKey : "mld_melding_key",
                                   kenmerkWaarde: "mld_kenmerkmelding_waarde",
                                   kenmerkKey: "mld_kenmerk_key",
                                   currentKenmerkenSQL: currentKenmerkenSQL,
                                   allKenmerkenSQL: allKenmerkenSQL,
                                   requestQF: Request.Form,
                                   isNew: isNew, flexPath: "MLD/M",
                                   tracking: true,
                                   module: "MLD"
                              });

  var doneParams = { mld_key : mld_key, autoprint: false, warning: "", autoorder: autoorder, success: true };

  var sjabl_opdr_key = -1;
  if (!isNew)
  {
    if (mldUpd.trackarray.length || flextrack.length)
    { // NB: de eerste regel wordt ook als notificatie (ipv automatisch fac_srtnotificatie_oms[MLDUPD]) gebruikt,
      // Vandaar hier bij uitzondering ook het meldingsnummer en stdmelding_omschrijving vermelden
      // Is quickfix voor AANS#20804

      var formattedID = stdm_info.ins_srtdiscipline_prefix+mld_key + " ("+ stdm_info.discipline_omschrijving + "/"+ stdm_info.stdmelding_omschrijving +")";
      mld.trackmeldingupdate(mld_key, L("lcl_mld_is_mldupdtrack").format(formattedID) + "\n" + mldUpd.trackarray.concat(flextrack).join("\n"));
    }

    // Voeg extra tracking toe als melding afgerond is.
    if (newvalafgerond == 1 && !mldUpd.oldjsvals["mld_melding_afgerond"])
      mld.trackmeldingafronden(mld_key, L("lcl_mld_is_mldafrtrack").format(formattedID));
  }
  else if (parent_key < 0)  // isNew, Doe wat speciale dingen voor nieuwe opdrachten (sjabloon of autoorder)
  {
    mld.nextworkflowstep(mld_key, -1);  // -1 = initial (the originating call)

    // Als er een activiteit is gevonden met een sjabloon opdracht (sjabl_opdr_key > 0)
    // dan moet er een nieuwe opdracht onder water aangemaakt worden met het sjabloon als voorbeeld
    sql = "SELECT mo.mld_opdr_key"
        + "  FROM mld_disc_params dp, fac_activiteit fa, mld_opdr mo"
        + " WHERE dp.fac_activiteit_key = fa.fac_activiteit_key"
        + "   AND fa.fac_activiteit_xmlnode = 'opdracht'"
        + "   AND mo.fac_activiteit_key = fa.fac_activiteit_key"
        + "   AND dp.mld_ins_discipline_key = " + discipline_key;
    oRs = Oracle.Execute(sql);
    if (!oRs.Eof)
      sjabl_opdr_key = oRs("mld_opdr_key").Value;
    oRs.Close();
    if (sjabl_opdr_key > 0)
    {
      // Eerst de melding op gaccepteerd zetten dan opdracht aanmaken
      /* FSN#15158/PF 13-2-2009 15:00:24*/
      // Zetten van de status op geaccepteerd en afhandelen van de tracking.
      mld.setmeldingstatus(mld_key, 4);

      var sql = "SELECT mld_s_mld_opdr_key.nextval FROM DUAL";

      oRs = Oracle.Execute(sql);
      new_opdr = oRs(0).Value;
      oRs.Close();

      sql = "INSERT INTO mld_opdr ("
          + "mld_opdr_key"
          + ", mld_opdr_module"
          + ", mld_melding_key"
          + ", mld_uitvoerende_keys"
          + ", mld_typeopdr_key"
          + ", mld_statusopdr_key"
          + ", mld_standaardopdr_key"
          + ", mld_opdr_omschrijving"
          + ", mld_opdr_datumbegin"
          + ", mld_opdr_einddatum"
          + ", mld_opdr_werkzaamheden"
          + ", mld_opdr_uren"
          + ", mld_opdr_materiaal"
          + ", mld_opdr_kosten"
          + ", mld_opdr_contactpersoon"
          + ", mld_opdr_geprint"
          + ", mld_opdr_bedrijfopdr_volgnr"
          + ", mld_opdr_uurloon"
          + ", prs_perslid_key"
          + ", prs_contactpersoon_key"
          + ", cnt_contract_key"
          + ", cnt_contract_dienst_key"
          + ", prs_kostenplaats_key"
          + ", mld_opdr_opmerking_fiat"
          + ", mld_opdr_ordernr"
          + ", mld_opdr_teverzenden"
          + ", mld_opdr_opmerking)"
          + " SELECT"
          + " " + new_opdr
          + ", mld_opdr_module"
          + ", " + mld_key
          + ", mld_uitvoerende_keys"
          + ", mld_typeopdr_key"
          + ", mld_statusopdr_key"
          + ", mld_standaardopdr_key"
          + ", mld_opdr_omschrijving"
          + ", mld_opdr_datumbegin"
          + ", mld_opdr_einddatum"
          + ", mld_opdr_werkzaamheden"
          + ", mld_opdr_uren"
          + ", mld_opdr_materiaal"
          + ", mld_opdr_kosten"
          + ", mld_opdr_contactpersoon"
          + ", mld_opdr_geprint"
          + ", mld_opdr_bedrijfopdr_volgnr"
          + ", mld_opdr_uurloon"
          + ", prs_perslid_key"
          + ", prs_contactpersoon_key"
          + ", cnt_contract_key"
          + ", cnt_contract_dienst_key"
          + ", prs_kostenplaats_key"
          + ", mld_opdr_opmerking_fiat"
          + ", mld_opdr_ordernr"
          + ", mld_opdr_teverzenden"
          + ", mld_opdr_opmerking"
          + " FROM mld_opdr o"
          + " WHERE o.mld_opdr_key = " + sjabl_opdr_key;

      Oracle.Execute(sql);

      // Kopiëren flexkenmerken
      // De regels in de tabel mld_kenmerkopdr kopiëren
      sql = "INSERT INTO mld_kenmerkopdr ("
          + " mld_opdr_key"
          + ", mld_kenmerk_key"
          + ", mld_kenmerkopdr_waarde)"
          + " SELECT " + new_opdr
          + ", mld_kenmerk_key"
          + ", mld_kenmerkopdr_waarde"
          + " FROM mld_kenmerkopdr"
          + " WHERE mld_opdr_key = " + sjabl_opdr_key;
      Oracle.Execute(sql);

      // Copy de flex folders: CopyFlexFolders(oldbasepath, newbasepath, flexsql)
      // typeopdr and mld_kenmerk_key is for both orders, old (sjabloon) and new, the same

      var flexsql = "SELECT k_old.mld_kenmerk_key k_old"
                  + ", k_old.mld_kenmerk_key k_new"
                  + " FROM mld_srtkenmerk t"
                  + ", mld_kenmerk k_old"
                  + ", mld_opdr o_old"
                  + " WHERE o_old.mld_opdr_key = " + sjabl_opdr_key
                  + " AND t.mld_srtkenmerk_kenmerktype IN ('F', 'E', 'M') "
                  + " AND k_old.mld_typeopdr_key = o_old.mld_typeopdr_key "
                  + " AND k_old.mld_kenmerk_niveau = 'O' "
                  + " AND k_old.mld_kenmerk_verwijder IS NULL "
                  + " AND k_old.mld_srtkenmerk_key = t.mld_srtkenmerk_key "
                  + " AND t.mld_srtkenmerk_verwijder IS NULL";
      CopyFlexFolders("MLD/" + subfolderKey("O", sjabl_opdr_key), "MLD/" + subfolderKey("O", new_opdr), flexsql);
    }
  }

  if (!frontend && (S("mld_melding_autoprint") == 2 || (isNew && sjabl_opdr_key < 0 && S("mld_melding_autoprint") == 1)))
  { // S("mld_melding_autoprint"): 2-altijd, 1-aleen als er geen orders zijn.
    doneParams.autoprint = true;
  }

  // Klantspecifieke check functie (hookfunction) voor de invoer
  var pResult = new HookResult();
  if (!custfunc.mld_postsave(mld_key, pResult))
  {
    abort_with_warning(pResult.errmsg);
  }
}
else
{ // Eerst extra signaleringsvraag stellen daarna pas gegevens opslaan
  var doneParams = { doublecheck: true,
                     urole: urole,
                     stdm_key: stdm_key,
                     ruimtekey: ruimtekey,
                     verdiepingkey: verdiepingkey,
                     gebouwkey: gebouwkey,
                     locatiekey: locatiekey,
                     obj_arr: obj_arr }
}

mld.unlock(mld_key);

Response.Write(JSON.stringify(doneParams));
Response.End;
%>
