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

     File:              api_res_soap.asp
     Description:       API voor res-soap berichten
                        Interpreteert bericht zodanig dat er iets reserveringsachtig wordt
                        aangemaakt.

     Parameters:        Een xml
     Status:            Eerste implementatie in kader AAEN#25223 (tbv. TIBCO/Smart Signs)
     Context:
     Notes:
*/
    DOCTYPE_Disable = 1;
    THIS_FILE = "appl/api/api_ressoap.asp";
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/xml_converter.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../Shared/flexfiles.inc" -->
<!-- #include file="../api/api.inc" -->
<!-- #include file="../shared/kpl_ksrt_validate.inc" -->
<!-- #include file="../res/res.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 insert/update-sql

    var xmlReq = styledRequestXML(API);

    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

    // Dit is de reserveringenloop (mochten er ooit nog anderen gaan volgen).
    var reserveringen = xmlReq.getElementsByTagName("reservering");
    for (i=0; i < reserveringen.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) tags en waarden.
        var fields = []; // Bij te werken velden.
        var resid         = reserveringen[i].getAttribute("key"); // Bij type=update/delete
        var resaction     = reserveringen[i].getAttribute("type").toLowerCase();
        var ruimtekey     = parseInt(XMLval(reserveringen[i], "ruimtekey"), 10); // res_ruimte_key
        var van           = XMLval(reserveringen[i], "van");
        var tot           = XMLval(reserveringen[i], "tot");
        var res_oms       = XMLval(reserveringen[i], "omschrijving");
        var shown         = XMLval(reserveringen[i], "shown");
        //var reskenmerken = (reserveringen[i].getElementsByTagName("kenmerk")); // Unsupported yet

        if (resid == null) { // Voorkom problemen als key-attribuut ontbreekt!
          resid = '';
        }
        if (isNaN(ruimtekey) ) { // Voorkom problemen als ruimtekey ontbreekt!
          ruimtekey = -1;
        }
        var idarr = resid.split('/');
        var reservering_key   = parseInt(idarr[0], 10); // En anders bepaald bij insert!
        var rsv_ruimte_volgnr = parseInt(idarr[1], 10); // En anders 1 bij insert!
        var rsv_ruimte_key    = -1; // Bepalen we later bij insert/update/delete!

        user.checkAutorisation("WEB_RESFOF"); // Dit is nog ongeacht de reservering

        if (resaction == 'insert') {
          tsql = "  SELECT rad.res_discipline_key, rad.res_activiteit_key, rro.res_ruimte_opstel_key,"
              + "          COALESCE(rr.res_ruimte_begintijd, " + S("res_t1") + ") begintijd,"
              + "          COALESCE(rr.res_ruimte_eindtijd, " + S("res_t2") + ") eindtijd"
              + "     FROM res_ruimte_opstelling rro, res_ruimte rr, res_activiteitdiscipline rad,"
              + "          (SELECT * FROM res_activiteit ra1"
              + "            WHERE NOT EXISTS"
              + "                     (SELECT 1 FROM res_activiteit ra2"
              + "                       WHERE COALESCE (ra2.res_activiteit_volgnr, 999 + ra2.res_activiteit_key) <"
              + "                             COALESCE (ra1.res_activiteit_volgnr, 999 + ra1.res_activiteit_key))) ra"
              + "    WHERE rro.res_ruimte_key="+ruimtekey
              + "      AND rro.res_ruimte_key = rr.res_ruimte_key"
              + "      AND res_ruimte_verwijder IS NULL"
              + "      AND rr.res_discipline_key = rad.res_discipline_key"
              + "      AND rad.res_activiteit_key = ra.res_activiteit_key"
              + " ORDER BY rro.res_ruimte_opstel_default DESC NULLS LAST"; // die met '1' komt vooraan
          var oRs = Oracle.Execute(tsql);
          if (oRs.eof) {
            resultcode = 3;
            resulttekst = "Invalid/undefined ruimtekey";
          }
          else {
            // Hier heb ik een geldige res_ruimte_key en weet ik de discipline, default activiteit en default opstelling!
            var disc_key = oRs("res_discipline_key").value;
            var act_key = oRs("res_activiteit_key").value;
            var opstel_key = oRs("res_ruimte_opstel_key").value;

            if (van != null) {
              try {
                var vandate = XMLtoJsDate(van);
              }
              catch (e) {
                __DoLog("Formaat ontvangen XML-datum incorrect (van): "+van, "#00FF00");
                // Datum-formaat niet volgens spec.? Dan exit!
                resultcode = 4;
                resulttekst = "Invalid date format";
              }
            }
            else {
              __DoLog("Geen XML-datum ontvangen (van): ", "#00FF00");
              // Geen van-datum, dan exit!
              resultcode = 4;
              resulttekst = "Missing parameter(s)";
            }

            if (tot != null) {
              try {
                var totdate = XMLtoJsDate(tot);
              }
              catch (e) {
                __DoLog("Formaat ontvangen XML-datum incorrect (tot): "+tot, "#00FF00");
                // Datum-formaat niet volgens spec.? Dan exit!
                resultcode = 4;
                resulttekst = "Invalid date format";
              }
            }
            else {
              __DoLog("Geen XML-datum ontvangen (tot): ", "#00FF00");
              // Geen tot-datum, dan exit!
              resultcode = 4;
              resulttekst = "Missing parameter(s)";
            }

            if (res_oms == null) { // Geen/lege omschrijving wordt gezien als ongeplande reservering!
              res_oms = "Ongeplande reservering";
            }

            if (resultcode == -1) { // nog steeds geen fouten
              // Check van-dag = tot-dag = vandaag!
              if (1==0) {
                resultcode = 6;
                resulttekst = "Illegal reservering (date)";
              }
            }

            if (resultcode == -1) { // nog steeds geen fouten
              // Check van < tot en beide tegen openingstijden ruimte!
              var df = vandate.getHours() + vandate.getMinutes()/60;
              var dt = totdate.getHours() + totdate.getMinutes()/60;
              if (vandate > totdate ||
                  df < oRs("begintijd").value || df > oRs("eindtijd").value ||
                  dt < oRs("begintijd").value || dt > oRs("eindtijd").value) {
                resultcode = 6;
                resulttekst = "Illegal reservering (time)";
              }
            }

            if (resultcode == -1) { // nog steeds geen fouten
              // Combinatievalidatie ruimte discipline!
              if (!kpl_ksrt_validate(user.prs_kostenplaats_key(), null, disc_key)) {
                resultcode = 6;
                resulttekst = "Illegal reservering (cost)";
              }
            }

            if (resultcode == -1) { // nog steeds geen fouten
              // Feitelijke ad-hoc of ongeplande insert! Eerst ook altijd een res_reservering record aanmaken!
              var resfields = [ { dbs: "res_reservering_key",     typ: "key",      seq: "res_s_res_reservering_key" },
                                { dbs: "res_reservering_aanmaak", typ: "datetime", val: new Date() }
                              ];
              var resIns = buildInsert("res_reservering", resfields, { noValidateToken: true });
              reservering_key = resIns.sequences["res_reservering_key"];
              Oracle.Execute(resIns.sql);

              resid = reservering_key+"/1";

              fields.push({ dbs: "res_activiteit_key",            typ: "key",      val: act_key });
              fields.push({ dbs: "res_status_fo_key",             typ: "key",      val: 2 }); // definitief = 2???
              fields.push({ dbs: "res_ruimte_opstel_key",         typ: "key",      val: opstel_key });
              fields.push({ dbs: "res_rsv_ruimte_van",            typ: "datetime", val: vandate });
              fields.push({ dbs: "res_rsv_ruimte_tot",            typ: "datetime", val: totdate });
              fields.push({ dbs: "res_rsv_ruimte_bezoekers",      typ: "number",   val: 1 }); // altijd 1
              fields.push({ dbs: "prs_kostenplaats_key",          typ: "key",      val: user.prs_kostenplaats_key() });
              fields.push({ dbs: "res_rsv_ruimte_host_key",       typ: "key",      val: user_key });
              fields.push({ dbs: "res_rsv_ruimte_contact_key",    typ: "key",      val: user_key });
              fields.push({ dbs: "res_rsv_ruimte_omschrijving",   typ: "varchar",  val: res_oms, len: 4000 });

              fields = fields.concat(
                        [ { dbs: "res_rsv_ruimte_key",            typ: "key",      seq: "res_s_res_rsv_ruimte_key" },
                          { dbs: "res_reservering_key",           typ: "key",      val: reservering_key },
                          { dbs: "res_rsv_ruimte_volgnr",         typ: "number",   val: 1 }, // altijd 1
                          { dbs: "res_status_bo_key",             typ: "key",      val: 2 } // ingevoerd
                        ]);

              var resIns = buildInsert("res_rsv_ruimte", fields, { noValidateToken: true });
              rsv_ruimte_key = resIns.sequences["res_rsv_ruimte_key"];
              sql = "BEGIN "
                  + resIns.sql + ";"
                  + "res.set_ruimte_dirty (" + rsv_ruimte_key + "); " // Zelf dirty geworden?
                  + "END;";
              Oracle.Execute(sql);

              // RESNEW-tracking toevoegen!
              shared.trackaction("RESNEW", rsv_ruimte_key);

              resultcode = 0; // Ik heb gedaan wat ik moest en mocht doen voor deze reservering.
            }
          	oRs.Close();
          }
        }
        else if (resaction == 'update')
        {
          if (resid == '') {
            resultcode = 2;
            resulttekst = "Undefined reservering (key)";
          }
          else if (isNaN (reservering_key) || isNaN (rsv_ruimte_volgnr)) {
            resultcode = 2;
            resulttekst = "Invalid reservering (key) "+resid;
          }
          else {
            tsql = "SELECT res_rsv_ruimte_key, res_rsv_ruimte_van, res_rsv_ruimte_tot"
                + "   FROM res_v_aanwezigrsv_ruimte"
                + "  WHERE res_reservering_key="+reservering_key
                + "    AND res_rsv_ruimte_volgnr="+rsv_ruimte_volgnr
                + "    AND TRUNC(res_rsv_ruimte_van)>=TRUNC(SYSDATE)" // Alleen vandaag of in de toekomst???
                + "    AND 1=1"; // Niet dirty, niet verwijderd, ...???
            var oRs = Oracle.Execute(tsql);
            if (!oRs.eof) {
              // Hier heb ik een geldige res_rsv_ruimte_key.
              rsv_ruimte_key = oRs("res_rsv_ruimte_key").value;

          	  var this_res = res.func_enabled(rsv_ruimte_key); // Wat heb ik zoal aan rechten op deze specifieke reservering
          	  user.auth_required_or_abort(this_res.canChange);

          	  if (shown != null) { // Bij update optioneel
                // Feitelijke UPDATE shown.
                // Verder geen checks (Oracle fout als shown < 0 of shown > 999 niet afvangen???)!
                if (S("res_noshow_detailed") == 1) {
                  sql = "UPDATE res_rsv_ruimte"
                      + "    SET res_rsv_ruimte_bezoekers_shown="+parseInt(shown, 10)
                      + "  WHERE res_rsv_ruimte_key="+rsv_ruimte_key
                      + "    AND 1=1"; // Niet dirty, niet verwijderd, ...???
                  Oracle.Execute(sql);
                }
                else {
                  if (parseInt(shown, 10) == 0) {
                    sql = "UPDATE res_rsv_ruimte"
                        + "    SET res_rsv_ruimte_noshow = 1"
                        + "  WHERE res_rsv_ruimte_key="+rsv_ruimte_key
                        + "    AND 1=1"; // Niet dirty, niet verwijderd, ...???
                    Oracle.Execute(sql);
                  }
                }
                // RESNOS-tracking toevoegen!
                shared.trackaction("RESNOS", rsv_ruimte_key);
              }

              var oldvan = new Date(oRs("res_rsv_ruimte_van").Value);
              var oldtot = new Date(oRs("res_rsv_ruimte_tot").Value);
          	  if (tot != null) { // Bij update optioneel
                try {
                  var totdate = XMLtoJsDate(tot);
                }
                catch (e) {
                  __DoLog("Formaat ontvangen XML-datum incorrect (tot): "+tot, "#00FF00");
                  // Datum-formaat niet volgens spec.? Dan exit!
                  resultcode = 4;
                  resulttekst = "Invalid date format";
                }

                if (resultcode == -1) { // nog steeds geen fouten
                  // Check van-dag = tot-dag = vandaag!
                  if (1==0) {
                    resultcode = 6;
                    resulttekst = "Illegal update (tot-date)";
                  }
                }

                if (resultcode == -1) { // nog steeds geen fouten
                  // Check oldvan < tot (openingstijden ruimte niet afvangen???)!
                  if (oldvan > totdate) {
                    resultcode = 6;
                    resulttekst = "Illegal update (tot-time)";
                  }
                }

                if (resultcode == -1) { // nog steeds geen fouten
                  // Feitelijke UPDATE tot-tijd (tijd in minuten/seconden niet afvangen???)!
                  // Meerdaags op dit moment hieronder nog in UPDATE voorkomen.
                  sql = "UPDATE res_rsv_ruimte"
                      + "   SET res_rsv_ruimte_tot="+totdate.toSQL(true)
                      + " WHERE res_rsv_ruimte_key="+rsv_ruimte_key
                      + "   AND TRUNC(res_rsv_ruimte_tot)=TRUNC("+totdate.toSQL(true)+")"
                      + "   AND 1=1"; // Niet dirty, niet verwijderd, niet meerdaags, niet overlappend, ...???
                  Oracle.Execute(sql);

                  sql = "BEGIN "
                      + "res.set_ruimte_dirty (" + rsv_ruimte_key + "); " // Zelf dirty geworden?
                      + "res.set_ruimtes_clean (" + oldvan.toSQL() + "); " // Anderen clean geworden
                      + "res.follow_artikel (" + rsv_ruimte_key + ", " + oldvan.toSQL(true) + ", " + oldtot.toSQL(true) + "); " // catering mee verplaatsen
                      + "res.follow_deel (" + rsv_ruimte_key + ", " + oldvan.toSQL(true) + ", " + oldtot.toSQL(true) + "); " // objecten mee verplaatsen
                      + "res.follow_afspraak (" + rsv_ruimte_key + ", " + S("res_copy_to_bez") + "); " // bezoekers mee verplaatsen
                      + "END;";
                  Oracle.Execute(sql);

                  // TODO: Nog iets met parkeerplaatsen???

                  // RESUPD-tracking toevoegen!
                  shared.trackaction("RESUPD", rsv_ruimte_key);
                }
              }

              if (resultcode == -1) { // nog steeds geen fouten
                resultcode = 0; // Ik heb gedaan wat ik moest en mocht doen voor deze reservering.
              }
          	} else {
              resultcode = 5;
              resulttekst = "Not updatable reservering "+resid;
          	}
          	oRs.Close();
          }
        }
        else if (resaction == 'delete')
        {
          if (resid == '') {
            resultcode = 2;
            resulttekst = "Undefined reservering (key)";
          }
          else if (isNaN (reservering_key) || isNaN (rsv_ruimte_volgnr)) {
            resultcode = 2;
            resulttekst = "Invalid reservering (key) "+resid;
          }
          else {
            tsql = "SELECT r.res_rsv_ruimte_key"
                + "   FROM res_v_aanwezigrsv_ruimte r, fac_tracking t, fac_srtnotificatie sn"
                + "  WHERE r.res_reservering_key="+reservering_key
                + "    AND r.res_rsv_ruimte_volgnr="+rsv_ruimte_volgnr
                + "    AND TRUNC(r.res_rsv_ruimte_van)>=TRUNC(SYSDATE)" // Alleen vandaag of in de toekomst???
                + "    AND 1=1" // Niet dirty, niet verwijderd, geen voorzieningen, ...???
                + "    AND r.res_rsv_ruimte_key=t.fac_tracking_refkey"
                + "    AND t.fac_srtnotificatie_key=sn.fac_srtnotificatie_key"
                + "    AND sn.fac_srtnotificatie_code='RESNEW'"
                + "    AND t.prs_perslid_key="+user_key;
            var oRs = Oracle.Execute(tsql);
            if (!oRs.eof) {
              // Hier heb ik een geldige res_rsv_ruimte_key die kan/mag worden verwijderd!
              rsv_ruimte_key = oRs("res_rsv_ruimte_key").value;

          	  var this_res = res.func_enabled(rsv_ruimte_key); // Wat heb ik zoal aan rechten op deze specifieke reservering
          	  user.auth_required_or_abort(this_res.canDelete);

              // Feitelijke delete (voorlopig?) alleen toegestaan voor eerder via API aangemaakte ad-hoc/ongeplande reservering!
              sql = "UPDATE res_rsv_ruimte r"
                 + "    SET r.res_rsv_ruimte_verwijder=SYSDATE"
                 + "  WHERE r.res_rsv_ruimte_key="+rsv_ruimte_key;
              Oracle.Execute(sql);

              // TODO: Nog iets met anderen clean geworden???

              // RESDEL-tracking toevoegen (zonder opmerking???)!
              shared.trackaction("RESDEL", rsv_ruimte_key);

              resultcode = 0; // Ik heb gedaan wat ik moest en mocht doen voor deze reservering.
          	}
          	else {
              resultcode = 5;
              resulttekst = "Not deletable reservering "+resid;
          	}
          	oRs.Close();
          }
        }
        else {
          resultcode = 2;
          resulttekst = "Undefined operation (type)";
        }

        var binfo = {
                     returncode: resultcode,
                     returntekst: resulttekst,
                     // executed:sql, // debug
                     datum: nowtxt, // TODO: Beter ook xml-datum???
                     resid: resid
                    }

        var FCLTBody = xmlResp.createElement("reservering");   // type=response
        FCLTBody.setAttribute('key', resid);
        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 reservering-nodes zijn behandeld.

    xmlResp.appendChild(FCLTElement);

    Response.ContentType = "text/xml";
    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.Write(xmlResp.xml)
    }
%>
<% ASPPAGE_END(); %>
