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

     File:          opdr_close_save.asp
     Description:   Het echte sluiten van een opdracht, zonder interactie
     Parameters:
         opdr_key   Opdracht key van de opdracht die moet worden afgemeld
     Context:
     Note:          A Rechtstreeks vanuit opdr_close_confirm.asp
                    B in multi-mode wordt dit aangeroepen via $.post en doen we geen interactie
                              er wordt dan ook geen opmerking gevraagd
                    C Vanuit Pda/order.asp

*/
var JSON_Result = true;
var opdr_key_arr = getQParamIntArray("opdr_key");
if (opdr_key_arr.length)
    var LOCKED_USER_OK = { "xmlnode": "opdracht", "key": opdr_key_arr[0] };
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../Shared/kenmerk_common.inc" -->
<!-- #include file="mld.inc" -->
<%

function mldClose(sluitmelding, ingesloten)
{
  if (sluitmelding == 1)
  {
    var mld_close = (Request.Form("mld_close").count == 1); // Die ook?

    if (ingesloten.length > 1) // Vraag is al geweest
    {
      if (mld_close)
        sluitmelding = 2; // yepe
      else
        sluitmelding = 0; // nope
    }
  }
  return sluitmelding;
}

function writeOpdrOpmToMld()
{ // Afhandelingtekst van de opdracht automatisch kopiëren naar de melding.
  var sql = "SELECT mld_melding_opmerking"
          + "  FROM mld_melding"
          + " WHERE mld_melding_key = " + mld_opdr.mld_key;
  var oRs = Oracle.Execute(sql);
  var new_opm = (oRs("mld_melding_opmerking").Value || "") + "\n" + L("lcl_mld_final_remark") + ":\n" + opdr_opm;
  var fields =  [ { dbs: "mld_melding_opmerking",  typ: "varchar", val: new_opm, track: L("lcl_mld_inf_Opmerking"), len: 4000 } ];
  var mldUpd = buildTrackingUpdate("mld_melding", " mld_melding_key = " + mld_opdr.mld_key, fields);
  oRs = Oracle.Execute(mldUpd.sql);
  if (mldUpd.trackarray.length)
    mld.trackmeldingupdate(mld_opdr.mld_key, L("lcl_mld_is_mldupd") + "\n" + mldUpd.trackarray.join("\n"));
}

var mld_hlt = (Request.Form("mld_hlt").count == 1);
var result = {};
var ingesloten = [];
var reqStatusEmptyMelding = [];
var reqStatusEmptyOpdr = [];

