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

     File:              API_plan_intern.asp
     Description:       API om in een intern (RES)planbord plan-voorstellen op te halen

     Parameters:        Een xml
     Status:
     Context:
     Notes:             Zie "z:\Project\Implementaties\Customers\MARX\DOC\POC Planbord via reserveringen\marx_plannen_jgl.docx"
                        voor een overzicht van de verschillende XML-stadia
*/
    DOCTYPE_Disable = 1;
    THIS_FILE = "appl/marx/api_plan_intern.asp";
%>
<!-- #include file="../../appl/Shared/common.inc" -->
<!-- #include file="../Shared/xml_converter.inc" -->
<!-- #include file="../api/api.inc" -->
<!-- #include file="../shared/putorders.inc" -->
<!-- #include file="../MARX/GetLatLng.inc" -->

<%
Session.Codepage = 65001;
Response.Charset = 'utf-8';

var API = new API_func();

/*
De inkomende XML is het ketenstandaard/DICO planningsrequest (BERICHT I) of planningsreactie (BERICHT II):
<?xml version="1.0" encoding="UTF-8"?>
<PlanningRequest xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.ketenstandaard.nl/planningsverzoek/SALES/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://www.ketenstandaard.nl/planningsverzoek/SALES/005 Planningsverzoek_SALES005.xsd">
  <PlanningRequestNumber>ABC123XYZ</PlanningRequestNumber>
  <MessageDate>2020-08-13</MessageDate>
  <MessageTime>12:34:56</MessageTime>
  <Duration>P0Y0M0DT2H30M</Duration>
  <NumberOfPlanningOptions>3</NumberOfPlanningOptions>
  <Buyer>
    <GLN>8713783669303</GLN>
  </Buyer>
  <Contractor>
    <GLN>8713783642016</GLN>
  </Contractor>
  <MaintenanceLocation>
    <Street>XXXXXXXXXXXXXXXXXXXXXXXXXX</Street>
    <HouseNumber>12</HouseNumber>
    <HouseLetter></HouseLetter>
    <HouseNumberSuffix></HouseNumberSuffix>
    <PostalCode>XXXX</PostalCode>
    <City>XXXXXXXXXXXXXXX</City>
  </MaintenanceLocation>
  <Competence>
    <CompetenceCode>ELE</CompetenceCode>
    <NumberOfResources>1</NumberOfResources>
  </Competence>
  <MaintenanceMoment>
    <EarliestExecutionDate>2020-08-17</EarliestExecutionDate>
    <LatestExecutionDate>2020-08-31</LatestExecutionDate>
    <TimeblocksPerWeekday>
      <Weekday>MON</Weekday>
      <Timeblock>
        <EarliestExecutionTime>09:00:00</EarliestExecutionTime>
        <LatestExecutionTime>12:00:00</LatestExecutionTime>
      </Timeblock>
      <Timeblock>
        <EarliestExecutionTime>13:00:00</EarliestExecutionTime>
        <LatestExecutionTime>16:00:00</LatestExecutionTime>
      </Timeblock>
    </TimeblocksPerWeekday>
    <TimeblocksPerWeekday>
      <Weekday>TUE</Weekday>
      <Timeblock>
        <EarliestExecutionTime>09:00:00</EarliestExecutionTime>
        <LatestExecutionTime>12:00:00</LatestExecutionTime>
      </Timeblock>
      <Timeblock>
        <EarliestExecutionTime>13:00:00</EarliestExecutionTime>
        <LatestExecutionTime>16:00:00</LatestExecutionTime>
      </Timeblock>      
    </TimeblocksPerWeekday>
    <Timeblock>
      <EarliestExecutionTime>09:00:00</EarliestExecutionTime>
      <LatestExecutionTime>12:00</LatestExecutionTime>
    </Timeblock>
    <Timeblock>
      <EarliestExecutionTime>13:00:00</EarliestExecutionTime>
      <LatestExecutionTime>16:00</LatestExecutionTime>
    </Timeblock>
  </MaintenanceMoment>
</PlanningRequest>

--> DOEL: Op ZOEK NAAR EEN GESCHIKT TIJDSBLOK 'Timeblock' waarbinnen de werkzaamheden, voor betreffende competentie met bijbehorende tijdsduur, van start kan gaan.

Van belang zijn de volgende gegevens:
PlanningRequestNumber --> v_PlanningRequestNumber (gaat als antwoord retour, zie XML hieronder)
Contractor/GLN --> v_bedrijf_key van leverancier, deze zal dezelfde (moeten) zijn als waar de 'user_key' contactpersoon is van dit bedrijf.
CompetenceCode --> v_prs_dienst_hint (ELE/SCH/LOO/...)
MaintenanceMoment/EarliestExecutionDate --> v_date_start (zoek vanaf deze datum)
MaintenanceMoment/LatestExecutionDate --> v_date_end (zoek t/m deze datum)
Timeblock/EarliestExecutionTime --> v_time_start (zoek vanaf dit tijdstip)
Timeblock/LatestExecutionTime --> v_time_end (zoek t/m dit tijdstip)
Duration --> v_duration_minutes (in minuten) - Op zoek naar vrij plek met om te starten in bovengenoemde datum-range en dag/tijdsblok en voldoende tijd om de klus te klaren, in minuten uitgedrukt dus.
NumberOfPlanningOptions --> v_max_options - Maximaal dit aantal als resultaat teruggeven

Hiervoor maken we gebruik van de DB function 'marx_get_planproposals'


-------------------------------------------------------

We antwoorden altijd met planningsreactie (BERICHT II):
<?xml version="1.0" encoding="UTF-8"?>
<PlanningResponse xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.ketenstandaard.nl/planningsreactie/SALES/005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.ketenstandaard.nl/planningsreactie/SALES/005 Planningsreactie_SALES005.xsd">
  <PlanningResponseNumber>XXXXXXXXXXXXXXXXX</PlanningResponseNumber>
  <MessageDate>2020-08-13</MessageDate>
  <MessageTime>12:34:58</MessageTime>
  <PlanningRequestReference>
    <PlanningRequestNumber>ABC123XYZ</PlanningRequestNumber>
  </PlanningRequestReference>
  <Buyer>
    <GLN>8713783669303</GLN>
  </Buyer>
  <Contractor>
    <GLN>8713783642016</GLN>
  </Contractor>
  <MaintenanceMoment>
    <EarliestExecutionDate>2020-08-17</EarliestExecutionDate>
    <Timeblock>
      <EarliestExecutionTime>10:00:00</EarliestExecutionTime>
      <LatestExecutionTime>11:00:00</LatestExecutionTime>
    </Timeblock>
  </MaintenanceMoment>
  <MaintenanceMoment>
    <EarliestExecutionDate>2020-08-17</EarliestExecutionDate>
    <Timeblock>
      <EarliestExecutionTime>13:00:00</EarliestExecutionTime>
      <LatestExecutionTime>15:30:00</LatestExecutionTime>
    </Timeblock>
  </MaintenanceMoment>
  <MaintenanceMoment>
    <EarliestExecutionDate>2020-08-18</EarliestExecutionDate>
    <Timeblock>
      <EarliestExecutionTime>12:00:00</EarliestExecutionTime>
      <LatestExecutionTime>15:00:00</LatestExecutionTime>
    </Timeblock>
  </MaintenanceMoment>
</PlanningResponse>

*/


