<% @language="javascript"%>
<% /*
     $Revision$
     $Id$

    File:               bes_edit_bestellign_save
    Description:        Opsla script van bes_edit_bestelling.asp

    Parameters:         bes_key (-1 voor nieuwe)
                        dis_key: default catalogus. Verplicht voor nieuwe
    Context:
    Note:               flexArray gaat de flexkenmerken van de *bestelling* bevatten
                        flexkey_string de flexkenmerken van de bes_bestel_item
*/
var JSON_Result = true;
 %>

<!-- #include file="../Shared/common.inc" -->
<!-- #include file="./bes.inc" -->
<!-- #include file="../PRS/prs.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../Shared/kpl_ksrt_validate.inc" -->
<!-- #include file="../Shared/kenmerk_common.inc" -->
<!-- #include file="../Shared/budget.inc" -->

<%
var isCorrectie = getQParamInt("correctie", 0) == 1; // Is een correctiebestelling
var bes_key = getQParamInt("bes_key", -1);
if (bes_key < 0)
{
  var dis_key = getQParamInt("dis_key");
}
else
{
  var bes_bestelling = bes.bestelling_info(bes_key); // Globale variabele met alle bes_bestelling informatie
  var dis_key = bes_bestelling.dis_key;
  var oldStatus = bes_bestelling.rfoStatus; // Status bestelaanvraag
  var opdrStatus = bes_bestelling.rfoBestelOpdrStatus; // Status bestelopdracht (0 indien geen opdracht)
}
var bes_disc_info = bes.disc_info(dis_key);
var approver_key = -1;

var act_key = getFParamInt("act_key", -1);
var act_mode = (act_key > 0);
var kostenplaats_key = getFParamInt("kostenplaats",-1);
var amount_arr = getFParamFloatArray("amount_string",[], true); // true zodat -1 niet gestript wordt
var item_keys_unsafe = getFParamArray("item_keys",[]); // kan ook 'new1' zijn voor nieuwe opdrachten
var flexkey_string_arr = getFParamIntArray("flexkey_string",[]);
var flexval_string_arr = getFParamArray("flexval_string",[]);
var flexdeel_string_arr = getFParamArray("flexdeel_string",[]);
var flexitem_string_unsafe = getFParamArray("flexitem_string",[]); // kan ook 'new1' zijn voor nieuwe opdrachten
var srtdeel_keys = getFParamIntArray("srtdeel_keys",[]); // Bij isFree ook voor bewerken bestaande
var isPunchout = (bes_disc_info.disc_params_punchouturl && !bes_disc_info.isFreeArticle) ? 1 : 0;

if (bes_disc_info.isFreeArticle)
{   // Moeten we de nieuwe srtdeel-en nog aanmaken
    var lev_key = getFParamInt("lev_key_ro", -1);
    if (lev_key == -1) { lev_key = getFParamInt("lev_key"); }
    if (lev_key == -1)
    { // Mag niet voorkomen, maar doet het toch af en toe? (VGLD#53606)
        __DoLog("AiAi: lev_key == -1\nbes_key: " + bes_key + "\ndis_key: " + dis_key);
        abort_with_warning("FATAL ERROR: No Supplier selected..");
    }

    for (var itemregelnr = 0; itemregelnr < item_keys_unsafe.length; itemregelnr++)
    {
        var srtdeel_nr = getFParam("srtdeel_nr_" + item_keys_unsafe[itemregelnr], ""); // Leeg bij bewerken bestaande;
        if (srtdeel_nr)
        {
            var data = { //srtgroep_key: getFParamInt("srtgroup_key_" + item_keys_unsafe[itemregelnr]),
                         srtgroep_omschrijving: L("lcl_bes_free_artgroep"),
                         srtdeel_nr: srtdeel_nr,
                         srtdeel_omschrijving: getFParam("srtdeel_omschrijving_" + item_keys_unsafe[itemregelnr]),
                         srtdeel_prijs: getFParamFloat("price_" + item_keys_unsafe[itemregelnr]),
                         srtdeel_eenheid: getFParam("eenheid_" + item_keys_unsafe[itemregelnr], ""),
                         srtdeel_btw: getFParamFloat("btw_" + item_keys_unsafe[itemregelnr], 21),
                         bedrijf_key: lev_key,
                         srtdeel_opmerking: "" //opmerking
                       };
            try
            {
                var bes_srtdeel_key = bes.upsert_deel(dis_key, data);
            }
            catch (e)
            {
                abort_with_warning(L("lcl_bez_no_double_art").format(srtdeel_nr));
            }
            srtdeel_keys[itemregelnr] = bes_srtdeel_key;
        }
    }
}