if (opdr_key_arr.length == 1)
{
  var this_opdr = mld.func_enabled_opdracht(opdr_key_arr[0]); // wat mag ik zoal op deze opdracht
  var mld_opdr = this_opdr.mld_opdr;
  var kosten_verplicht_afm = mld_opdr.tonen_totaal && (mld_opdr.typeopdr_kosten_verplicht & 2 || (mld_opdr.typeopdr_kosten_verplicht == 0 && mld_opdr.opdrkosten_verplicht & 2));
  var opdr_kosten = mld_opdr.t_cost;

  // save mandatory characteristics before check on empty mandatory characteristics
  var currentKenmerkenSQL = "SELECT k.mld_kenmerk_key"
                          + "     , mld_kenmerkopdr_waarde"
                          + "     , k.mld_kenmerk_toonbaar"
                          + "     , k.fac_functie_key"
                          + "  FROM mld_kenmerkopdr ko"
                          + "     , mld_kenmerk k"
                          + " WHERE k.mld_kenmerk_key = ko.mld_kenmerk_key"
                          + "   AND mld_kenmerkopdr_verwijder IS NULL"
                          + "   AND mld_opdr_key = " + opdr_key_arr[0];

  var allKenmerkenSQL = "SELECT COALESCE (" + lcl.xsql("k.mld_kenmerk_omschrijving", "k.mld_kenmerk_key")
                      + "              ,  " + lcl.xsql("t.mld_srtkenmerk_omschrijving", "t.mld_srtkenmerk_key") + ") kenmerk_omschrijving"
                      + "     , t.mld_srtkenmerk_kenmerktype kenmerk_kenmerktype"
                      + "     , t.mld_srtkenmerk_systeem     kenmerk_systeem"
                      + "     , k.mld_kenmerk_toonbaar       kenmerk_readonly"
                      + "     , k.mld_kenmerk_uniek          kenmerk_uniek"
                      + "     , fac_kenmerkdomein_key"
                      + "  FROM mld_kenmerk k"
                      + "     , mld_srtkenmerk t"
                      + " WHERE k.mld_srtkenmerk_key = t.mld_srtkenmerk_key"
                      + "   AND k.mld_kenmerk_key = "; /* wordt in saveFlexkenmerken uitgebreid */

  var flextrack =
      saveFlexKenmerken(opdr_key_arr[0], { kenmerkTable: "mld_kenmerkopdr",
                                    kenmerkParentKey : "mld_opdr_key",
                                    kenmerkWaarde: "mld_kenmerkopdr_waarde",
                                    kenmerkKey: "mld_kenmerk_key",
                                    kenmerkToonbaar: "mld_kenmerk_toonbaar",
                                    nameprefix: getFParam("nameprefix", ""),
                                    extraserie: hasFParam("nameprefix"),
                                    currentKenmerkenSQL: currentKenmerkenSQL,
                                    allKenmerkenSQL: allKenmerkenSQL,
                                    requestQF: Request.Form,
                                    isNew: false,
                                    flexPath: "MLD/O",
                                    tracking: true,
                                    module: "MLD"
                                  }
                       );

  // Wijzigingen flexkenmerken tracken.
  if (flextrack.length)
  {
    var ins_srtdiscipline_prefix = mld.mld_prefix(mld_opdr.mld_key);
    var formattedID = ins_srtdiscipline_prefix + mld_opdr.mld_key + "/" + mld_opdr.volgnr;
    mld.trackopdrachtupdate(opdr_key_arr[0], L("lcl_ord_is_ordupdtrack").format(formattedID) + "\n" + flextrack.join("\n"));
  }

  // Zijn bij deze opdracht alle verplichte kenmerken ingevuld?
  reqStatusEmptyOpdr = mld.getActieKenmerkenOpdr(reqStatusEmptyOpdr, opdr_key_arr[0], {status: 6}); // Opdracht status "Technisch Voltooid(6)"

  user.auth_required_or_abort(!(kosten_verplicht_afm && opdr_kosten == null) && this_opdr.canClose, L("lcl_mld_opdr_kosten_verpl_afm")); // Dan zijn we vlug klaar.
  user.auth_required_or_abort(!reqStatusEmptyOpdr.length, reqStatusEmptyOpdr.join("<br>")); // Dan zijn we vlug klaar.

  var sql = "SELECT o.mld_melding_key"
          + "     , o.mld_opdr_einddatum"
          + "     , mto.mld_typeopdr_sluitmelding"
          + "  FROM mld_opdr o"
          + "     , mld_typeopdr mto"
          + " WHERE o.mld_typeopdr_key = mto.mld_typeopdr_key"
          + "   AND o.mld_opdr_key = " + opdr_key_arr[0];
  var oRs = Oracle.Execute(sql);
  var mld_key = oRs("mld_melding_key").Value;
  var mld_opdr_einddatum = oRs("mld_opdr_einddatum").Value != null? new Date(oRs("mld_opdr_einddatum").value) : null;
  var typeopdr_sluitmelding = oRs("mld_typeopdr_sluitmelding").Value;
  oRs.Close();

  // Hoeveel opdrachten staan er open bij deze melding.
  var sql = "SELECT COUNT(mld_opdr_key) nrOpen"
          + "  FROM mld_opdr o"
          + " WHERE o.mld_melding_key = " + mld_key
          + "   AND o.mld_statusopdr_key NOT IN (1, 6, 7, 9)";
  var oRs = Oracle.Execute(sql);
  var nrOpen = oRs("nrOpen").Value;
  oRs.Close();

  ingesloten.push(opdr_key_arr[0]);
  var sluitmelding = mldClose(typeopdr_sluitmelding, ingesloten);

  if (nrOpen == 1 && sluitmelding)
  {
    // Zijn bij de melding van deze opdracht alle verplichte kenmerken en/of verplicht object ingevuld?
    // Alleen te controleren als melding na afsluiten van de opdracht ook gesloten wordt.
    var this_mld = mld.func_enabled_melding(mld_key);  // Wat heb ik zoal aan rechten op deze specifieke melding.
    if (this_mld.canClose)
      reqStatusEmptyMelding = mld.getReqStatusEmptyMelding(reqStatusEmptyMelding, mld_key, 5); // Melding status "Afgemeld(5)"
  }
  user.anything_todo_or_abort(!reqStatusEmptyMelding.length, reqStatusEmptyMelding.join("<br />"));
  // Als Setting S("mld_ord_afmeld_future") niet is gezet: Opdrachten waarvan de einddatum in de toekomst ligt mogen niet worden afgemeld.
  user.auth_required_or_abort((S("mld_ord_afmeld_future") == 1 || mld_opdr_einddatum == null || (mld_opdr_einddatum && mld_opdr_einddatum < new Date())) && this_opdr.canClose, L("lcl_mld_einddatum_to_late_opdr"));
}
else
{
  // Bepaal de opdrachten in de selectie die
  // ook echt afgemeld kunnen of mogen worden.
  for (var i = 0; i < opdr_key_arr.length; i++)
  {
    var this_opdr = mld.func_enabled_opdracht(opdr_key_arr[i]); // wat mag ik zoal op deze opdracht
    var mld_opdr = this_opdr.mld_opdr;
    var sql = "SELECT mld_opdr_einddatum"
            + "  FROM mld_opdr o"
            + " WHERE o.mld_opdr_key = " + opdr_key_arr[i];
    var oRs = Oracle.Execute(sql);

    var mld_opdr_einddatum = oRs("mld_opdr_einddatum").Value != null? new Date(oRs("mld_opdr_einddatum").Value) : null;
    var kosten_verplicht_afm = mld_opdr.tonen_totaal && (mld_opdr.typeopdr_kosten_verplicht & 2 || (mld_opdr.typeopdr_kosten_verplicht == 0 && mld_opdr.opdrkosten_verplicht & 2));
    var opdr_kosten = mld_opdr.t_cost;

    // Zijn bij deze opdracht alle verplichte kenmerken ingevuld?
    reqStatusEmptyOpdr = mld.getActieKenmerkenOpdr(reqStatusEmptyOpdr, opdr_key_arr[i], {status: 6}); // Opdracht status "Technisch Voltooid(6)"

    // Als Setting S("mld_ord_afmeld_future") niet is gezet (0): Opdrachten waarvan de einddatum in de toekomst ligt mogen niet worden afgemeld.
    if ((S("mld_ord_afmeld_future") == 1 || mld_opdr_einddatum == null || (mld_opdr_einddatum && mld_opdr_einddatum < new Date())) &&
        this_opdr.canClose &&
        !(kosten_verplicht_afm && opdr_kosten == 0) &&
        !reqStatusEmptyOpdr.length)
    {
      ingesloten.push(opdr_key_arr[i]);
    }
    oRs.Close();
    // Mbv mld_close en mld_typeopdr_sluitmelding weet ik of de melding ook moet worden gesloten na de laatste opdracht,
    // maar op dit punt is nog niet met zekerheid vast te stellen of dit ook de laatste opdracht is.
    // Het heeft dus geen zin om hier te controleren of alle verplichte kenmerken bij de melding zijn ingevuld.
  }
}
user.anything_todo_or_abort(ingesloten.length > 0); // We klagen niet over enkele wel en enkele niet
var result = { opdr_key: ingesloten.join(","), message: "", success: false, canCloseMld: false };