function xmlNodeVal(xml, strQuery)
{
    var node = xml.selectSingleNode(strQuery);
    if (node)
        return node.text;
    else
        return null;
}

function marx_plan_get_request_nr (p_xml)
{ var l_req_nr;
  var l_xml_query = "//pln_nspace:PlanningRequestNumber";
  var l_req_nr = xmlNodeVal(p_xml, l_xml_query);
  return (l_req_nr);
}

function marx_plan_get_response_nr (p_xml)
{ var l_rsp_nr;
  var l_xml_query = "//pln_nspace:PlanningResponseNumber";
  var l_rsp_nr = xmlNodeVal(p_xml, l_xml_query);
  return (l_rsp_nr);
}

function marx_plan_get_sysdate ()
{ var l_sysdate
  var sql = "SELECT to_char(SYSDATE,'yyyy-mm-dd HH24:mi:ss') l_sysdate FROM DUAL";
  var oRs = Oracle.Execute(sql);
  if (!oRs.eof)
  {
      l_sysdate = oRs("l_sysdate").Value;
  }
  oRs.close();  
  return (l_sysdate);
}

function marx_plan_get_buyer_gln (p_xml)
{ var l_gln;
  var l_xml_query = "//pln_nspace:Buyer/pln_nspace:GLN";
  var l_gln = xmlNodeVal(p_xml, l_xml_query);
  return (l_gln);
}

function marx_plan_get_prs_woco_key (p_xml)
{ var l_prs_bedrijf_key;
  var l_gln = marx_plan_get_buyer_gln(p_xml);
  if (l_gln){    
    var sql = "SELECT prs_bedrijf_key"
                + " FROM prs_bedrijf"
                + " WHERE prs_bedrijf_verwijder IS NULL"
                + " AND prs_leverancier_nr = " + safe.quoted_sql(l_gln);
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
        l_prs_bedrijf_key = oRs("prs_bedrijf_key").Value;
    }
    oRs.close();
  }
  return (l_prs_bedrijf_key);
}

function marx_plan_get_contractor_gln (p_xml)
{ var l_gln;
  var l_xml_query = "//pln_nspace:Contractor/pln_nspace:GLN";
  var l_gln = xmlNodeVal(p_xml, l_xml_query);
  return (l_gln);
}


function marx_plan_get_prs_bedrijf_key (p_xml)
{ var l_prs_bedrijf_key;
  var l_gln = marx_plan_get_contractor_gln(p_xml);
  if (l_gln){    
    var sql = "SELECT prs_bedrijf_key"
                + " FROM prs_bedrijf"
                + " WHERE prs_bedrijf_verwijder IS NULL"
                + " AND prs_leverancier_nr = " + safe.quoted_sql(l_gln);
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
        l_prs_bedrijf_key = oRs("prs_bedrijf_key").Value;
    }
    oRs.close();
  }
  return (l_prs_bedrijf_key);
}