var isNew = (bes_key == -1);
var isChange = !isNew && bes_bestelling.parent_key > 0;
// Een change bestelling kan alleen gewijzigd (er wordt geen nieuwe change aangemaakt) worden indien deze status 2 (Nieuw) heeft.
if (isChange && oldStatus != 2)
  abort_with_warning("Internal error: Change bestelling kan niet gewijzigd worden");

// Person's info
prs_key = getFParamInt("person");
if (bes_disc_info.disc_params_for_others)
  prs_key_voor = getFParamInt("personFor");
else
  // Als de setting niet is gezet is "Bestelling voor" gelijk aan contactpersoon. Invoerveld "Bestelling voor" was dan ook niet aanwezig.
  // Kollommen prs_perslid_key en prs_perslid_key_voor zijn dan identiek.
  prs_key_voor = prs_key;

if (bes_key < 0)
{
  var fiatbedrag = 0;
}
else
{ // Indien a) de aanvrager geen profiellimiet heeft of
  //        b) de setting can_selfapprove < 0
  // dan moet er ALTIJD ge(her)fiatteerd worden. In deze gevallen moet bij herfiattering gefiatteerd worden alsof het de eerste fiattering is.
  // Het bes_bestelling_fiatbedrag zal wel bijgehouden moeten worden omdat er meerdere kostenplaats(groep) fiatteurs na elkaar moeten kunnen fiatteren,
  // maar als er opnieuw gefiatteerd dient te worden, dan moet er bij de eerste fiattering weer uitgegaan worden van een LEEG bes_bestelling_fiatbedrag.
  var sql = "SELECT prs.getprofiellimiet(" + (S("prs_dep_default_kpn_voor") == 0? prs_key : prs_key_voor) + ", " + dis_key + ") limiet FROM DUAL";
  var oRs = Oracle.Execute(sql);
  if (oRs("limiet").value == null || S("can_selfapprove") < 0)
    // Geen profiel is altijd te hoog of ik kan nooit zelf fiatteren.
    // Als nieuw fiatteren.
    var fiatbedrag = 0;
  else
    var fiatbedrag = bes_bestelling.fiatbedrag;
  oRs.Close();
}

var urole = getQParamSafe("urole");
var autfunction = {fo: 'WEB_BESFOF', bo: 'WEB_BESBOF'}[urole] || 'WEB_BESUSE';
if (!act_mode)
{
    if (bes_key < 0)
    {
        user.checkAutorisation(autfunction); // TODO: Scherper dat je op elke item-regel rechten hebt
    }
    else
    {
      var this_bes = bes.func_enabled_bestelling(bes_bestelling);
      user.auth_required_or_abort(this_bes.canChange);
    }

}

var item_coll = [];
for (i = 0; i < amount_arr.length; i++)
{
  item_coll[i] = parseInt(item_keys_unsafe[i], 10);
}

// staffel_info.totaalbedrag is erg handig
var staffel_info = bes.staffel_info(srtdeel_keys, amount_arr);
itemprijsstring = staffel_info.itemprijsstring;

var strState = ""; // L("lcl_bes_RFO_regSuccess")

// Check customer specific restrictions
// customer hook
var pResult = new HookResult();

// Klantspecifieke check functie (hookfunction) voor de invoer
if ((!custfunc.bes_checkrfo(dis_key, srtdeel_keys, amount_arr, pResult)) && (!act_mode))
{
  abort_with_warning(pResult.errmsg);
}