for (var i = 0; i < ingesloten.length; i++)
{
  var mld_opdr = mld.mld_opdr_info(ingesloten[i]);
  lcl.set_dialect(mld_opdr.opdr_type, "MLD_TYPEOPDR_KEY");

  var this_opdr = mld.func_enabled_opdracht(ingesloten[i]); // wat mag ik zoal op deze opdracht
  if (this_opdr.canOpmChange)
  {
    var opdr_opm = getFParam("opdr_opm", "");
    result.opdr_opm = opdr_opm;
    if (ingesloten.length > 1) // Bulk
    {
      var sql = "SELECT mld_opdr_opmerking"
              + "  FROM mld_opdr o"
              + " WHERE o.mld_opdr_key = " + ingesloten[i];
      oRs = Oracle.Execute(sql);
      var opm = (oRs("mld_opdr_opmerking").Value? oRs("mld_opdr_opmerking").Value + "\n":"") + opdr_opm;
      oRs.Close();
    }
    else
      var opm = opdr_opm;
    var fields = [ { dbs: "mld_opdr_opmerking",     typ: "varchar", val: opm,      track: L("lcl_mld_inf_Opmerking") } ];

    // Als de behandelaar leeg is en een user van het INTERNE bedrijf meldt de opdracht af, dan de user_key als behandelaar (prs_perslid_key) zetten.
    if (mld_opdr.uitv_type == 'B' && mld_opdr.uitv_intern && mld_opdr.contactpers_key == -1)
      fields.push({ dbs: "prs_perslid_key",         typ: "key",     val: user_key, track: L("lcl_mld_behandelaar"),     foreign: "prs_perslid" });
    else if (mld_opdr.uitv_type == 'B' && !mld_opdr.uitv_intern && mld_opdr.contactpersuitv_key == null)
    { // Is de user een extern contactpersoon van het uitvoerende externe bedrijf? Dan deze invullen als contactpersoon.
      var sql = "SELECT prs_contactpersoon_key"
              + "  FROM prs_contactpersoon"
              + " WHERE prs_contactpersoon_verwijder IS NULL"
              + "   AND prs_bedrijf_key = " + mld_opdr.uitvoerende_key
              + "   AND prs_perslid_key = " + user_key;
      var oRs = Oracle.Execute(sql);
      if (!oRs.eof)
        // User is contactpersoon van het uitvoerende externe bedrijf.
        fields.push({ dbs: "prs_contactpersoon_key", typ: "key", val: oRs("prs_contactpersoon_key").Value, track: L("lcl_contact_pers"), foreign: "prs_contactpersoon" });
      oRs.Close();
    }

    var mldUpd = buildTrackingUpdate("mld_opdr", "mld_opdr_key = " + ingesloten[i], fields);
  }

  var def_date = new Date();
  var afmelddatum = getFParamDate("date_from", def_date);
  var orgdate = getFParamDate("orgdate", def_date);

  var formattedID = "";
  if ((mldUpd && mldUpd.trackarray.length) ||
      ((mld_opdr.typeopdr_afmeldmarge > 0 && ingesloten.length == 1) && (afmelddatum.getTime() != orgdate.getTime())))
  {
    var ins_srtdiscipline_prefix = mld.mld_prefix(mld_opdr.mld_key);
    formattedID = ins_srtdiscipline_prefix + mld_opdr.mld_key + "/" + mld_opdr.volgnr;
  }

  if (mldUpd && mldUpd.trackarray.length)
  {
    Oracle.Execute(mldUpd.sql);
    mld.trackopdrachtupdate(ingesloten[i], L("lcl_ord_is_ordupdtrack").format(formattedID) + "\n" + mldUpd.trackarray.join("\n"));
  }

  // Zetten van de status en afhandelen van de tracking van het afmelden (close).
  mld.setopdrachtstatus(ingesloten[i], 6); // Technisch voltooid (TV) (Afgemeld)
  if (mld_opdr.typeopdr_afmeldmarge > 0 && ingesloten.length == 1) // Datum is niet wijzigbaar bij bulk acties
  {
    if (afmelddatum.getTime() != orgdate.getTime())
    { // Antidateren voor SLA rapportages.
      var sql = "BEGIN fac.backtrackaction('ORDAFM', " + ingesloten[i] + ", " + user_key + ", " + afmelddatum.toSQL(true) +"); END;"
      Oracle.Execute(sql);
      // Wel even tracken
      mld.trackopdrachtupdate(ingesloten[i], L("lcl_ord_is_ordupdtrack").format(formattedID) + "\n" + L("lcl_opdr_closeafwijk") + L("lcl_trackto") + toDateTimeString(afmelddatum));
    }
  }

  var sluitmelding = mldClose(mld_opdr.typeopdr_sluitmelding, ingesloten);

  mld.updatemeldingstatus(mld_opdr.mld_key, 0);

  if (sluitmelding > 0 && mld_opdr.typeopdr_isofferte == 0) // misschien melding nu ook? Bij offertes melding nooit automatisch afmelden of de vraag weergeven
  { // Zijn er niet-afgemelde opdrachten bij dezelfde melding?
    sql = "SELECT COUNT(*) aantal"
        + "  FROM mld_opdr o1"
        + " WHERE o1.mld_melding_key = " + mld_opdr.mld_key
        + "   AND o1.mld_statusopdr_key NOT IN (1, 2, 6, 7, 9)";
    oRs = Oracle.Execute(sql);
    var nn = oRs("aantal").Value;
    oRs.Close();
    if (nn == 0) // Het was de laatste opdracht van de melding die nog niet afgemeld is
    {
      reqStatusEmptyMelding = mld.getReqStatusEmptyMelding(reqStatusEmptyMelding, mld_opdr.mld_key, 5); // Melding status "Afgemeld(5)"
      if (reqStatusEmptyMelding.length == 0) // Alle verplichte kenmerken en/of verplicht object zijn ingevuld.
      {
        // Mag ik dan ook de melding afmelden?
        var this_mld = mld.func_enabled_melding(mld_opdr.mld_key);
        // Heeft de melding een openstaande taak?
        sql = "SELECT COUNT(mo.mld_melding_key) aantal"
            + "  FROM mld_melding_object mo"
            + "     , ins_deelsrtcontrole idsc"
            + " WHERE mo.ins_deelsrtcontrole_key = idsc.ins_deelsrtcontrole_key"
            + "   AND idsc.ins_deelsrtcontrole_status < 5"
            + "   AND mo.mld_melding_key = " + mld_opdr.mld_key;
        oRs = Oracle.Execute(sql);
        var aantal_opentaken = oRs("aantal").Value; // Aantal openstaande taken bij de melding.
        oRs.Close();

        if (aantal_opentaken == 0 && this_mld.canClose && (sluitmelding == 2)) // Autoclose mld
        {
          writeOpdrOpmToMld();
          // Handle workflow actions for completion:
          mld.setmeldingstatus(mld_opdr.mld_key, 5);
          mld.nextworkflowstep(mld_opdr.mld_key, 1);  // 1 = completed
        }
        else if (!this_mld.canClose && S("mld_add_mldopmerk_on_opdrclose") == 1 && opdr_opm != "")
        { // Afhandelingtekst van de opdracht automatisch kopiëren naar de melding.
          writeOpdrOpmToMld();
        }
        else
        { //
          result.canCloseMld = this_mld.canClose; // Er wordt alsnog de vraag gesteld of melding ook moet worden gesloten via callback functie, als je de rechten hebt.
          result.mld_key = (result.mld_key? "," : "") + mld_opdr.mld_key; // De meldingen die afgemeld kunnen worden via de callback functie.
        }
      }
      // else: Als result.canCloseMld == true dan is sluitmelding == (1 of 2) en dan wordt alsnog de vraag gesteld of melding ook moet worden gesloten via callback functie.
    }
  }

  // Zijn er bijbehorende facturen die al zijn ingevoerd met de status "Ingevoerd(2)" die nog geapproved moeten worden?
  mld.autoapprovefactuur(ingesloten[i]);

  if (mld_hlt)
  { // Er is 1 onderbroken opdracht die hervat moet worden. Dit doen we door een "ORDRSM" tracking op de opdracht te doen.
    // Haal de onderbroken opdracht weer op.
    var hltopdr = mld.gethltopdrachten(opdr_key_arr[0]);
    // De onderbroken opdracht weer hervatten.
    shared.trackaction("ORDRSM", hltopdr.opdr_key);
    Oracle.Execute("UPDATE mld_opdr SET mld_opdr_halted = 0 WHERE mld_opdr_key = " + hltopdr.opdr_key);
  }
}
result.success = true;
if (ingesloten.length === 1) {
  result.toaster = L("lcl_mld_ord_closed").format(ingesloten[0]);
} else if (ingesloten.length > 1) {
  result.toaster = L("lcl_mld_ord_closed_m").format(ingesloten.length);
}

Response.Write(JSON.stringify(result));
%><% ASPPAGE_END(); %>