function marx_plan_bedrijf_key_is_oke (p_prs_bedrijf_key, p_userkey)
{ var l_result = 0; // false  
  if (p_userkey && p_prs_bedrijf_key){
    var sql = "SELECT b.prs_bedrijf_key"
            + " FROM prs_bedrijf b"
            + " WHERE prs_bedrijf_key = " + p_prs_bedrijf_key
            + " AND EXISTS (SELECT 'x' FROM prs_contactpersoon p"
            + "             WHERE p.prs_bedrijf_key = b.prs_bedrijf_key"
            + "             AND p.prs_perslid_key = " + p_userkey + ")";
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
        l_result = 1;
    }
    oRs.close();
  }
  return (l_result);
}


function marx_get_dummy_res_rsv_ruimte_contact_key (p_res_rsv_ruimte_key_str)
{ var l_contact_key;
  if (p_res_rsv_ruimte_key_str){
    var sql = "SELECT res_rsv_ruimte_contact_key FROM res_rsv_ruimte WHERE res_rsv_ruimte_key=fac.safe_to_number(" + safe.quoted_sql(l_res_rsv_ruimte_key_str) + ")";
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
        l_contact_key = oRs("res_rsv_ruimte_contact_key").Value;
    }
    oRs.close();
  }
  return (l_contact_key);
}

function marx_plan_get_api_user_key (p_bedrijf_key)
{ var l_api_user_key;
  if (p_bedrijf_key){
    var sql = "SELECT marx_get_api_user(" + p_bedrijf_key + ") prs_perslid_key FROM DUAL";
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
        l_api_user_key = oRs("prs_perslid_key").Value;
    }
    oRs.close();
  }
  return (l_api_user_key);
}


function marx_plan_get_competentie_code (p_xml)
{ var l_competentie_code;
  var l_xml_query = "//pln_nspace:Competence/pln_nspace:CompetenceCode";
  var l_competentie_code = xmlNodeVal(p_xml, l_xml_query);  
  return (l_competentie_code);
}

//MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie
//Heeft leverancier p_bedrijf_key wel autorisatie voor Mareon Premium Groene Planningen
//Waarde = 0, dan geen autorisatie
//Waarde = 1, dan wel autorisatie
function marx_bedrijf_auth_groenplannen (p_bedrijf_key)
{ var l_result;
  l_result = 0;
  if (p_bedrijf_key){
    var sql = "SELECT marx_bedrijf_auth_4_greenplan(" + p_bedrijf_key + ") waarde FROM DUAL";
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof)
    {
      if (oRs("waarde").Value == 1)
      {
        l_result = 1;
      }        
    }
    oRs.close();
  }
  return (l_result);
}

function marx_plan_get_region_id (p_xml)
{ var l_region_id;
  var l_xml_query = "//pln_nspace:MaintenanceLocation/pln_nspace:MARX_RegionId";
  var l_region_id = xmlNodeVal(p_xml, l_xml_query);  
  return (l_region_id);
}
function marx_plan_get_straat (p_xml)
{ var l_straatnaam;
  var l_xml_query = "//pln_nspace:MaintenanceLocation/pln_nspace:Street";
  var l_straatnaam = xmlNodeVal(p_xml, l_xml_query);  
  return (l_straatnaam);
}
function marx_plan_get_huisnr (p_xml)
{ var l_huisnr;
  var l_xml_query = "//pln_nspace:MaintenanceLocation/pln_nspace:HouseNumber";
  var l_huisnr = xmlNodeVal(p_xml, l_xml_query);  
  return (l_huisnr);
}
function marx_plan_get_postcode (p_xml)
{ var l_postcode;
  var l_xml_query = "//pln_nspace:MaintenanceLocation/pln_nspace:PostalCode";
  var l_postcode = xmlNodeVal(p_xml, l_xml_query);  
  return (l_postcode);
}
function marx_plan_get_plaats (p_xml)
{ var l_plaatsnaam;
  var l_xml_query = "//pln_nspace:MaintenanceLocation/pln_nspace:City";
  var l_plaatsnaam = xmlNodeVal(p_xml, l_xml_query);  
  return (l_plaatsnaam);
}

function marx_plan_get_startdatum (p_xml)
{ var l_startdatum;
  var l_xml_query = "//pln_nspace:MaintenanceMoment/pln_nspace:EarliestExecutionDate";
  var l_startdatum = xmlNodeVal(p_xml, l_xml_query); // yyyy-m-dd
  return (l_startdatum);
}

function marx_plan_get_einddatum (p_xml)
{ var l_einddatum;
  var l_xml_query = "//pln_nspace:MaintenanceMoment/pln_nspace:LatestExecutionDate";
  var l_einddatum = xmlNodeVal(p_xml, l_xml_query); // yyyy-m-dd
  return (l_einddatum);
}