if (!isCorrectie)
{
  if (staffel_info.totaalbedrag < bes_disc_info.disc_params_min_bedrag && isNew)
  {
    if (!act_mode)
    {
      abort_with_warning(L("lcl_bes_below_limit") + " " + S("currency_pref") + safe.curr(bes_disc_info.disc_params_min_bedrag) + S("currency_suff"));
    }
  }

  // Combinatievalidatie
  if (!kpl_ksrt_validate(kostenplaats_key, null, dis_key))
    abort_with_warning(L("lcl_res_kpks_validatie"));

  var ter_finfiattering = false;
  var isFE = autfunction == 'WEB_BESUSE';

  // reinit
  var pResult = new HookResult();
  // Note:   ALTERNATIEF VOOR DE FUNCTIE ZOU EEN BES_DISC_PARAMS_REMOTE KUNNEN ZIJN..??
  var UseRemoteApproval = custfunc.bes_hasremoteapproval(dis_key, pResult) && pResult.value;
  if (UseRemoteApproval)
  {
    // De fiattering voor deze catalogus ligt helemaal buiten FACILITOR
    ter_finfiattering = true;
  }
  else
  {
    if (bes_disc_info.disc_params_autoacceptrfo == 0)  // :Automatisch accepteren aanvraag
    {
      var params = {prs_key: prs_key,
                    prs_key_voor: prs_key_voor,
                    dis_key: dis_key,
                    kp_key: kostenplaats_key,
                    totaalbedrag: staffel_info.totaalbedrag,
                    fiatbedrag: fiatbedrag,
                    bes_bestelling: bes_bestelling,
                    bes_disc_info: bes_disc_info,
                    isNew: isNew,
                    isFE: isFE,
                    oldStatus: oldStatus,
                    act_mode: act_mode};
      ter_finfiattering = bes.checkFiat(bes_key, params);


      // Als het boven mijn profiel is, of ik -als ik budgethouder ben/zou zijn- niet zelf mag goedkeuren.
      // Gaan we kijken wie dan wel.
      if (ter_finfiattering)
      { // Wie moet dit (als eerste) goedkeuren voor deze kostenplaats?
        // De melder van de melding (prs_key) mag niet zelf goedkeuren boven het bedrag can_selfapprove.
        // staffel_info.totaalbedrag > can_selfapprove => prs_key als exclude key meegeven.
        // prs_key heeft altijd een waarde (prs_key > 0) (required).
        approver_key = prs.getApprover(params);
      }
    }
  }
}
// JGL:  5.1.2: er is besloten dat een concept/embargo alleen (en altijd)
//       wordt aangemaakt als er ook al opdrachten waren.
//       Tot die tijd wordt een gewone update gedaan (net als 5.1.1) maar
//       alleen wel oppassen dat er mogelijk ge(her)fiatteerd moet worden

// We kunnen in vier varianten belanden
// A) helemaal nieuwe bestelling aanmaken (isNew)
// B) bestaande hoofdbestelling bijwerken (vervang, !isChange), er zullen nog geen opdrachten zijn
// C) bestaande concept bestelling bijwerken (vervang, isChange), hij zelfs nog niet gefiatteerd
// D) nieuwe embargo/concept bestelling aanmaken (makechange)

var makechange = false; // Wijziging maken/behouden
var vervang = isChange; // Wijzig origineel
if (!isNew && !isChange)
{ // Bestaande (niet change) bestellingen
  makechange = (oldStatus == 5); // Opdrachten zijn aangemaakt en nog niet geleverd==>make change request
                                 // Of ze ook *echt* de deur uit zijn negeren we.
  vervang = !makechange;
}

// tamper check
if (S("fac_tamper_check") > 0 && !user.has(["WEB_BESFOF", "WEB_BESBOF"]))
{
    __Log("Tamper checking frontend");
    if (prs_key > 0)
        user.auth_required_or_abort(user.isCollega(prs_key));

    var personH_key = getFParamInt("personH", user_key);
    if (prs_key_voor > 0 && prs_key_voor != user_key) // geen onnodig dure controle
    {
        var bresult = user.func_enabled2("BES", {  // We nemen geen disciplines mee, dat is onbegonnen werk
                                                   // alg_key: alg_onroerendgoed_keys,
                                                   prs_key: prs_key_voor
                                                }
                                        )
        user.auth_required_or_abort(bresult.canWrite("WEB_BESUSE"));
    }
}

if (makechange && !bes_disc_info.can_concept)
    INTERNAL_ERROR_UNEXPECTED_MAKECHANGE;

var fields =  [ { dbs: "prs_perslid_key",             typ: "key",      val: prs_key ,               track: L("lcl_name"),          foreign: "prs_perslid"},
                { dbs: "prs_perslid_key_voor",        typ: "key",      val: prs_key_voor ,          track: L("lcl_bes_order_for"), foreign: "prs_perslid"},
                { dbs: "prs_kostenplaats_key",        typ: "key",      frm: "kostenplaats",         track: L("lcl_account"),       foreign: "prs_kostenplaats" },
                { dbs: "bes_bestelling_ordernr",      typ: "varchar",  frm: "ordernr",              track: L("lcl_mld_inf_Ordernr") },
                { dbs: "bes_bestelling_kosten_klant", typ: "check",    frm: "kostenklant" },
                { dbs: "mld_adres_key_lev",           typ: "key",      frm: "deliveryAddr",         track: L("lcl_delivery_address"),foreign: "MLD_V_AFLEVERADRES" },
                { dbs: "bes_bestelling_leverdatum",   typ: "date",     frm: "calendar",             track: (bes_disc_info.disc_params_leverdagen>0? L("lcl_bes_deli_date_exp") : L("lcl_bes_deli_date")) },
                { dbs: "bes_bestelling_plaats",       typ: "varchar",  frm: "delivery_place",       track: L("lcl_bes_del_room") },
                { dbs: "bes_bestelling_module",       typ: "varchar",  val: "BES" },
                { dbs: "bes_bestelling_levkosten",    typ: "float",    val: staffel_info.bes_kosten },
                { dbs: "bes_bestelling_lev_opm",      typ: "varchar",  frm: "lev_opm",              track: L("lcl_bes_bestelling_lev_opm"), len: 320 }
              ];

