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

     File:              api_mld_soap.asp
     Description:       API voor mld-soap berichten
                        Interpreteert melding-bericht zodanig dat een melding wordt
                        aangemaakt.

     Parameters:        Een xml
     Status:
     Context:
     Notes:
*/
    DOCTYPE_Disable = 1;
    THIS_FILE = "appl/api/api_mldsoap.asp";
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/xml_converter.inc" -->
<!-- #include file="../Shared/save2db.inc" -->
<!-- #include file="../Shared/flexfiles.inc" -->
<!-- #include file="../Shared/upload.inc" -->
<!-- #include file="../api/api.inc" -->
<!-- #include file="../mld/mld.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 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 + "_IN");

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 meldingenloop (mochten er ooit nog anderen gaan volgen).
var meldingen = xmlReq.getElementsByTagName("melding");
for (i = 0; i < meldingen.length; i++)
{
  // Lees per node de (optionele) tags en waarden.
  var fields = []; // Bij te werken velden.
  var ext_id        = meldingen[i].getAttribute("key");
  var meldaction    = meldingen[i].getAttribute("type").toLowerCase();
  var melddatum     = XMLval(meldingen[i], "datum");
  var einddatum     = XMLval(meldingen[i], "einddatum");
  //var melderemail   = XMLval(meldingen[i], "melder");                   // Unsupported yet
  var stdmld_key    = parseInt(XMLval(meldingen[i], "stdmelding"), 10); // Numeriek
  var stdmld_sla    = -1;   // Normale uitvoertijd (prio door melder nog unsupported)
  //var meldprio      = XMLval(meldingen[i], "prioriteit");               // Unsupported yet
  //var meldobj_id    = XMLval(meldingen[i], "object");                   // Unsupported yet
  var meldloc       = XMLval(meldingen[i], "locatiecode");
  var meldgeb       = XMLval(meldingen[i], "gebouwcode");
  var meldver       = XMLval(meldingen[i], "verdiepingcode");
  var meldrnr       = XMLval(meldingen[i], "ruimtecode");
  var locatie_key   = -1;   // Bepaald op basis van meldloc
  var plaats_key    = -1;   // Bepaald op basis van meldgeb/meldver/meldrnr
  var meld_oms      = XMLval(meldingen[i], "omschrijving");
  //var mldkenmerken  = (meldingen[i].getElementsByTagName("kenmerk"))[0].childNodes[0].nodeValue; // Unsupported yet
  var mldkenmerken  = meldingen[i].getElementsByTagName("kenmerk");
  var mld_key       = -1;   // Bepaald na insert

  user.checkAutorisation("WEB_MLDUSE"); // Dit is nog ongeacht de melding

  if (ext_id == null)
  {
    resultcode = 1;
    resulttekst = "Undefined external ID (key)";
  }
  else if (meldaction != 'insert')
  {
    resultcode = 2;
    resulttekst = "Undefined operation (type)";
  }
  else
  {
    tsql = "SELECT sm.mld_stdmelding_t_uitvoertijd.tijdsduur tijdsduur"
         + "     , sm.mld_stdmelding_t_uitvoertijd.eenheid eenheid"
         + "  FROM mld_stdmelding sm"
         + " WHERE sm.mld_stdmelding_key = " + stdmld_key
         + "   AND sm.mld_stdmelding_verwijder IS NULL";
    var oRs = Oracle.Execute(tsql);
    if (oRs.eof)
    {
      resultcode = 3;
      resulttekst = "Undefined stdmelding";
    }
    else
    { // Hier heb ik een geldige mld_stdmelding_key.
      stdmld_sla_tijdsduur = oRs("tijdsduur").value;
      stdmld_sla_eenheid = oRs("eenheid").value;

      fields.push({ dbs: "mld_stdmelding_key", typ: "key", val: stdmld_key });
      fields.push({ dbs: "mld_melding_t_uitvoertijd.tijdsduur", typ: "number",  val: stdmld_sla_tijdsduur, obj: "MLD_T_UITVOERTIJD" });
      fields.push({ dbs: "mld_melding_t_uitvoertijd.eenheid",   typ: "varchar", val: stdmld_sla_eenheid,   obj: "MLD_T_UITVOERTIJD" });
      if (melddatum != null)
      {
        try
        {
          var meldaanmaakdate = XMLtoJsDate(melddatum);
          fields.push({ dbs: "mld_melding_datum", typ: "datetime", val: meldaanmaakdate });
        }
        catch (e)
        { // Verkeerde datum-formaat, volgens spec. dan now gebruiken!
          __DoLog("Formaat ontvangen XML-datum incorrect: "+ melddatum, "#00FF00");
          meldaanmaakdate = now;
          fields.push({ dbs: "mld_melding_datum", typ: "datetime", val: meldaanmaakdate });
        }
      }
      else
      {
        fields.push({ dbs: "mld_melding_datum", typ: "datetime", val: now });
      }
      // De einddatum is de meegegeven einddatum, maar als die niet wordt meegegeven is het
      // gewoon enddate_std en dat regelt de trigger wel, dus DAN MOET IK HEM NIET MEEGEVEN
      if (einddatum != null)
      {
        try
        {
          var meldeinddate = XMLtoJsDate(einddatum);
          if (meldeinddate > meldaanmaakdate)
          {
            fields.push({ dbs: "mld_melding_einddatum", typ: "datetime", val: meldeinddate });
          }
          else
          {
            // Ontvangen XML-einddatum voor begindatum, dan later volgens SLA zetten!
            __DoLog("Ontvangen XML-einddatum voor begindatum: "+ einddatum, "#00FF00");
          }
        }
        catch (e)
        {
          // Verkeerde datum-formaat, dan later volgens SLA zetten!
          __DoLog("Formaat ontvangen XML-einddatum incorrect: "+ einddatum, "#00FF00");
        }
      }

      tsql = "SELECT alg_locatie_key  "
          + " FROM alg_v_aanweziglocatie"
          + " WHERE alg_locatie_code="+ safe.quoted_sql(meldloc);
      var oRs = Oracle.Execute(tsql);
      if (!oRs.eof)
      {
        locatie_key = oRs("alg_locatie_key").value;
        fields.push({ dbs: "mld_alg_locatie_key", typ: "key", val: locatie_key });

        tsql = "SELECT alg_gebouw_key  "
            + " FROM alg_v_aanweziggebouw"
            + " WHERE alg_locatie_key ="+ locatie_key
            + " AND alg_gebouw_code="+ safe.quoted_sql(meldgeb);
        var oRs = Oracle.Execute(tsql);
        if (!oRs.eof)
        {
          plaats_key = oRs("alg_gebouw_key").value;

          tsql = "SELECT alg_verdieping_key  "
              + " FROM alg_v_aanwezigverdieping"
              + " WHERE alg_gebouw_key ="+ plaats_key
              + " AND alg_verdieping_code="+ safe.quoted_sql(meldver);
          var oRs = Oracle.Execute(tsql);
          if (!oRs.eof)
          {
            plaats_key = oRs("alg_verdieping_key").value;

            tsql = "SELECT alg_ruimte_key  "
                + " FROM alg_v_aanwezigruimte"
                + " WHERE alg_verdieping_key ="+ plaats_key
                + " AND alg_ruimte_nr="+ safe.quoted_sql(meldrnr);
            var oRs = Oracle.Execute(tsql);
            if (!oRs.eof) {
                plaats_key = oRs("alg_ruimte_key").value;
            }
          }
        }

        if (plaats_key != -1)
        {
          fields.push({ dbs: "mld_alg_onroerendgoed_keys", typ: "key", val: plaats_key });
        }
      }

      fields = fields.concat(
                      [ { dbs: "mld_melding_key",            typ: "key",     seq: "mld_s_mld_melding_key" },
                        { dbs: "mld_melding_module",         typ: "varchar", val: "MLD" },
                        { dbs: "mld_meldbron_key",           typ: "key",     val: 6 }, // system
                        { dbs: "mld_melding_omschrijving",   typ: "varchar", val: meld_oms, len: 4000 },
                        { dbs: "prs_kostenplaats_key",       typ: "key",     val: user.afdeling().prs_kostenplaats_key() },
                        { dbs: "prs_perslid_key",            typ: "key",     val: user_key },
                        { dbs: "prs_perslid_key_voor",       typ: "key",     val: user_key },
                        { dbs: "mld_melding_spoed",          typ: "key",     val: 3 }, // default (frontend) = 3
                        { dbs: "mld_melding_externnr",       typ: "varchar", val: ext_id, len: 30 }
                      ]);

      // We weten wat te inserten, nu nog uitvoeren; rechten voldoende afgedekt via MLDUSE-check hierboven?

      if (resultcode == -1)
      {  // nog steeds geen fouten
        var mldIns = buildInsert("mld_melding", fields, { noValidateToken: true });
        mld_key = mldIns.sequences["mld_melding_key"];

        sql = mldIns.sql;
        oRs = Oracle.Execute(sql);

        // Zetten van de status op ingevoerd en afhandelen van de tracking.
        mld.setmeldingstatus(mld_key, 2); // Zorgt ook voor tracking & daarmee notificatie.

        // Eventuele (gewijzigde) objecten zijn nu ook opgeslagen. Nu kan de definitieve mld_melding.mld_melding_einddatum_std bepaald en gezet worden.
        //mld.updatestdeinddatum(mld_key); // Unsupported yet. So update of mld_melding_einddatum_std not needed yet.

        // De kenmerken.
        for (j=0; j < mldkenmerken.length; j++)
        {
          var kenmerk_naam = mldkenmerken[j].getAttribute("naam");
          if (mldkenmerken[j].childNodes.length > 0)
            var kenmerk_waarde = mldkenmerken[j].childNodes[0].nodeValue;
          else
            var kenmerk_waarde = "";
          //Response.Write(kenmerk_naam);
          //Response.Write(kenmerk_waarde);
          // Zoek het kenmerk op naam terug
          ksql = "SELECT k.mld_kenmerk_key, sk.mld_srtkenmerk_kenmerktype, sk.mld_srtkenmerk_lengte "
               + "  FROM mld_kenmerk k"
               + "     , mld_srtkenmerk sk"
               + "     , mld_stdmelding s"
               + "     , mld_discipline d"
               + " WHERE s.mld_ins_discipline_key = d.ins_discipline_key"
               + "   AND k.mld_srtkenmerk_key = sk.mld_srtkenmerk_key "
               + "   AND k.mld_kenmerk_verwijder IS NULL "
               + "   AND sk.mld_srtkenmerk_upper = " + safe.quoted_sql_upper(kenmerk_naam)
               + "   AND s.mld_ins_discipline_key = d.ins_discipline_key"
               + "   AND s.mld_stdmelding_key = " + stdmld_key
               + "   AND ((k.mld_stdmelding_key = s.mld_stdmelding_key     AND k.mld_kenmerk_niveau = 'S')"
               + "     OR (k.mld_stdmelding_key = s.mld_ins_discipline_key AND k.mld_kenmerk_niveau = 'D')"
               + "     OR (k.mld_stdmelding_key = d.ins_srtdiscipline_key  AND k.mld_kenmerk_niveau = 'T'))";

          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 km.mld_kenmerkmelding_key "
                 + "  FROM mld_kenmerkmelding km "
                 + " WHERE km.mld_melding_key =  " + mld_key
                 + "   AND km.mld_kenmerk_key = " + kenmerk_key;
            var oRs = Oracle.Execute(ksql);

            switch (kenmerk_type)
            {
              case 'C':
              {
                // we ondersteunen alleen nog maar karakter velden.
                if (!oRs.eof)
                {
                  var kenmerkmelding_key = oRs("mld_kenmerkmelding_key").value;
                  ksql = "UPDATE mld_kenmerkmelding"
                       + "   SET mld_kenmerkmelding_waarde = " + safe.quoted_sql(kenmerk_waarde)
                       + " WHERE mld_kenmerkmelding_key = " + kenmerkmelding_key;
                }
                else
                {
                  ksql = "INSERT INTO mld_kenmerkmelding (mld_kenmerk_key, mld_melding_key, mld_kenmerkmelding_waarde) "
                       + "VALUES (" + kenmerk_key + ", " + mld_key + ", " + safe.quoted_sql(kenmerk_waarde) + ")";
                }
                Oracle.Execute(ksql);
                break;
              }
              case 'N':
              {
                // we ondersteunen alleen nog maar karakter velden.
                if (!oRs.eof)
                {
                  var kenmerkmelding_key = oRs("mld_kenmerkmelding_key").value;
                  ksql = "UPDATE mld_kenmerkmelding"
                       + "   SET mld_kenmerkmelding_waarde = " + safe.quoted_sql(kenmerk_waarde)
                       + " WHERE mld_kenmerkmelding_key = " + kenmerkmelding_key;
                }
                else
                {
                  ksql = "INSERT INTO mld_kenmerkmelding (mld_kenmerk_key, mld_melding_key, mld_kenmerkmelding_waarde) "
                       + "VALUES (" + kenmerk_key + ", " + mld_key + ", " + safe.quoted_sql(kenmerk_waarde) + ")";
                }
                Oracle.Execute(ksql);
                break;
              }
              case "M": // Folder met bijlagen
              {
                //Response.Write(kenmerk_naam);
                var bijlagen = mldkenmerken[j].getElementsByTagName("bijlage");
                var bi;
                for (bi = 0; bi < bijlagen.length; bi++)
                {
                  var Attachment = XMLval(bijlagen[bi], "attachment");
                  var Name = XMLval(bijlagen[bi], "name");
                  var Size = XMLval(bijlagen[bi], "size");
                  //Response.Write("Name: " + Name + " size: " + Size);
                  if (Attachment && Name && Size)
                  {
                    var SafeName = safe.filename(Name);
                    var params = flexProps("MLD", mld_key, String(kenmerk_key), "M");
                    if (!params.isAllowedName(SafeName))
                    {
                      __DoLog("Unsafe SOAP file '{0}' ignored.".format(SafeName), "#FFFF00");
                    }
                    else
                    {
                      __Log("Start saving: " + params.AttachPath + SafeName);
                      CreateFullPath(params.AttachPath);
                      encodedString2File(params.AttachPath + SafeName, Attachment, "bin.hex");
                      __Log("Done saving: " + params.AttachPath + SafeName);
                                                   }
                  }
                }
              }
            }
            oRs.Close();
          }
        }

        resultcode = 0; // Ik heb gedaan wat ik moest en mocht doen voor deze melding.
        // En nog maar even de aanname dat een extern systeem niet aan workflows/ktos doet?
      }
    } // end geldige stdmld_key
  } // end geldige ext_id

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

  var FCLTBody = xmlResp.createElement("melding");   // type=response
  FCLTBody.setAttribute('key', ext_id); // Let op: key van de aanroeper!
  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 melding-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)
}
%>