function marx_plan_get_duration_minutes (p_xml)
{ var l_duration_minutes;
  var l_xml_query = "//pln_nspace:Duration";
  var l_duration = xmlNodeVal(p_xml, l_xml_query); // formaat PnYnMnDTnHnM, bv P0Y0M0DT1H0M
  __Log("l_duration:" + l_duration);
  var l_dur_M = l_duration.substring(l_duration.indexOf("H")+1, l_duration.lastIndexOf("M"));
  var l_dur_H = l_duration.substring(l_duration.indexOf("T")+1, l_duration.lastIndexOf("H"));
  var l_dur_D = l_duration.substring(l_duration.indexOf("M")+1, l_duration.lastIndexOf("D"));
  //De Y(ear) en M(onth) ondersteuen we (nog) niet...  
  __Log("l_dur_M:" + l_dur_M);
  __Log("l_dur_H:" + l_dur_H);
  __Log("l_dur_D:" + l_dur_D);  
  l_duration_minutes = (parseInt(l_dur_D,10) * 24 * 60) + (parseInt(l_dur_H,10) * 60) + parseInt(l_dur_M,10);

  return (l_duration_minutes);
}

function marx_plan_get_interval_minutes (p_xml)
{ var l_interval_minutes;
  l_interval_minutes = 0;
  return (l_interval_minutes);
}

function marx_plan_get_alltime_intervals (p_xml, p_dag)
{
    var l_result = "";
    var l_xml_query = "//pln_nspace:MaintenanceMoment/pln_nspace:TimeblocksPerWeekday[pln_nspace:Weekday='" + p_dag + "']";
    var l_node = xmlNodeVal(p_xml, l_xml_query);
    if (l_node)
    { // De "dag" node bestaat, en gaat voor op de algemene node
      var timeblock_nodes = p_xml.selectNodes(l_xml_query + "/pln_nspace:Timeblock");
      for (var i = 0; i < timeblock_nodes.length; i++)
      {
          var timeblock_node = timeblock_nodes.item(i);            
          var l_time1 = xmlNodeVal(timeblock_node, "pln_nspace:EarliestExecutionTime");            
          var l_time2 = xmlNodeVal(timeblock_node, "pln_nspace:LatestExecutionTime");
          l_result = l_result + l_time1 + "-" + l_time2 + ";"
      }
    }
    else
    {   // De "dag" node bestaat NIET, als de algemene node er is, dan telt deze tijd
        var l_xml_query = "//pln_nspace:MaintenanceMoment";
        var timeblock_nodes = p_xml.selectNodes(l_xml_query + "/pln_nspace:Timeblock");
        for (var i = 0; i < timeblock_nodes.length; i++)
        {
            var timeblock_node = timeblock_nodes.item(i);            
            var l_time1 = xmlNodeVal(timeblock_node, "pln_nspace:EarliestExecutionTime");            
            var l_time2 = xmlNodeVal(timeblock_node, "pln_nspace:LatestExecutionTime");
            l_result = l_result + l_time1 + "-" + l_time2 + ";"
        }    
    }
    return (l_result);
}

function marx_plan_get_aant_opties (p_xml)
{ var l_aant_opties;
  var l_xml_query = "//pln_nspace:NumberOfPlanningOptions";
  var l_aant_opties = xmlNodeVal(p_xml, l_xml_query);
  return (l_aant_opties);
}

function marx_plan_get_starttime (p_xml)
{ var l_starttime;
  var l_xml_query = "//pln_nspace:MaintenanceMoment/pln_nspace:Timeblock/pln_nspace:EarliestExecutionTime";
  var l_starttime = xmlNodeVal(p_xml, l_xml_query);
  return (l_starttime);
}

function marx_plan_get_endtime (p_xml)
{ var l_endtime;
  var l_xml_query = "//pln_nspace:MaintenanceMoment/pln_nspace:Timeblock/pln_nspace:LatestExecutionTime";
  var l_endtime = xmlNodeVal(p_xml, l_xml_query);
  return (l_endtime);
}

// ---------  START  ---------  START  ---------  START  ---------  START  ---------  START  ---------  START  ---------  START  ---------  START  ---------  START  ---------  START

// TODO: target adres en stylesheet achterhalen
// TODO: authenticatie voor de target?


var xmlReq = styledRequestXML(API); // Deze eventuele stylesheet is hier onafhankelijk van het
                                    // aanvragende systeem (user_key) en niet direct zinvol (gebruik identity)

xmlReq.setProperty ("SelectionNamespaces", "xmlns:pln_nspace='http://www.ketenstandaard.nl/planningsverzoek/SALES/005'");