var mld_key = getQParamInt("mld_key", -1);
if (mld_key != -1)
{ // New bestelling originated from a mld_melding
  fields.push({dbs: "mld_melding_key", typ: "key", val: mld_key});
}

// Opslaan bestelaanvraag (bestelling info), insert of update
var parent_key;
if (isNew || makechange)
{ // Insert een nieuwe (change) bestelaanvraag
  if (makechange)
  { // Parent_key ook opslaan
    fields.push({dbs: "bes_bestelling_parentkey", typ: "key", val: bes_key});
  }

  if (act_mode)
  {
    fields.push({dbs: "fac_activiteit_key", typ: "key", val: act_key});
  }

  var levdat = getFParamDate("calendar");
  var maxdate = new Date();
  maxdate.setDate(maxdate.getDate() + S("bes_datum_limiet"));
  if ( S("bes_datum_limiet") > 0 && levdat > maxdate )
  {
    abort_with_warning(L("lcl_bes_date_farfuture")); // te ver in de toekomst
  }
  if (levdat < (new Date()).midnight() && bes_disc_info.disc_params_leverdagen > 0)
  {
    abort_with_warning(L("lcl_bes_date_future")); // Moet in de toekomst
  }

  fields = fields.concat([{dbs: "bes_bestelling_key", typ: "key", seq: "bes_s_bes_bestelling_key"}])
  var besIns = buildInsert("bes_bestelling", fields);

  // Nieuwe bestelaanvraag krijgt een nieuwe bes_key
  bes_key = besIns.sequences["bes_bestelling_key"];
  var err = Oracle.Execute(besIns.sql, true);
  if (err.friendlyMsg)
    abort_with_warning(err.friendlyMsg);

  // NIET tracken (wordt later met volgende stap gedaan) bes.setbestellingstatus(bes_key, 2); // Aangemaakt
  // Nieuwe net aangemaakte bestelling heeft nu nog status 2 (Nieuw)
  status = 2;
}
else
{ // Update (vervang)
  var besUpd = buildTrackingUpdate("bes_bestelling", " bes_bestelling_key = " + bes_key, fields);

  if (bes_bestelling.totaal.toFixed(2) != staffel_info.totaalbedrag.toFixed(2))
    besUpd.trackarray.push(L("lcl_total") + ": " + buildTrackText("float", safe.curr(bes_bestelling.totaal),  safe.curr(staffel_info.totaalbedrag)));

  if (bes_disc_info.isFreeArticle && bes_bestelling.prs_bedrijf_key != lev_key)
  {
    var upd_lev = "UPDATE bes_srtdeel"
                + "   SET prs_bedrijf_key = " + lev_key
                + " WHERE bes_srtdeel_key IN"
                + "(SELECT s.bes_srtdeel_key"
                + "   FROM bes_bestelling_item b"
                + "      , bes_srtdeel s"
                + "  WHERE b.bes_srtdeel_key = s.bes_srtdeel_key"
                + "    AND b.bes_bestelling_key = " + bes_key
                + ")";
    Oracle.Execute(upd_lev);
    // tracking
    var old_lev = prs.prs_bedrijfinfo(bes_bestelling.prs_bedrijf_key);
    var new_lev = prs.prs_bedrijfinfo(lev_key);
    besUpd.trackarray.push(L("lcl_ins_leverancier") + ": " + buildTrackText("varchar", old_lev.naam, new_lev.naam, { nodiff: true }));
  }

  Oracle.Execute(besUpd.sql);

  status = oldStatus;
}

currentKenmerkenSQL = "SELECT kb.bes_kenmerk_key"
                    + "     , kb.bes_kenmerkbestell_waarde"
                    + "     , k.bes_kenmerk_toonbaar"
                    + "     , k.fac_functie_key"
                    + "  FROM bes_kenmerkbestell kb"
                    + "     , bes_kenmerk k"
                    + " WHERE k.bes_kenmerk_key = kb.bes_kenmerk_key"
                    + "   AND bes_kenmerkbestell_verwijder IS NULL"
                    + "   AND bes_bestelling_key = " + bes_key;

