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

    File:           api_opdrsoap.asp
    Description:    API voor mld-soap berichten
                    Interpreteert een bericht zodanig dat opdrachtgegevens worden aangepast
                    Dat is: qua omschrijving (voortgang), kosten of status.
                    Als een status wordt meegegeven, dan is ook vereist dat dat een
                    geldige statusovergang is, anders wordt het hele bericht genegeerd.

    Parameters:     een xml
    Context:
    Notes:

*/

    DOCTYPE_Disable = 1;
    THIS_FILE = "cust/rwsn/api_opdrsoap.asp";
%>
<!-- #include file="../../Appl/Shared/common.inc" -->
<!-- #include file="../../Appl/Shared/xml_converter.inc" -->
<!-- #include file="../../Appl/Shared/save2db.inc" -->
<!-- #include file="../../Appl/api/api.inc" -->
<!-- #include file="../../Appl/mld/mld.inc" -->

<%
    // We sturen het antwoord in UTF-8
    Session.Codepage = 65001;
    Response.Charset = 'utf-8';

    var APIname = getQParam("API");
    var APIKEY = getQParam("APIKEY");
    var API = new API_func(APIname, APIKEY);
    var appendRemark = -1;
    for (opt in API.apidata.options)
    {
      if (opt = "appendRemark")
      {
         appendRemark = API.apidata.options["appendRemark"] == 1;
      }
    }

    Session("logging") = API.apidata.loglevel||0;

    var tsql = "-";     // Voor tijdelijke statement
    var sql = "-";      // De uiteindelijke update-sql


   // if (API.apidata.loglevel & 1)
   // {
   //     // als het nodig is gaan we eerst het binnenkomende bericht loggen.
   //     fileStream = Server.CreateObject("ADODB.Stream");
   //     fileStream.Type = 1; // adTypeBinary eerst nog
   //     fileStream.Open();
   //     fileStream.Write(Request.BinaryRead(Request.TotalBytes));
   //     fileStream.SaveToFile(Server.MapPath(rooturl + "/temp/") + "/" + customerId + "_" + APIname + ".tmp", 2); //  2=create
   //}

    var xmlReq = Server.CreateObject("MSXML2.DOMDocument.6.0");
    xmlReq.load(Request);

    var xmlResp = new ActiveXObject("MSXML2.DOMDocument.6.0");
    xmlResp.appendChild(xmlResp.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""))

    // The response
    var FCLTElement = xmlResp.createElement("facilitor");
    // The response header
    var now = new Date();
    var nowtxt = now.getFullYear()+'-'+padout(now.getMonth()+1) +'-'+padout(now.getDate()) +' '
                           +padout(now.getHours()) +':'+padout(now.getMinutes())+':'+padout(now.getSeconds());

    var FCLTHeader = xmlResp.createElement("header");
    var headerinfo = {
//                 file: String(Request.ServerVariables("SCRIPT_NAME")).toLowerCase(),
                 datum: nowtxt,
                 naam: user.naam(),
                 custId: customerId,
                 language: user.lang()
               }
    for (param in headerinfo)
    {
        var FCLTdata = xmlResp.createElement(param);
        FCLTdata.appendChild(xmlResp.createTextNode(headerinfo[param]));
        FCLTHeader.appendChild(FCLTdata);
    }
    FCLTElement.appendChild(FCLTHeader);

   // Luie oplossing: Oracle kan dit simpeler dan JavaScript
   function XMLtoJsDate(xmlDate)
   {
        var sql = "select to_date("+safe.quoted_sql(xmlDate)+", 'YYYY-MM-DD HH24:MI:SS') FROM DUAL";
        var oRs = Oracle.Execute(sql);
        var dt = new Date(oRs(0).Value);
        oRs.Close();
        return dt;
   }
   function XMLval(xml, tag)
   {
        if (!xml)
            return null;
        var xx = xml.getElementsByTagName(tag);
        if (!xx || !xx.length)
            return null;
        xx = xx[0].childNodes
        if (!xx || !xx.length)
            return null;
        return xx[0].nodeValue;
   }

    // Hier zou het echte werk moeten gebeuren n.a.v. xmlReq
    // en FCLTElement moeten we uitbreiden met antwoorden
    var detected ="?";
    //    xmlReq.setProperty("SelectionLanguage", "XPath");       // Weet niet of noodzakelijk


    // Dit is de opdrachtenloop (mochten er ooit nog anderen gaan volgen)
    var opdrachten = xmlReq.getElementsByTagName("opdracht");
    for (i=0; i < opdrachten.length; i++)
    {
        var resultcode = -1;        /* zolang deze -1 is, is het nog goed. Uiteindelijk eindigt het met 0 (als goed) */
        var resulttekst = "";

        // Lees per node de (optionele) tages en waarden
        //var opdraction      = (opdrachten[i].getElementsByTagName("action"))[0].childNodes[0].nodeValue;
        var opdr_key        = -1;   // Bepalen we zo uit de melding/volgnr
        var oldstatus       = -1;   // Bepalen we zo uit de melding/volgnr
        var topdr_key       = -1;   // Bepalen we zo uit de melding/volgnr
        var mld_fields      = [];   // bij te werken velden
        var opdr_fields     = [];   // bij te werken velden
        var opdrid          = opdrachten[i].getAttribute("key");
        var opdraction      = opdrachten[i].getAttribute("type").toLowerCase();
        var opdrstatus      = XMLval(opdrachten[i], "status");
        var opdropmerking   = XMLval(opdrachten[i], "opmerking");
        var txt_mut_datum   = XMLval(opdrachten[i], "mut_datum");

        var opdrgereed      = XMLval(opdrachten[i], "datumgereed");
        var opdrkosten      = XMLval(opdrachten[i], "kosten");
        var opdrkenmerken   = (opdrachten[i].getElementsByTagName("kenmerk"));


        var idarr = opdrid.split('/');
        var mldkey = parseInt(idarr[0], 10);
        var opdrvolgnr = parseInt(idarr[1], 10);

        if (isNaN (mldkey) || isNaN (opdrvolgnr)) {
            resultcode = 2;
            resulttekst = "Invalid opdracht id (key) "+opdrid;
        } else {
            tsql = "SELECT mld_opdr_key, mld_statusopdr_key, mld_typeopdr_key"
                + " FROM mld_opdr"
                + " WHERE mld_melding_key="+ mldkey
                + " AND mld_opdr_bedrijfopdr_volgnr="+opdrvolgnr;
            var oRs = Oracle.Execute(tsql);
            if (!oRs.eof) {
                opdr_key = oRs("mld_opdr_key").value;
                oldstatus = oRs("mld_statusopdr_key").value;
                topdr_key = oRs("mld_typeopdr_key").value;
            }

            if (opdr_key == -1) {
                resultcode = 5;
                resulttekst = "Non existent opdracht";
            } else {
                // Hier heb ik een geldige opdrachtkey
                if (this_opdr = mld.func_enabled_opdracht(opdr_key))
                {
                    // Ik weet nu ook de rechten
                    var mld_opdr = mld.mld_opdr_info(opdr_key);

                    sql = "SELECT mld_stdmelding_autoorder"
                        + "  FROM mld_stdmelding ms"
                        + " WHERE mld_stdmelding_key = " + mld_opdr.stdm_key;
                    var oRs = Oracle.Execute(sql);
                    var autoorder = oRs("mld_stdmelding_autoorder").value == 1;

                    var mut_datum = new Date();
                    if (txt_mut_datum && mld_opdr.typeopdr_afmeldmarge>0)
                    {
                        var mut_datum = XMLtoJsDate(txt_mut_datum);
                        var maxmarge = new Date();
                        maxmarge.setDate(maxmarge.getDate() - mld_opdr.typeopdr_afmeldmarge);
                        if (mut_datum < maxmarge)
                            mut_datum = new Date(); // te lang geleden
                    }


                    // Dit zijn de wijzigingen, die voeren we alleen uit bij een geldige statuswijziging
                    // of geen statuswijziging
                    if (opdropmerking != null)
                    {
                        // opmerking bij de opdracht
                        var new_opm = opdropmerking;
                        sql = "SELECT mld_opdr_opmerking"
                            + "  FROM mld_opdr"
                            + " WHERE mld_opdr_key = " + opdr_key;
                        oRs = Oracle.Execute(sql);
                        // in geval van auto-order opdracht wordt de opmerking in de opdracht overschreven
                        // de complete backoffice wordt op dat moment beheerd door de soap gekoppelde partij.
                        // dit is te overrullen met de optie appendRemark. Als deze -1 is dan is de waarde niet
                        // gezet. Ander wordt deze hard gezet.
                        appendRemark = oRs("mld_opdr_opmerking").Value != null && ((!autoorder && appendRemark == -1) || appendRemark == 1);
                        if (appendRemark == 1) {
                            new_opm = oRs("mld_opdr_opmerking").Value + "\n" + new_opm;
                        }
                        opdr_fields.push({ dbs: "mld_opdr_opmerking",  typ: "varchar", val: new_opm,        track: L("lcl_mld_inf_Opmerking"), len: 4000 });

                        // opmerking bij de melding
                        var new_mld_opm = opdropmerking;
                        sql = "SELECT mld_melding_opmerking"
                            + "  FROM mld_melding"
                            + " WHERE mld_melding_key = " + mld_opdr.mld_key;
                        oRs = Oracle.Execute(sql);
                        appendRemark = oRs("mld_melding_opmerking").Value != null && ((!autoorder && appendRemark == -1) || appendRemark == 1);
                        if (appendRemark == 1) {
                            new_mld_opm = oRs("mld_melding_opmerking").Value + "\n" + new_mld_opm;
                        }
                        mld_fields.push({ dbs: "mld_melding_opmerking",  typ: "varchar", val: new_mld_opm,        track: L("lcl_mld_inf_Opmerking"), len: 4000 });

                    }

                    if (opdrkosten != null)
                        opdr_fields.push({ dbs: "mld_opdr_kosten",     typ: "float",   val: opdrkosten,     track: L("lcl_total_cost") });
                    if (opdrgereed != null) {
                        var opdrgereeddate = XMLtoJsDate(opdrgereed);
                        opdr_fields.push({ dbs: "mld_opdr_einddatum",  typ: "date",    val: opdrgereeddate, track: L("lcl_opdr_enddate") });
                        mld_fields.push({ dbs: "mld_melding_einddatum",  typ: "date",    val: opdrgereeddate, track: L("lcl_mld_enddate") });
                    }
                    // We weten nu de updates, straks voeren we deze pas uit
                    // Eerst de eventuele statuswijzigingen
                    var newstatus = -1;
                    if (opdrstatus != null) {
                        // Er is dus wel een status meegegeven
                        switch (opdrstatus) {
                            case 'ORDACP' :
                                if (this_opdr.canAccept) {
                                    if (oldstatus == 5) {
                                        newstatus = 8;
                                    } else {
                                        resultcode = 2;
                                        resulttekst = "Invalid status change";
                                    }
                                } else {
                                    resultcode = 4;
                                    resulttekst = "Not authorized for ORDACP";
                                }
                                break;
                            case 'ORDCAN' :
                                if (this_opdr.canCancel) {
                                    if (oldstatus == 5 || oldstatus == 8) {
                                        newstatus = 1;
                                    } else {
                                        resultcode = 2;
                                        resulttekst = "Invalid status change";
                                    }
                                } else {
                                    resultcode = 4;
                                    resulttekst = "Not authorized for ORDCAN";
                                }
                                break;
                            case 'ORDAFM' :
                                 if (this_opdr.canClose) {
                                    if (oldstatus == 5 || oldstatus == 8 ) {
                                        newstatus = 6;
                                    } else {
                                        resultcode = 2;
                                        resulttekst = "Invalid status change";
                                    }
                                } else {
                                    resultcode = 4;
                                    resulttekst = "Not authorized for ORDAFM";
                                }
                                break;
                            case 'ORDAFR' :
                                if (this_opdr.canFinish) {
                                    if (oldstatus == 6 ) {
                                        newstatus = 9;
                                    } else {
                                        resultcode = 2;
                                        resulttekst = "Invalid status change";
                                    }
                                } else {
                                    resultcode = 4;
                                    resulttekst = "Not authorized for ORDAFR";
                                }
                                break;
                            default:
                                resultcode = 3;
                                resulttekst = "Invalid status";
                        }  // switch
                    }

                    if (resultcode == -1) {  // nog steeds geen fouten
                        // Construct the update
                        if (this_opdr.canChange)
                        {
                            if (opdr_fields.length>0)
                            {
                                var mldUpd = buildTrackingUpdate("mld_opdr", "mld_opdr_key = " + opdr_key, opdr_fields);
                                Oracle.Execute(mldUpd.sql);
                                mld.trackopdrachtupdate(opdr_key, L("lcl_ord_is_updatedbysoap") + "\n" + mldUpd.trackarray.join("\n"));
                                if (mut_datum) // Antidateren voor SLA rapportages.
                                {
                                    var sql = "BEGIN fac.backtrackaction('ORDUPD', " + opdr_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;"
                                    Oracle.Execute(sql);
                                }
                            }
                        }

                        var this_mld = mld.func_enabled_melding(mld_opdr.mld_key);
                        // mag ik de melding ook aanpassen?
                        if (this_mld.canChange && autoorder)
                        {
                            if (mld_fields.length>0)
                            {
                                var mldUpd = buildTrackingUpdate("mld_melding", "mld_melding_key = " + mld_opdr.mld_key, mld_fields);
                                Oracle.Execute(mldUpd.sql);
                                mld.trackmeldingupdate(mld_opdr.mld_key, L("lcl_ord_is_updatedbysoap") + "\n" + mldUpd.trackarray.join("\n"));
                                if (mut_datum) // Antidateren voor SLA rapportages.
                                {
                                    var sql = "BEGIN fac.backtrackaction('MLDUPD', " + mld_opdr.mld_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;"
                                    Oracle.Execute(sql);
                                }
                            }
                        }

                        //Response.Write("lengte:"+ opdrkenmerken.length);
                        for (j=0; j < opdrkenmerken.length; j++)
                        {
                          var kenmerk_naam = opdrkenmerken[j].getAttribute("naam");
                          var kenmerk_waarde = opdrkenmerken[j].childNodes[0].nodeValue;
                          //Response.Write(kenmerk_naam);
                          //Response.Write(kenmerk_waarde);
                          ksql = "SELECT k.mld_kenmerk_key, sk.mld_srtkenmerk_kenmerktype, sk.mld_srtkenmerk_lengte "
                               + "  FROM mld_kenmerk k, mld_srtkenmerk sk "
                               + " WHERE k.mld_typeopdr_key = " + topdr_key
                               + "   AND k.mld_srtkenmerk_key = sk.mld_srtkenmerk_key "
                               + "   AND sk.mld_srtkenmerk_upper = " + safe.quoted_sql_upper(kenmerk_naam);
                          var oRs = Oracle.Execute(ksql);

                          if (!oRs.eof)
                          {
                            var kenmerk_key = oRs("mld_kenmerk_key").value;
                            var kenmerk_type = oRs("mld_srtkenmerk_kenmerktype").value;
                            var kenmerk_lengte = oRs("mld_srtkenmerk_lengte").value;

                            ksql = "SELECT ko.mld_kenmerkopdr_key "
                                 + "  FROM mld_kenmerkopdr ko "
                                 + " WHERE ko.mld_opdr_key =  " + opdr_key
                                 + "   AND ko.mld_kenmerk_key = " + kenmerk_key;
                            var oRs = Oracle.Execute(ksql);

                            if (kenmerk_type = 'C')
                            {
                              // we ondersteunen alleen nog maar karakter velden.
                              if (!oRs.eof)
                              {
                                var kenmerkopdr_key = oRs("mld_kenmerkopdr_key").value;
                                ksql = "UPDATE mld_kenmerkopdr SET mld_kenmerkopdr_waarde = " + safe.quoted_sql(kenmerk_waarde) + " WHERE mld_kenmerkopdr_key = " + kenmerkopdr_key;
                              }
                              else
                              {
                                ksql = "INSERT INTO mld_kenmerkopdr (mld_kenmerk_key, mld_opdr_key, mld_kenmerkopdr_waarde) "
                                     + "VALUES (" + kenmerk_key + ", " + opdr_key + ", " + safe.quoted_sql(kenmerk_waarde) + ")";
                              }
                              Oracle.Execute(ksql);
                            }
                          }
                        }

                        if (newstatus != -1)
                        {
                            mld.setopdrachtstatus(opdr_key, newstatus);
                            // Hier terugchecken van de status
                            tsql = "SELECT mld_statusopdr_key FROM mld_opdr"
                                 + " WHERE mld_opdr_key="+ opdr_key;
                            oRs = Oracle.Execute(tsql);
                            if (oRs("mld_statusopdr_key").value == newstatus)
                            {
                                resulttekst = "Status set to "+opdrstatus;
                                if (mut_datum && opdrstatus) // Tracking antidateren voor SLA rapportages.
                                {  // 'Toevallig' loopt opdrstatus 1-op-1 met onze trackingcodes
                                    var sql = "BEGIN fac.backtrackaction("+safe.quoted_sql(opdrstatus)+", " + opdr_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;"
                                    Oracle.Execute(sql); // Statuswijzigingen wel even tracken
                                    var txt = { "ORDAFM": L("lcl_ord_is_ordafm"),
                                                "ORDACP": L("lcl_ord_is_ordacp"),
                                                "ORDAFR": L("lcl_ord_is_ordafr")
                                              }[opdrstatus];
                                    mld.trackopdrachtupdate(opdr_key, L("lcl_ord_is_ordupd") + "\n" + txt + L("lcl_trackto") + toDateTimeString(mut_datum));
                                }



                                // Zijn er nog lopende opdrachten
                                tsql = "SELECT COUNT ( * ) lopend FROM  mld_opdr"
                                     + " WHERE mld_melding_key = " + mldkey
                                     + " AND mld_statusopdr_key NOT IN (1, 2, 6, 7, 9)"; // (1=afgewezen, 2=niet akkoord, 6=afgemeld, 7=verwerkt en 9=afgerond)
                                oRs = Oracle.Execute(tsql);

                                if (oRs("lopend").value == 0)
                                { // Er zijn alleen opdrachten met status 1 (Afgewezen) of 6/9 (Afgemeld/Afgerond)
                                  // Check of setting bij opdrachttype automatisch sluiten ALTIJD (= 2) toestaat.
                                  tsql = "SELECT mld_typeopdr_sluitmelding FROM mld_typeopdr"
                                       + " WHERE mld_typeopdr_key = " + topdr_key;
                                  var oRs = Oracle.Execute(tsql);

                                  // Afhankelijk van sluitmelding nu melding status zetten (0=nooit, 1=vragen en 2=altijd)
                                  if (  (oRs("mld_typeopdr_sluitmelding").value == 2 || oRs("mld_typeopdr_sluitmelding").value == 1)
                                           && this_mld.canClose
                                           && opdrstatus != 'ORDCAN') {
                                    mld.setmeldingstatus (mldkey, 5); // Afgemeld
                                    var sql = "BEGIN fac.backtrackaction('MLDAFM', " + mldkey + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;"
                                    Oracle.Execute(sql); // Statuswijzigingen wel even tracken
                                    mld.trackmeldingupdate(mldkey, L("lcl_mld_is_mldupd") + "\n" + L("lcl_mld_is_mldafm") + L("lcl_trackto") + toDateTimeString(mut_datum));
                                  }
                                  else
                                    // Dan zetten we de Melding hier terug naar Geaccepteerd indien die Uitgegeven was
                                    // Zodat die bij de FO weer onder Inbehandeling valt.
                                    mld.setmeldingstatus (mldkey, 4); // Geaccepteerd
                                }
                                // else status van de melding niet aanpassen.
                                resultcode = 0;
                            } else {
                                resultcode = 1;
                                resulttekst = "Status not set to "+opdrstatus+" (is "+oRs("mld_statusopdr_key").value+")";
                            }
                        }
                    }
                }
                // Ik heb gedaan wat ik moest en mocht doen voor deze opdracht
            }  // end geldige opdrachtkey

        }  // end geldige opdrid

        var binfo = {
                     returncode: resultcode,
                     returntekst: resulttekst,
                     executed:sql,   // debug
                     datum: nowtxt
                   }

        var FCLTBody = xmlResp.createElement("opdracht");   // type=response
        FCLTBody.setAttribute('type', 'response');
        FCLTBody.setAttribute('key', opdrid);
        for (param in binfo)
        {
            var FCLTdata = xmlResp.createElement(param);
            FCLTdata.appendChild(xmlResp.createTextNode(binfo[param]));
            FCLTBody.appendChild(FCLTdata);
        }

        FCLTElement.appendChild(FCLTBody);
    } // end for
    // Alle nodes zijn behandeld.

    xmlResp.appendChild(FCLTElement);

    Response.ContentType = "text/xml";
    Response.Write(xmlResp.xml)
%>