if (xmlNodeVal(xmlReq, "//pln_nspace:PlanningRequest")){
  var v_msgtype = "PLNRSP";
  
  var l_prs_woco_key = marx_plan_get_prs_woco_key(xmlReq);
  __Log("l_prs_woco_key:" + l_prs_woco_key);
  var l_prs_bedrijf_key = marx_plan_get_prs_bedrijf_key(xmlReq);
  __Log("l_prs_bedrijf_key:" + l_prs_bedrijf_key);
  
  __Log("user_key:" + user_key);
  var l_bedrijf_is_oke = marx_plan_bedrijf_key_is_oke(l_prs_bedrijf_key, user_key);
  __Log("l_bedrijf_is_oke:" + l_bedrijf_is_oke);
  
  
  var l_req_nr = marx_plan_get_request_nr(xmlReq);
  var l_rsp_nr = l_req_nr;
  __Log("l_req_nr:" + l_req_nr);
  var l_gln_buyer = marx_plan_get_buyer_gln(xmlReq);
  __Log("l_gln_buyer:" + l_gln_buyer);
  var l_gln_contractor = marx_plan_get_contractor_gln(xmlReq);
  __Log("l_gln_contractor:" + l_gln_contractor);
  
  
  if (l_bedrijf_is_oke){
    var l_competentie_code = marx_plan_get_competentie_code(xmlReq);
    __Log("l_competentie_code:" + l_competentie_code);    
    var l_startdatum = marx_plan_get_startdatum(xmlReq);
    __Log("l_startdatum:" + l_startdatum);
    var l_einddatum = marx_plan_get_einddatum(xmlReq);
    __Log("l_einddatum:" + l_einddatum);
    
    var l_duration_minutes = marx_plan_get_duration_minutes(xmlReq);
    __Log("l_duration_minutes:" + l_duration_minutes);
    
    var l_interval_minutes = marx_plan_get_interval_minutes(xmlReq);
    __Log("l_interval_minutes:" + l_interval_minutes);
    
    
    var l_aant_opties = marx_plan_get_aant_opties(xmlReq);
    __Log("l_aant_opties:" + l_aant_opties);
    
    // MARX#70053 Mareon Premium Groene Planningen: plannen met geografische optimalisatie
    var latlng;
    var l_lat;
    var l_lng;
    // MARX#75600 Mareon Groene Planning: Aansturing gebiedsoptimalisatie vanuit opdrachtgever
    var l_region_id;
    
    // Eerst ff checken of leverancier wel autorisatie hiervoor heeft, anders slaan we de geografische zoektochtje over...
    var l_auth_groenplannen_lev = marx_bedrijf_auth_groenplannen(l_prs_bedrijf_key);
    __Log("l_auth_groenplannen_lev:" + l_auth_groenplannen_lev);
    // Eerst ff checken of woco wel autorisatie hiervoor heeft, anders slaan we de gebiedsoptimalisatie vanuit opdrachtgever over...
    var l_auth_groenplannen_woco = marx_bedrijf_auth_groenplannen(l_prs_woco_key);
    __Log("l_auth_groenplannen_woco:" + l_auth_groenplannen_woco);
    
    if (l_auth_groenplannen_lev == 1)
    {
      //Hier ben ik voor groen plannen geautoriseerd, leverancier wil dit graag.
      
      // MARX#75600 Mareon Groene Planning: Aansturing gebiedsoptimalisatie vanuit opdrachtgever
      // Region-id vanuit opdrachtgever is alleen van belang als opdrachtgevers deze instelling "Groen plannen" ook heeft ingesteld, anders wordt hier niets mee gedaan (geskipped, en blijft l_region_id leeg).
      if (l_auth_groenplannen_woco == 1)
      {
        var l_region_id = marx_plan_get_region_id(xmlReq);
        __Log("l_region_id:" + l_region_id);
      }
      
      var l_postcode = marx_plan_get_postcode(xmlReq);
      __Log("l_postcode:" + l_postcode);
      var l_huisnr = marx_plan_get_huisnr(xmlReq);
      __Log("l_huisnr:" + l_huisnr);
      var l_straatnaam = marx_plan_get_straat(xmlReq);
      __Log("l_straatnaam:" + l_straatnaam);
      var l_plaatsnaam = marx_plan_get_plaats(xmlReq);
      __Log("l_plaatsnaam:" + l_plaatsnaam);
    
    
      if (l_straatnaam && l_plaatsnaam)
      {
        if (l_huisnr)
        {
          latlng = GetLatLng(l_straatnaam + "+" + l_huisnr + "+" + l_plaatsnaam);
        }
        if (!latlng)
        {
          latlng = GetLatLng(l_straatnaam + "+" + l_plaatsnaam);
        }
      }
      if (!latlng)
      {
        if (l_postcode)
        { 
          if (l_huisnr)
          {
            latlng = GetLatLng(l_postcode + "+" + l_huisnr);
          }
          if (!latlng)
          {
            latlng = GetLatLng(l_postcode);
          }        
        }
      }
      if (latlng)
      {
        l_lat = latlng.split("|")[0];
        __Log("l_lat:" + l_lat);
        l_lng = latlng.split("|")[1];
        __Log("l_lng:" + l_lng);
      }
    }
    else
    {
      //Geen autorisatie voor Groen Plannen, kunnen we wel ff loggen
      __Log("Bedrijf heeft geen autorisatie voor Mareon Premium Groene Planning (prs_bedrijf_key):" + l_prs_bedrijf_key);
    }
    
    var l_mon_times = marx_plan_get_alltime_intervals(xmlReq, "MON");
    __Log("l_mon_times:" + l_mon_times);
    var l_tue_times = marx_plan_get_alltime_intervals(xmlReq, "TUE");
    __Log("l_tue_times:" + l_tue_times);
    var l_wed_times = marx_plan_get_alltime_intervals(xmlReq, "WED");
    __Log("l_wed_times:" + l_wed_times);
    var l_thu_times = marx_plan_get_alltime_intervals(xmlReq, "THU");
    __Log("l_thu_times:" + l_thu_times);
    var l_fri_times = marx_plan_get_alltime_intervals(xmlReq, "FRI");
    __Log("l_fri_times:" + l_fri_times);
    var l_sat_times = marx_plan_get_alltime_intervals(xmlReq, "SAT");
    __Log("l_sat_times:" + l_sat_times);
    var l_sun_times = marx_plan_get_alltime_intervals(xmlReq, "SUN");
    __Log("l_sun_times:" + l_sun_times);
    
    var sql = "select marx_get_planproposals(" + l_prs_woco_key + "," + l_prs_bedrijf_key + "," + safe.quoted_sql(l_competentie_code) + ", fac.safe_to_date(" + safe.quoted_sql(l_startdatum) + ",'yyyy-mm-dd'), fac.safe_to_date(" + safe.quoted_sql(l_einddatum) + ",'yyyy-mm-dd')," + safe.quoted_sql(l_mon_times) + "," + safe.quoted_sql(l_tue_times) + "," + safe.quoted_sql(l_wed_times) + "," + safe.quoted_sql(l_thu_times) + "," + safe.quoted_sql(l_fri_times) + "," + safe.quoted_sql(l_sat_times) + "," + safe.quoted_sql(l_sun_times) + "," + l_duration_minutes + ", " + l_interval_minutes + ", " +  l_aant_opties + ", " + " fac.safe_to_number(" + safe.quoted_sql(l_lat) + ")" +  ", " + " fac.safe_to_number(" + safe.quoted_sql(l_lng) + ")" + "," + safe.quoted_sql(l_region_id) + " ) planproposals from dual"; 
  }
}
else{
  xmlReq.setProperty ("SelectionNamespaces", "xmlns:pln_nspace='http://www.ketenstandaard.nl/planningsreactie/SALES/005'");
  if (xmlNodeVal(xmlReq, "//pln_nspace:PlanningResponse")){
    var v_msgtype = "PLNCFM";
    var l_prs_woco_key = marx_plan_get_prs_woco_key(xmlReq);
    var l_prs_bedrijf_key = marx_plan_get_prs_bedrijf_key(xmlReq);
    __Log("l_prs_bedrijf_key:" + l_prs_bedrijf_key);
    __Log("user_key:" + user_key);
    var l_bedrijf_is_oke = marx_plan_bedrijf_key_is_oke(l_prs_bedrijf_key, user_key);
    __Log("l_bedrijf_is_oke:" + l_bedrijf_is_oke);
    
    var l_gln_buyer = marx_plan_get_buyer_gln(xmlReq);
    __Log("l_gln_buyer:" + l_gln_buyer);
    var l_gln_contractor = marx_plan_get_contractor_gln(xmlReq);
    __Log("l_gln_contractor:" + l_gln_contractor);
    
    //In het request-nummer staat het response-nummer die leverancier in vorig bericht terug heeft gegegeven, en nu in de confirmation weer retour gaat, zodat leverancier de plan-id terug heeft.
    //Betreft unieke res_rsv_ruimte_key die leverancier in 1e call (planproposals) heeft teruggegeven aan caller, die deze in 2e call (nu dus) weer mee moet geven, waarmee de andere (STATIC) parameters (prs_bedrijf_key, v_duration_minutes, v_dienst_hint bepaald kunnen worden
    var l_req_nr = marx_plan_get_request_nr(xmlReq);
    var l_res_rsv_ruimte_key_str= l_req_nr;
    __Log("l_res_rsv_ruimte_key_str:" + l_res_rsv_ruimte_key_str);
    
    // In het response-nummer staat de toekomstige ION (inkoopopdrachtnummer) van opdrachtgever...
    var l_rsp_nr = marx_plan_get_response_nr(xmlReq);
    var l_ion_nr = l_rsp_nr;
    __Log("l_rsp_nr:" + l_rsp_nr);
    
    user.auth_required_or_abort(l_bedrijf_is_oke);
    
    if (l_bedrijf_is_oke){
      // Autorisatie check: is de user_key wel perslid binnen het bedrijf? --> op dit punt dus: JA
      
      var l_contact_key = marx_get_dummy_res_rsv_ruimte_contact_key(l_res_rsv_ruimte_key_str);
      var l_api_user_key = marx_plan_get_api_user_key (l_prs_bedrijf_key);
      
      user.auth_required_or_abort(l_contact_key == l_api_user_key);
      if (l_contact_key == l_api_user_key){
        // Extra Autorisatie check: is l_res_rsv_ruimte_key_str wel van l_prs_bedrijf_key? --> op dit punt dus: JA
        // De contact-key van de dummy reservering zou de (one-and-only) api-user van het bedrijf moeten zijn, en als we hier zijn gekomen, is dat het geval --> autorisatiecheck geslaagd, deze dummy reservering mag aangepast worden
      
        var l_confirm_datum = marx_plan_get_startdatum(xmlReq);
        __Log("l_confirm_datum:" + l_confirm_datum);
        var l_confirm_time1 = marx_plan_get_starttime(xmlReq);
        __Log("l_confirm_time1:" + l_confirm_time1);
        var l_confirm_time2 = marx_plan_get_endtime(xmlReq);
        __Log("l_confirm_time2:" + l_confirm_time2);
        
        var sql = "select marx_set_planconfirmation(" + l_prs_woco_key + "," + l_prs_bedrijf_key + ", fac.safe_to_number(" + safe.quoted_sql(l_res_rsv_ruimte_key_str) + ")," + safe.quoted_sql(l_ion_nr) + ",fac.safe_to_date(" + safe.quoted_sql(l_confirm_datum) + ",'yyyy-mm-dd')," + safe.quoted_sql(l_confirm_time1) + "," + safe.quoted_sql(l_confirm_time2) + ") planproposals from dual";
      }
    }
  }
}