allKenmerkenSQL     = "SELECT COALESCE (" + lcl.xsql("k.bes_kenmerk_omschrijving", "k.bes_kenmerk_key")
                    + "              ,  " + lcl.xsql("t.bes_srtkenmerk_omschrijving", "t.bes_srtkenmerk_key") + ") kenmerk_omschrijving"
                    + "     , t.bes_srtkenmerk_kenmerktype kenmerk_kenmerktype"
                    + "     , t.bes_srtkenmerk_systeem     kenmerk_systeem"
                    + "     , k.bes_kenmerk_toonbaar       kenmerk_readonly"
                    + "     , k.bes_kenmerk_uniek          kenmerk_uniek"
                    + "     , fac_kenmerkdomein_key"
                    + "  FROM bes_kenmerk k"
                    + "     , bes_srtkenmerk t"
                    + " WHERE k.bes_srtkenmerk_key = t.bes_srtkenmerk_key"
                    + "   AND k.bes_kenmerk_key = "; /* wordt in saveFlexkenmerken uitgebreid */

var flextrack = saveFlexKenmerken(bes_key, { kenmerkTable: "bes_kenmerkbestell",
                                             kenmerkParentKey : "bes_bestelling_key",
                                             kenmerkWaarde: "bes_kenmerkbestell_waarde",
                                             kenmerkKey: "bes_kenmerk_key",
                                             kenmerkToonbaar: "bes_kenmerk_toonbaar",
                                             currentKenmerkenSQL: currentKenmerkenSQL,
                                             allKenmerkenSQL: allKenmerkenSQL,
                                             requestQF: Request.Form,
                                             isNew: isNew,
                                             flexPath: "BES/B",
                                             tracking: true,
                                             module: "BES"
                                           }
                                 );

if (!isNew && !makechange) // update nog tracken
{
    shared.trackaction("BESUPD", bes_key, L("lcl_bes_is_besupdtrack").format(S("bes_bestelling_prefix") + bes_key) + "\n" +
                                          besUpd.trackarray.concat(flextrack).join("\n"));
};

// ======================================================
// Bestelling info is geweest. Ga nu verder met regelinfo
// ======================================================

