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

     File:              api_besordsoap.asp
     Description:       API voor besord-soap berichten (bestelopdrachten)!
                        Interpreteert een bericht zodanig dat bestelopdracht wordt aangepast.
                        Dat is: qua status (bevesting/afwijzing en levering).
                        Als een status wordt meegegeven, dan is ook vereist dat dat een
                        geldige statusovergang is, anders wordt het hele bericht genegeerd.

     Parameters:        Een xml
     Status:
     Context:
     Notes:
*/
    DOCTYPE_Disable = 1;
    THIS_FILE = "appl/api/api_besordsoap.asp";
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/xml_converter.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../api/api.inc" -->
<!-- #include file="../bes/bes.inc" -->
<%
    // We sturen het antwoord in UTF-8.
    Session.Codepage = 65001;
    Response.Charset = 'utf-8';

    var API = new API_func();
    var tsql = "-";        // Voor tijdelijke statement(s)
    var sql = "-";         // De uiteindelijke update-sql
    var resultcode = -1;   /* Zolang deze -1 is, is het nog goed. Uiteindelijk eindigt het met 0 (als goed). */
    var resulttekst = "";
    var xmlReq = Server.CreateObject("MSXML2.DOMDocument.6.0");
    if (API.apidata.stylesheet)
    {
        var iXsl = Server.CreateObject("MSXML2.DOMDocument.6.0");
        if( ! iXsl.load(Server.MapPath(API.apidata.stylesheet)) )
        {
            API.error("Could not load XSL " + API.apidata.stylesheet + "\n" + iXsl.parseError.reason);
        }
        var inputXML = Server.CreateObject("MSXML2.DOMDocument.6.0");
        inputXML.load(Request);
        inputXML.transformNodeToObject(iXsl, xmlReq);
    }
    else
        xmlReq.load(Request);

    if (API.apidata.loglevel) __Log2File(xmlReq.xml, API.APIname + "_TUSSEN");

    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 elmHeader = 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]));
        elmHeader.appendChild(FCLTdata);
    }
    FCLTElement.appendChild(elmHeader);

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

    // Is hiermee voldoende gecheckt op rechten?
    var authparams = user.checkAutorisation("WEB_BESBOR");

    // Dit is de opdrachtenloop (mochten er ooit nog anderen gaan volgen).
    var opdrachten = xmlReq.getElementsByTagName("bestelopdracht");
    for (i=0; i < opdrachten.length; i++)
    {
        // Lees per node de (optionele) tags en waarden.
        var opdrid     = opdrachten[i].getAttribute("key");
        var opdraction = opdrachten[i].getAttribute("type").toLowerCase();
        var opdrstatus = XMLval(opdrachten[i], "status");
        var opdropm    = XMLval(opdrachten[i], "opmerking");
        var opdr_key   = -1;   // Bepaald op basis van opdrid
        var lev_key    = -1;
        var curstatus  = -1;

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

        if (isNaN (bes_key) || isNaN (opdrvolgnr))
        {
            resultcode = 2;
            resulttekst = "Invalid ID (key="+ opdrid +")";
        }
        else if (opdraction != "update")
        {
            resultcode = 2;
            resulttekst = "Invalid action (type="+ opdraction +")";
        }
        else
        {
            tsql = "SELECT bes_bestelopdr_key, prs_bedrijf_key, bes_bestelopdr_status "
                + " FROM bes_bestelopdr"
                + " WHERE bes_bestelopdr_id="+ safe.quoted_sql(opdrid);
            var oRs = Oracle.Execute(tsql);
            if (!oRs.eof)
            {
                opdr_key = oRs("bes_bestelopdr_key").value;
                lev_key = oRs("prs_bedrijf_key").value;
                curstatus = oRs("bes_bestelopdr_status").value;
            }

            if (opdr_key == -1)
            {
                resultcode = 3;
                resulttekst = "Unknown order";
            }
            else
            {   // Hier heb ik een geldige bes_bestelling_key + bes_bestelopdr_key.
                // Bericht bevat statuswijziging of artikellijst; nooit beide!
                if (opdrstatus != null)
                {   // Hier is dus een status meegegeven; evt. artikellijst wordt genegeerd!
                    switch (opdrstatus)
                    {
                        case 'BES2CO':
                        case 'BES2RE':
                            var opdropm_kolom = "BES_BESTELOPDR_OPMERKING";

                            // Check of vinkje bij leverancier "buitenom" bevestiging toestaat.
                            tsql = "SELECT prs_bedrijf_order_confirm "
                                + " FROM prs_bedrijf"
                                + " WHERE prs_bedrijf_key="+ lev_key;
                            oRs = Oracle.Execute(tsql);
                            if (oRs("prs_bedrijf_order_confirm").value == 1)
                            {
                                if (curstatus == 5) { // Ter bevestiging
                                    if (opdrstatus == 'BES2CO')
                                    {
                                        tsql = "BEGIN BES.acceptopdracht(" + opdr_key + ", " + user_key +", ''); END;";
                                        Oracle.Execute(tsql);
                                    }
                                    else
                                    {
                                        tsql = "BEGIN BES.rejectopdracht(" + opdr_key + ", " + user_key +", ''); END;";
                                        Oracle.Execute(tsql);
                                    }
                                }
                                else
                                {
                                    resultcode = 5;
                                    resulttekst = "Invalid status change";
                                }
                            }
                            else
                            {
                                resultcode = 4;
                                resulttekst = "Remote confirmation not enabled";
                            }
                            break;
                        case 'BES2AF':
                            var opdropm_kolom = "BES_BESTELOPDR_DELIVERY_OPMERK";

                            // Check of vinkje bij catalogus registratie van levering toestaat.
                            tsql = "SELECT MAX(dp.bes_disc_params_remoteconfirm) bes_disc_params_remoteconfirm "
                                + " FROM bes_bestelling_item bi, bes_srtdeel sd, bes_srtgroep sg, bes_disc_params dp"
                                + " WHERE bi.bes_bestelling_key="+ bes_key
                                + " AND bi.bes_srtdeel_key=sd.bes_srtdeel_key"
                                + " AND sd.bes_srtgroep_key=sg.bes_srtgroep_key"
                                + " AND sg.ins_discipline_key=dp.bes_ins_discipline_key";
                            oRs = Oracle.Execute(tsql);
                            if (oRs("bes_disc_params_remoteconfirm").value == 1)
                            {
                                if (curstatus == 4 )
                                {   // In bestelling
                                    // Zeg dat alles geleverd is wat besteld is.
                                    tsql = "UPDATE bes_bestelopdr_item "
                                        + " SET bes_bestelopdr_item_aantalontv=bes_bestelopdr_item_aantal"
                                        + "   , bes_bestelopdr_item_ontvangen=SYSDATE"
                                        + " WHERE bes_bestelopdr_key="+ opdr_key;
                                    Oracle.Execute(tsql);
                                    bes.updatebestelopdrstatus(opdr_key, user_key);

                                    // Sluit alle aanvraagregels af die nu geheel geleverd zijn.
                                    tsql = "UPDATE bes_bestelling_item "
                                        + " SET bes_bestelling_item_aantalontv = bes_bestelling_item_aantal"
                                        + " WHERE bes_bestelling_item_key IN"
                                        + " (SELECT bi.bes_bestelling_item_key "
                                        + "  FROM bes_bestelling b, bes_bestelling_item bi, bes_bestelopdr_item boi"
                                        + "  WHERE b.bes_bestelling_key="+ bes_key
                                        + "  AND b.bes_bestelling_status=5" // Besteld
                                        + "  AND b.bes_bestelling_key=bi.bes_bestelling_key"
                                        + "  AND bi.bes_bestelopdr_item_key=boi.bes_bestelopdr_item_key"
                                        + "  AND boi.bes_bestelopdr_key="+ opdr_key
                                        + "  AND boi.bes_bestelopdr_item_aantal=boi.bes_bestelopdr_item_aantalontv)";
                                    Oracle.Execute(tsql);
                                    bes.updatebestellingstatus (bes_key, user_key);
                                }
                                else
                                {
                                    resultcode = 5;
                                    resulttekst = "Invalid status change";
                                }
                            }
                            else
                            {
                                resultcode = 4;
                                resulttekst = "Remote delivery not enabled";
                            }
                            break;
                        default:
                            resultcode = 2;
                            resulttekst = "Invalid status";
                    } // switch
                }
                else
                {   // Hier is dus een artikellijst meegegeven (prijswijzigingen, aantallen en/of alleen opmerking)!
                    var artikelen = opdrachten[i].getElementsByTagName("artikel");
                    if (artikelen.length > 0)
                    {   // Loop door artikelen.
                        if (curstatus == 4 )
                        {   // In bestelling; alleen in deze toestand mogen - via API - artikelen worden bijgewerkt!
                            var opdropm_kolom = "BES_BESTELOPDR_DELIVERY_OPMERK";

                            for (i=0; i < artikelen.length && resultcode == -1; i++)
                            {   // Lees per node weer de tags en waarden.
                                var artikelnr = artikelen[i].getAttribute("nummer");
                                var newprijs = XMLval(artikelen[i], "prijs");
                                var newprijsval = parseFloat(XMLval(artikelen[i], "prijs"));
                                var newink = XMLval(artikelen[i], "inkprijs");
                                var newinkval = parseFloat(XMLval(artikelen[i], "inkprijs"));
                                var newbruto = XMLval(artikelen[i], "brutoprijs");
                                var newbrutoval = parseFloat(XMLval(artikelen[i], "brutoprijs"));
                                var newontv = XMLval(artikelen[i], "aantalontv");
                                var newontvval = parseInt(XMLval(artikelen[i], "aantalontv"), 10);

                                // Bepaal item-keys plus huidige aantallen besteld/geleverd voor artikel.
                                tsql = "SELECT bi.bes_bestelling_item_key, bi.bes_bestelopdr_item_key, "
                                    + "        boi.bes_bestelopdr_item_aantal curaant, "
                                    + "        COALESCE(boi.bes_bestelopdr_item_aantalontv, 0) curontv "
                                    + " FROM bes_bestelopdr_item boi, bes_bestelling_item bi, bes_srtdeel sd"
                                    + " WHERE boi.bes_bestelopdr_key="+ opdr_key
                                    + " AND boi.bes_bestelopdr_item_key=bi.bes_bestelopdr_item_key"
                                    + " AND bi.bes_srtdeel_key=sd.bes_srtdeel_key"
                                    + " AND sd.bes_srtdeel_nr="+ safe.quoted_sql(artikelnr);
                                oRs = Oracle.Execute(tsql);
                                if (!oRs.eof)
                                {
                                    var bi_key = oRs("bes_bestelling_item_key").value;
                                    var boi_key = oRs("bes_bestelopdr_item_key").value;
                                    var curaant = oRs("curaant").value;
                                    var curontv = oRs("curontv").value;

                                    if ((newprijs && (isNaN (newprijsval) || newprijsval < 0)) ||
                                        (newink && (isNaN (newinkval) || newinkval < 0)) ||
                                        (newbruto && (isNaN (newbrutoval) || newbrutoval < 0)))
                                    {
                                        resultcode = 8;
                                        resulttekst = "Invalid price(s)";
                                    }
                                    else if (newprijs || newink || newbruto)
                                    {   // Werk de eventuele prijzen bij; zover meegegeven zijn die geldig.
                                        // In de bestelaanvraag!
                                        tsql = "UPDATE bes_bestelling_item "
                                            + " SET bes_srtdeel_key=bes_srtdeel_key"
                                            + (newprijs ? ", bes_bestelling_item_prijs="+ newprijsval : "")
                                            + (newink ?   ", bes_bestelling_item_inkprijs="+ newinkval : "")
                                            + (newbruto ? ", bes_bestelling_item_brutoprijs="+ newbrutoval : "")
                                            + " WHERE bes_bestelling_item_key="+ bi_key;
                                        Oracle.Execute(tsql);
                                        shared.trackaction("BESUPD", bes_key, L("lcl_bes_is_besupdtrackprice").format(S("bes_bestelling_prefix") + bes_key, safe.curr(newprijsval)));

                                        // En de bestelopdracht!
                                        tsql = "UPDATE bes_bestelopdr_item "
                                            + " SET bes_bestelopdr_item_posnr=bes_bestelopdr_item_posnr"
                                            + (newprijs ? ", bes_bestelopdr_item_prijs="+ newprijsval : "")
                                            + (newink ?   ", bes_bestelopdr_item_inkprijs="+ newinkval : "")
                                            + (newbruto ? ", bes_bestelopdr_item_brutoprijs="+ newbrutoval : "")
                                            + " WHERE bes_bestelopdr_item_key="+ boi_key;
                                        Oracle.Execute(tsql);
                                        shared.trackaction("BES2UP", opdr_key, L("lcl_bes_is_bes2uptrackprice").format(S("bes_bestelopdr_prefix") + opdrid, safe.curr(newprijsval)));
                                    }

                                    if (newontv && resultcode == -1)
                                    {   // Nieuw aantal ontvangen en nog steeds geen fouten.
                                        // Check of vinkje bij catalogus registratie van levering toestaat.
                                        tsql = "SELECT MAX(dp.bes_disc_params_remoteconfirm) bes_disc_params_remoteconfirm "
                                            + " FROM bes_bestelling_item bi, bes_srtdeel sd, bes_srtgroep sg, bes_disc_params dp"
                                            + " WHERE bi.bes_bestelling_key="+ bes_key
                                            + " AND bi.bes_srtdeel_key=sd.bes_srtdeel_key"
                                            + " AND sd.bes_srtgroep_key=sg.bes_srtgroep_key"
                                            + " AND sg.ins_discipline_key=dp.bes_ins_discipline_key";
                                        oRs = Oracle.Execute(tsql);
                                        if (oRs("bes_disc_params_remoteconfirm").value == 1)
                                        {   // Correcties of (deel)registratie retouren met negatieve <aantalontv> niet toegestaan; wel via BES2AF!
                                            if (isNaN (newontvval) || newontvval < 0 || (curontv + newontvval) > curaant)
                                            {
                                                resultcode = 8;
                                                resulttekst = "Invalid delivery count";
                                            }
                                            else
                                            {   // Werk het geleverde aantal bij.
                                                tsql = "UPDATE bes_bestelopdr_item "
                                                    + " SET bes_bestelopdr_item_ontvangen=SYSDATE"
                                                    + "   , bes_bestelopdr_item_aantalontv=COALESCE(bes_bestelopdr_item_aantalontv,0)+"+ newontvval
                                                    + " WHERE bes_bestelopdr_item_key="+ boi_key;
                                                Oracle.Execute(tsql);
                                                bes.updatebestelopdrstatus(opdr_key, user_key);
                                            }
                                        }
                                        else
                                        {
                                            resultcode = 4;
                                            resulttekst = "Remote delivery not enabled";
                                        }
                                    }
                                }
                                else
                                {
                                    resultcode = 7;
                                    resulttekst = "Unknown article number";
                                }
                            }

                            // Sluit alle aanvraagregels af die - mogelijk - nu geheel geleverd zijn.
                            tsql = "UPDATE bes_bestelling_item "
                                + " SET bes_bestelling_item_aantalontv = bes_bestelling_item_aantal"
                                + " WHERE bes_bestelling_item_key IN"
                                + " (SELECT bi.bes_bestelling_item_key "
                                + "  FROM bes_bestelling b, bes_bestelling_item bi, bes_bestelopdr_item boi"
                                + "  WHERE b.bes_bestelling_key="+ bes_key
                                + "  AND b.bes_bestelling_status=5" // Besteld
                                + "  AND b.bes_bestelling_key=bi.bes_bestelling_key"
                                + "  AND bi.bes_bestelopdr_item_key=boi.bes_bestelopdr_item_key"
                                + "  AND boi.bes_bestelopdr_key="+ opdr_key
                                + "  AND boi.bes_bestelopdr_item_aantal=boi.bes_bestelopdr_item_aantalontv)";
                            Oracle.Execute(tsql);
                            bes.updatebestellingstatus (bes_key, user_key);
                        }
                        else
                        {
                            resultcode = 6;
                            resulttekst = "Invalid update timing";
                        }
                    }
                    else
                    {   // Raar, alleen opmerking, heeft dan vast niets met levering te maken?
                        var opdropm_kolom = "BES_BESTELOPDR_OPMERKING";
                    }
                }

                // Dit zijn de overige wijzigingen (alleen opmerking), die voeren we alleen uit
                // bij geen of een geldige statuswijziging.
                if (resultcode == -1)
                {   // Nog steeds geen fouten.
                    if (opdropm != null )
                    {
                        tsql = "UPDATE bes_bestelopdr "
                            + " SET "+ opdropm_kolom
                            + "=DECODE ("+ opdropm_kolom
                            + "       , NULL, "+ safe.quoted_sql(opdropm)
                            + "       , SUBSTR ("+ opdropm_kolom +"||CHR(13)||CHR(10)||"+ safe.quoted_sql(opdropm) +", 1, 4000))"
                            + " WHERE bes_bestelopdr_key="+ opdr_key;
                        Oracle.Execute(tsql);
                    }

                    resultcode = 0; // Ik heb gedaan wat ik moest en mocht doen voor deze bestelopdracht.
                }
            } // end geldige opdrachtkey
            oRs.Close();
        } // end geldige opdrid

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

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

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

    xmlResp.appendChild(FCLTElement);

    if (API.apidata.stylesheet)
    {
        // Niet super efficient dat we eerst naar tekstuele xml gaan maar ach...
        STR2Stream(xmlResp.xml, API.apidata.stylesheet, Response, {});
    }
    else
    {
        Response.ContentType = "text/xml";
        Response.Write(xmlResp.xml)
    }
%>