v_planproposals = [];
if (l_bedrijf_is_oke){
  var oRs = Oracle.Execute(sql);
  if (!oRs.eof)
  {
      /* Voorbeeld v_planproposals =
       [{ "planproposal": {"res_deel_key": "1234", "startdate": "2021-04-01", "starttime": "09:00", "enddate": "2021-04-01", "endtime": "12:00" } },
        { "planproposal": {"res_deel_key": "1234", "startdate": "2021-04-01", "starttime": "13:00", "enddate": "2021-04-01", "endtime": "16:00" } },
        { "planproposal": {"res_deel_key": "9876", "startdate": "2021-04-02", "starttime": "09:00", "enddate": "2021-04-02", "endtime": "12:00" } },
        { "planproposal": {"res_deel_key": "9876", "startdate": "2021-04-05", "starttime": "13:00", "enddate": "2021-04-05", "endtime": "16:00" } },
        ]
        Let op: de startdate/time en enddate/time is in geval van:
        - PLNRSP: de bloktijden
        - PLNCFM: de echte plandatum begin/eind momenten
      */
      v_planproposals_txt = oRs("planproposals").Value;
      __Log("v_planproposals_txt: " + v_planproposals_txt);
      __Log("v_planproposals_txt.length: " + v_planproposals_txt.length);
      
      v_planproposals = eval("(" + v_planproposals_txt + ")");
      __Log("v_planproposals.length: " + v_planproposals.length);
  }
  oRs.close();
  
  if (v_msgtype == "PLNRSP" && v_planproposals.length > 0){
    // Wanneer er planningsverzoeken zijn, dan gaan we een DUMMY "ProForma" res_reservering vastleggen/registreren...
    
    var sql = "SELECT res_s_res_rsv_ruimte_key.nextval from dual";
    var oRs = Oracle.Execute(sql);
    if (!oRs.eof){
      var l_res_rsv_ruimte_key = oRs(0).Value;
      oRs.close();
      var sql = "BEGIN marx_put_dummy_res_reservering (" + l_prs_woco_key + "," + l_prs_bedrijf_key + "," + safe.quoted_sql(l_competentie_code) + "," + l_duration_minutes + "," + l_res_rsv_ruimte_key + ", " + " fac.safe_to_number(" + safe.quoted_sql(l_lat) + ")" +  ", " + " fac.safe_to_number(" + safe.quoted_sql(l_lng) + ")" + "," + safe.quoted_sql(l_region_id)  + "); END;";
       __Log("Aanroep van marx_put_dummy_res_reservering");
      var oRs = Oracle.Execute(sql);
      var l_rsp_nr = l_res_rsv_ruimte_key;
    }
  }
}