// 1=afgewezen, 2=nieuw, 3=Gefiatteerd, 4=Geaccepteerd, 5=Besteld
if (status == 1 || status == 2 || status == 3 || status == 4 || status == 5)
{ // In deze mode kunnen er regels bij of afkomen. We gooien alles weg en inserten opnieuw
  // Delete all objects if updating
  if (vervang)
  {
    sql = "DELETE FROM bes_bestelling_item WHERE bes_bestelling_key = " + bes_key;
    Oracle.Execute(sql);
  }
  // else isNew of makechange

  // insert values into bes_bestelling_item
  // insert flexproperies in bes_kenmerkbesteli
  nrSuccess = 0;
  // bes_srtdeel_key kan vaker ingevoerd zijn.
  for (var itemregelnr = 0; itemregelnr < item_keys_unsafe.length; itemregelnr++)
  { // items_keys bevat de regelnummers, aantal alleen van belang
    // Zelf volgende item_key opvragen

    // Het aantal moet groter zijn dan 0, anders niet opslaan.
    if (isCorrectie || amount_arr[itemregelnr] > 0)
    {
      var fields =  [ { dbs: "bes_bestelling_item_key",        typ: "key",    seq: "bes_s_bes_bestelling_item_key" },
                      { dbs: "bes_bestelling_key",             typ: "key",    val: bes_key },
                      { dbs: "bes_srtdeel_key",                typ: "key",    val: srtdeel_keys[itemregelnr] },
                      { dbs: "bes_bestelling_item_aantal",     typ: "float",  val: amount_arr[itemregelnr] },
                      { dbs: "bes_bestelling_item_brutoprijs", typ: "sql",    val: "bes.getsrtdeelprijs(" + srtdeel_keys[itemregelnr] + ", NULL)" },
                      { dbs: "bes_bestelling_item_inkprijs",   typ: "sql",    val: "bes.getsrtdeelinkprijs(" + srtdeel_keys[itemregelnr] + ", NULL)" },
                      { dbs: "bes_bestelling_item_prijs",      typ: "float",  val: itemprijsstring[itemregelnr] }
                    ];

      var besIns = buildInsert("bes_bestelling_item", fields);
      var bestelling_item_key = besIns.sequences["bes_bestelling_item_key"];
      var err = Oracle.Execute(besIns.sql);
      if (err.friendlyMsg)
        abort_with_warning(err.friendlyMsg);
      nrSuccess++;

      // Indien flexkenmerken bij dit item, dan opslaan
      foundone = false;
      for (var i = 0; i < flexdeel_string_arr.length; i++)
      {
        if (flexitem_string_unsafe[i] == item_keys_unsafe[itemregelnr])
        {
          foundone = true;
          var fields =  [ { dbs: "bes_bestelling_item_key",   typ: "key",     val: bestelling_item_key },
                          { dbs: "bes_kenmerk_key",           typ: "key",     val: flexkey_string_arr[i] },
                          { dbs: "bes_kenmerkbesteli_waarde", typ: "varchar", val: unescape(flexval_string_arr[i]) }
                        ];
          var besIns = buildInsert("bes_kenmerkbesteli", fields);
          var err = Oracle.Execute(besIns.sql, true);
          if (err.friendlyMsg)
            abort_with_warning(err.friendlyMsg);
        }
        else
        {
          if (foundone) break; // als er al 1 gevonden is dan staan ze achter elkaar.
        }
      }
    }
  }
  if (nrSuccess == 0)
    abort_with_warning("Internal error: geen bestelregels opgeslagen");

  if (!vervang)
    shared.trackaction("BESNEW", bes_key);

  if (makechange) // in de originele tracking verwijzen we naar de change-request
    shared.trackaction("BESUPD", getQParamInt("bes_key"), L("lcl_bes_change") + S("bes_bestelling_prefix") + bes_key );

  if (UseRemoteApproval)
  {
    __Log("Requesting remote approval");
    var remoteResult = custfunc.bes_getremoteapproval(getQParamInt("bes_key", pResult));   // dis_key ook meegeven?
    // Track dat fiattering gevraagd wordt aan extern systeem (custfunc.bes_remoteapprovalSystemName(dis_key)?)
    // En wat bij fail?
    // shared.trackaction("BESAP2", bes_key, remoteResult);
//    var corsaResult = false;
//    var corsaError = "";
//    corsaResult = corsaConnect();
//    if (!corsaResult)
//      strState = "Resultaat Corsa/Webservice: "+corsaError;
//
//    var xmlTableDef = Server.CreateObject("MSXML2.DOMDocument.6.0");
//    var docNr = corsaCreateDoc(bes_key);
//    var caseID = corsaGetCase(docNr);
//    xmlTableDef = corsaVarTabGet(caseID);
//    corsaVarTabSet(bes_key, caseID, xmlTableDef);
//    corsaDisconnect();

//    sql = "UPDATE bes_bestelling"
//        + "   SET bes_bestelling_opmerking = 'CORSA: " + docNr + " (" + caseID + ")'"
//        + " WHERE bes_bestelling_key = " + bes_key;
//    Oracle.Execute(sql);
  }
  else
  { // internal approval mechanism
    // Nu kan daadwerkelijk de juiste status gezet worden.

    // Afhankelijk van de fiatterings/acceptatie flow zijn dit de acties:
    // 1) "Fiatteur -> BESBOF": bes_disc_params_fiatflow = 0 (fiatteren en dan accepteren).
    //                           Als er gefiatter moet worden dan kostenplaats verantwoordelijke een notificatie sturen. De status blijft "Nieuw(2)".
    //                           Als er niet meer gefiatteerd moet worden, moet er gekeken worden of er geaccepteerd dient te worden.
    //                           Als er geaccepteerd dient te worden moet de status naar "Gefiatteerd(3)".
    //                           Als er niet meer geaccepteerd hoeft te worden kan de status dan naar "Geaccepteerd(4)" of naar status "Besteld(5)" als de setting auto_order is gezet.
    //                           Dit is de standaard flow.
    // 2) "BESBOF -> Fiatteur":  bes_disc_params_fiatflow = 1 (accepteren en dan fiatteren).
    //                           Als er geaccepteerd moet worden blijft de status "Nieuw(2)".
    //                           Als er niet meer geaccepteerd moet worden, moet er gekeken worden of er gefiatteerd dient te worden.
    //                           Als er gefiatteerd dient te worden moet de status naar "Geaccepteerd(4)". Dan de kostenplaats verantwoordelijke een notificatie sturen.
    //                           Als er niet meer gefiatteerd hoeft te worden kan de status dan naar "Gefiatteerd(3)" of naar status "Besteld(5)" als de setting auto_order is gezet.
    // Moet er finanicieel gefiatteerd worden?
    var hasToApprove = approver_key > 0;
    // Moet de BackoOffice (BO) nog accepteren?
    var hasToAccept = ((oldStatus == (bes_disc_info.disc_params_fiatflow == 0? 3 : 4) &&
                        staffel_info.totaalbedrag > bes_bestelling.approved &&
                        staffel_info.totaalbedrag > bes_disc_info.disc_params_bestellimiet) ||
                       ((staffel_info.totaalbedrag > bes_disc_info.disc_params_bestellimiet) &&
                        (isNew || bes.herfiatteren(bes_bestelling, bes_disc_info, staffel_info.totaalbedrag))));

    if (bes_disc_info.disc_params_fiatflow == 0) // Fiatteur -> BESBOF ofwel Fiatteren -> Accepteren.
    {
      if (hasToApprove) // Fiatteren.
      {  // Fiatteren + accepteren.
        // Deze bestelling moet financieel gefiatteerd worden.
        // Send de fiatteur een notificatie.
        // Niet uitvoeren bij bestelling voor geplande actie
        if (!act_mode)
        {
          if (vervang)
          {
            // Bij wijzigen i.v.m herfiattering/heraccepteren de fiatteur,het fiatteer bedrag en het accepteer bedrag op null zetten zodat het fiatteren + accepteren opnieuw kan beginnen.
            var sql = "UPDATE bes_bestelling"
                    + "   SET bes_bestelling_fiat_user = NULL"
                    + "     , bes_bestelling_fiatbedrag = NULL"
                    + "     , bes_bestelling_approved = NULL"
                    + "     , bes_bestelling_status = 2"
                    + " WHERE bes_bestelling_key = " + bes_key;
            Oracle.Execute(sql);
            // AP2 notificatie wordt al door sendNeedApprovalNotification gedaan
            // bes.setbestellingstatus(bes_key, 2); // terug naar Nieuw/ter acceptering
          }
          strState = bes.sendNeedApprovalNotification(bes_key, approver_key);
        }
      }
      else
      { // Alleen accepteren. Fiatteren niet nodig.
        // Geen financieele fiattering nodig.
        // Als orgineel nog geaccepteerd moet worden door BO (status is 3) dan zeker eerst accepteren.
        // Tenzij het bedrag is verlaagd tot onder het approved bedrag of eerste bestellimiet bedrag. Dan kan naar de volgende status worden gegaan.
        if  (hasToAccept)  // Moet BO nog accepteren?
        { // Accepteren + fiatteren.
          bes.setbestellingstatus(bes_key, 3, L("lcl_bes_fiatbyrules")); // finanicieel gefiatteerd, BO moet nog wel
          // Bij wijzigen i.v.m herfiattering/heraccepteren het approved bedrag op null zetten zodat het accepteren opnieuw kan beginnen.
          if (vervang)
          {
            var sql = "UPDATE bes_bestelling"
                    + "   SET bes_bestelling_approved = NULL"
                    + " WHERE bes_bestelling_key = " + bes_key;
            Oracle.Execute(sql);
          }
        }
        else
        {
          bes.setbestellingstatus(bes_key, 4); // Geaccepteerd(4).

          if (!act_mode && bes_disc_info.disc_params_auto_order == "1") // direct opdracht aanmaken
          {
            if (oldStatus == 5 && opdrStatus == 1) // afgewezen opdrachten vervangen we gewoon
              bes.changeOrders(user_key, bes_key);
            else
              bes.makeOrders(user_key, bes_key);
          }
        }
      }
    }
    else // bes_disc_info.disc_params_fiatflow == 1, BESBOF -> Fiatteur ofwel Accepteren -> Fiatteren.
    {
      if  (hasToAccept)
      { // Accepteren + fiatteren.
        // Bij wijzigen i.v.m herfiattering/heraccepteren de fiatteur/het accepteer bedrag op null zetten zodat het fiatteren/accepteren opnieuw kan beginnen.
        if (!act_mode)
        {
          if (vervang)
          {
            var sql = "UPDATE bes_bestelling"
                    + "   SET bes_bestelling_fiat_user = NULL"
                    + "     , bes_bestelling_fiatbedrag = NULL"
                    + "     , bes_bestelling_approved = NULL"
                    + "     , bes_bestelling_status = 2"
                    + " WHERE bes_bestelling_key = " + bes_key;
            Oracle.Execute(sql);
          }
          // De eerste niveau accepteerders (BESBOF) hoeven geen notificaties te ontvangen.
        }
      }
      else
      { // Alleen fiatteren. Accepteren niet nodig.
        // Als orgineel nog financieel gefiatteerd moet worden (status is 4) dan zeker eerst financieel fiatteren.
        if  (hasToApprove)  // Moet nog financieel gefiatteerd worden?
        {
          bes.setbestellingstatus(bes_key, 4, L("lcl_bes_acceptbyrules")); // BO heeft geaccepteerd, finanicieel fiatteren moet nog wel.
          // Bij wijzigen i.v.m herfiattering/heraccepteren de fiatteur op null zetten zodat het fiatteren opnieuw kan beginnen.
          if (vervang)
          {
            var sql = "UPDATE bes_bestelling"
                    + "   SET bes_bestelling_fiat_user = NULL"
                    + "     , bes_bestelling_fiatbedrag = NULL"
                    + " WHERE bes_bestelling_key = " + bes_key;
            Oracle.Execute(sql);
          }
        }
        else
        {
          bes.setbestellingstatus(bes_key, 3); // Gefiatteerd(3).

          if (bes_disc_info.disc_params_auto_order == "1") // direct opdracht aanmaken
          {
            if (oldStatus == 5 && opdrStatus == 1) // afgewezen opdrachten vervangen we gewoon
              bes.changeOrders(user_key, bes_key);
            else
              bes.makeOrders(user_key, bes_key);
          }
        } // !hasToApprove
      } // !hasToAccept
    } // bes_disc_info.disc_params_fiatflow == 1.
  } // internal approval mechanism.
} // Status 1 t/m 5.
else if (oldStatus == 6) // 6=geleverd
{ // er kunnen/zullen ook al bes_bestelopdr_item's bestaan
  // er zullen nooit regels bijkomen/weggaan, hoogstens aantallen gewijzigd

  sql = "SELECT bes_bestelling_item_key,"
      + "       bes_bestelling_item_aantal"
      + "  FROM bes_bestelling_item"
      + " WHERE bes_bestelling_key = " + bes_key;
  oRs = Oracle.Execute(sql);
  old_aantal = new Array();
  while(!oRs.eof)
  {
    old_aantal[oRs("bes_bestelling_item_key").value] = oRs("bes_bestelling_item_aantal").value;
    oRs.MoveNext();
  }
  oRs.Close();

  // Flex konden niet gewijzigd worden.
  for (var itemregelnr = 0; itemregelnr < item_keys_unsafe.length; itemregelnr++)
  {
    sql = "UPDATE bes_bestelling_item"
        + "   SET bes_bestelling_item_aantal = " + amount_arr[itemregelnr]
        + ",      bes_bestelling_item_brutoprijs = "
        + "             bes.getsrtdeelprijs(bes_bestelling_item.bes_srtdeel_key, NULL)"
        + ",      bes_bestelling_item_prijs = " + itemprijsstring[itemregelnr]
        + " WHERE bes_bestelling_item_key = " + parseInt(item_keys_unsafe[itemregelnr], 10)
        + "   AND bes_bestelling_key = " + bes_key;
    Oracle.Execute(sql);

    sql = "UPDATE bes_bestelopdr_item"
        + "   SET bes_bestelopdr_item_aantal = "
        + "          nvl(bes_bestelopdr_item_aantal, 0)"
        + "          - " + old_aantal[item_coll[itemregelnr]]
        + "          + " + amount_arr[itemregelnr]
        + ",      bes_bestelopdr_item_prijs = bes.calcbesartikelkortingsprijs(" + item_coll[itemregelnr] + ", " + isPunchout + ")"
        + " WHERE bes_bestelopdr_item_key ="
        + "     (SELECT bes_bestelopdr_item_key"
        + "        FROM bes_bestelling_item"
        + "       WHERE bes_bestelling_item_key = " + item_coll[itemregelnr]
        + "         AND bes_bestelling_key = " + bes_key + ")";
    Oracle.Execute(sql);

    sql = "SELECT DISTINCT boi.bes_bestelopdr_key besopdr_key"
        + "  FROM bes_bestelling_item bi"
        + ",      bes_bestelopdr_item boi"
        + " WHERE bi.bes_bestelopdr_item_key = boi.bes_bestelopdr_item_key"
        + "    AND bes_bestelling_key = " + bes_key;
    oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
      sql = " SELECT bes.calcbesopdrachtkosten(" + oRs("besopdr_key").value + ", 0) lev_kosten FROM DUAL";
      oRs2 = Oracle.Execute(sql);
      sql = "UPDATE bes_bestelopdr"
          + "   SET bes_bestelopdr_levkosten = " + (oRs2("lev_kosten").value? oRs2("lev_kosten").value : "0")
          + " WHERE bes_bestelopdr_key = " + oRs("besopdr_key").value;
      Oracle.Execute(sql);
    }
  }
}

// Klantspecifieke hookfunction
var pResult = new HookResult();
if (!custfunc.bes_postsave(bes_key, pResult))
{
  abort_with_warning(pResult.errmsg);
}
var doneParams = { bes_key: bes_key,
                   warning: safe.jsstring(strState),
                   success: true
                 }

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