var l_sysdate = marx_plan_get_sysdate();

var result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
           + "<soap:Envelope xmlns:msxml=\"urn:schemas-microsoft-com:xslt\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"https://www.ketenstandaard.nl/WS/MessageService/3.1\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
           + "<soap:Header>"
           + "</soap:Header>"
           + "<soap:Body>"
           + "<ns:Message>"
           + " <ns:MsgProperties>"
           + "  <ns:MsgFormat>SALES</ns:MsgFormat>"
           + "  <ns:MsgVersion>005</ns:MsgVersion>"
           + "  <ns:MsgType>" + v_msgtype + "</ns:MsgType>"
           + " </ns:MsgProperties>"
           + "<ns:MsgContent>"
           + " <PlanningResponse xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.ketenstandaard.nl/planningsreactie/SALES/005\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
           + " xsi:schemaLocation=\"http://www.ketenstandaard.nl/planningsreactie/SALES/005 Planningsreactie_SALES005.xsd\">"
           + "<PlanningResponseNumber>" + l_rsp_nr + "</PlanningResponseNumber>"
           + "<MessageDate>" + l_sysdate.substring(0,10) + "</MessageDate>"
           + "<MessageTime>" + l_sysdate.substring(11) + "</MessageTime>"
           + "<PlanningRequestReference>"
           + "  <PlanningRequestNumber>" + l_req_nr + "</PlanningRequestNumber>"
           + "</PlanningRequestReference>"
           + "<Buyer>"
           + "  <GLN>" + l_gln_buyer + "</GLN>"
           + "</Buyer>"
           + "<Contractor>"
           + "  <GLN>" + l_gln_contractor + "</GLN>"
           + "</Contractor>";


for(var i = 0; i < v_planproposals.length; i++)
{
  var v_res_deel_key = v_planproposals[i].planproposal.res_deel_key;
  var v_startdatum = v_planproposals[i].planproposal.startdate;
  var v_starttime = v_planproposals[i].planproposal.starttime;
  var v_enddatum = v_planproposals[i].planproposal.enddate;
  var v_endtime = v_planproposals[i].planproposal.endtime;
  
  result = result
          + "<MaintenanceMoment>"
          + " <EarliestExecutionDate>" + v_startdatum + "</EarliestExecutionDate>"
          + " <Timeblock>"
          + "   <EarliestExecutionTime>" + v_starttime + "</EarliestExecutionTime>"
          + "   <LatestExecutionTime>" + v_endtime + "</LatestExecutionTime>"
          + " </Timeblock>"
          + "</MaintenanceMoment>";
}
result = result + "</PlanningResponse>"
                + "</ns:MsgContent>"
                + "</ns:Message>"
                + "</soap:Body>"
                + "</soap:Envelope>";

__Log("result:" + result);


if (v_msgtype == "PLNCFM"){
    
  if (v_planproposals.length == 1){
    // De confirmation is succesvol, d.w.z. er is inderdaad een plekje vrij, we gaan hem boeken door de DUMMY "ProForma" res_reservering OM TE ZETTEN naar de juiste datum/tijdstip en persoon, dus van DUMMY naar REAL reservering
    // En we retourneren dan een MS31-XML met succes = true
    __Log("Aanroep van marx_put_res_dummy_2_real");
    var sql = "BEGIN marx_put_res_dummy_2_real(" + l_prs_woco_key
                                              + "," +  "fac.safe_to_number(" + safe.quoted_sql(l_res_rsv_ruimte_key_str) + ")"
                                              + "," + v_res_deel_key
                                              + "," + "fac.safe_to_date(" + safe.quoted_sql(v_startdatum + " " + v_starttime) + ",'yyyy-mm-dd hh24:mi:ss')"
                                              + "," + "fac.safe_to_date(" + safe.quoted_sql(v_enddatum + " " + v_endtime) + ",'yyyy-mm-dd hh24:mi:ss')"
                                              + "," + safe.quoted_sql(l_confirm_time1)
                                              + "," + safe.quoted_sql(l_confirm_time2)
                                              + "," + safe.quoted_sql(l_ion_nr)
                                              + "); END;";
    var oRs = Oracle.Execute(sql);
    
    var result = 
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
          + "<soap:Envelope xmlns:msxml=\"urn:schemas-microsoft-com:xslt\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"https://www.ketenstandaard.nl/WS/MessageService/3.1\">"
          + "<soap:Header>"
          + "</soap:Header>"
          + "<soap:Body>"
          + "<ns:MessageResponse>"
          + "<ns:MessageResult>true</ns:MessageResult>"
          + "</ns:MessageResponse>"
          + "</soap:Body>"
          + "</soap:Envelope>";
  }
  else{
    // De confirmation is NIET succesvol, d.w.z. het plekje is inmiddels (ondertussen) vergeven/ingepikt door iemand anders, de retour-XML (MS31) moet daarom een fault teruggeven aan de aanroepende partij
    
     var result = 
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
          + "<soap:Envelope xmlns:msxml=\"urn:schemas-microsoft-com:xslt\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"https://www.ketenstandaard.nl/WS/MessageService/3.1\">"
          + "<soap:Header>"
          + "</soap:Header>"
          + "<soap:Body>"          
          + "<soap:Fault>"
          + "<faultcode>soap:Server</faultcode>"
          + "<faultstring>Server error</faultstring>"
          + "<detail>"
          + "<FaultDetails>"
          + "<ErrorCode>900</ErrorCode>"
          + "<Message xml:lang=\"nl\">Planconfirmation is niet succesvol</Message>"
          + "</FaultDetails>"
          + "</detail>"
          + "</soap:Fault>"          
          + "</soap:Body>"
          + "</soap:Envelope>";
    
  }
  
}

if (result)
{
     var xmldoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
     xmldoc.async = false;
     xmldoc.loadXML(result);
     if (xmldoc.parseError.errorCode != 0)
     {
        var myErr = xmldoc.parseError;
        __Log("XML2STR3 Error in xmlfile: " + myErr.reason);
        Response.Write ("<html><body><b>Error in xmlfile:</b><br>" + myErr.reason + "</body></html>");
        Response.End;
     }
     
    if (API.apidata.stylesheet)
    {
      // Niet super efficient dat we eerst naar tekstuele xml gaan maar ach...
      __Log("Before STR2Stream:" + API.apidata.stylesheet);
      STR2Stream(xmldoc.xml, API.apidata.stylesheet, Response, {});
    }
    else
    {
      __Log("Before Response:" + xmldoc.xml);
      Response.Write(xmldoc.xml);
    }
}
else
    API.error("Could not send planrequest");

ASPPAGE_END();
%>
