<%@ language = "JavaScript" %> <% /* $Revision$ $Id$ File: api_opdrsoap.asp Description: API voor ORD-soap berichten Interpreteert een bericht zodanig dat een opdracht wordt aangemaakt (incl. evt. bovenliggende melding) of aangepast. Dat is: qua omschrijving (voortgang), kosten of status. Als een status wordt meegegeven, dan is ook vereist dat dat een geldige statusovergang is, anders wordt het hele bericht genegeerd. Parameters: Een xml Context: Notes: */ DOCTYPE_Disable = 1; THIS_FILE = "appl/api/api_opdrsoap.asp"; %> <% // We sturen het antwoord in UTF-8. Session.Codepage = 65001; Response.Charset = 'utf-8'; var API = new API_func(); var MLDremark = 0; // 0= negeer, 1=append bij autoorder, 2=overwrite bij autoorder, 5=append altijd, 6=overwrite altijd var ORDremark = 2; // /* API options voorbeeld: { MLDremark: 0, ORDremark: 2 } */ API.apidata.options = API.apidata.options || {}; if ("MLDremark" in API.apidata.options) MLDremark = API.apidata.options["MLDremark"]; if ("ORDremark" in API.apidata.options) ORDremark = API.apidata.options["ORDremark"]; //user.checkAutorisation("WEB_MLDUSE"); // Dit is nog ongeacht de melding. var tsql = "-"; // Voor tijdelijke statement. var sql = "-"; // De uiteindelijke insert/update-sql. var xmlReq = Server.CreateObject("MSXML2.DOMDocument.6.0"); //if (API.apidata.loglevel) __Log2File(Request, API.APIname + "_IN1"); 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 ="?"; // Dit is de opdrachtenloop (mochten er ooit nog anderen gaan volgen). var opdrachten = xmlReq.getElementsByTagName("opdracht"); var wasMLDremark = MLDremark; var wasORDremark = ORDremark; for (var i = 0; i < opdrachten.length; i++) { MLDremark = wasMLDremark; // Resetten voor elke opdracht. Tweede opdracht hoeft namelijk geen autoorder te zijn ORDremark = wasORDremark; 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 opdrid = opdrachten[i].getAttribute("key"); // UPD var opdraction = opdrachten[i].getAttribute("type").toLowerCase(); // NEW/UPD var externnr = XMLval(opdrachten[i], "externnr"); // NEW var externopdrnr = XMLval(opdrachten[i], "externopdrnr"); var plandatum = XMLval(opdrachten[i], "plandatum", true); if (S("mld_use_plandate2") & 2) // Otherwise ignore 'plandatum2' var plandatum2 = XMLval(opdrachten[i], "plandatum2", true); var halt = XMLval(opdrachten[i], "halt") == 1; // Onderbreken. var resume = XMLval(opdrachten[i], "resume") == 1; // Hervatten. var voor_key = parseInt(XMLval(opdrachten[i], "voor"), 10); // NEW var voor_email = XMLval(opdrachten[i], "voor_email"); // NEW var stdm_key = parseInt(XMLval(opdrachten[i], "stdmelding_key"), 10); // NEW var topdr_key = parseInt(XMLval(opdrachten[i], "typeopdr_key"), 10); // NEW var uitv_key = parseInt(XMLval(opdrachten[i], "bedrijf_key"), 10); // NEW var opdrachttekst = XMLval(opdrachten[i], "opdrachttekst"); // NEW var meldingtekst = XMLval(opdrachten[i], "meldingtekst"); // NEW var onderwerp = XMLval(opdrachten[i], "onderwerp"); // NEW var opdr_kpn = XMLval(opdrachten[i], "kostenplaats"); var flag = parseInt(XMLval(opdrachten[i], "flag"), 10); var txt_mut_datum = XMLval(opdrachten[i], "mut_datum"); // UPD var opdrstatus = XMLval(opdrachten[i], "status"); // UPD var opdropmerking = XMLval(opdrachten[i], "opmerking"); // UPD var opdrnote = XMLval(opdrachten[i], "note"); // UPD var opdrnoteflag = parseInt(XMLval(opdrachten[i], "noteflag")); // UPD var note_key = -1; // vooralnog // Welke tracking gaan we registreren? var status_tracking_key = -1; // prio1 var datum_tracking_key = -1; // prio2 var update_tracking_key = -1; // prio3 var opdrgereed = XMLval(opdrachten[i], "datumgereed"); // NEW/UPD var opdrkosten = XMLval(opdrachten[i], "kosten"); // NEW/UPD var opdruren = XMLval(opdrachten[i], "uren"); // NEW/UPD var opdrmateriaal = XMLval(opdrachten[i], "materiaal"); // NEW/UPD var opdruurloon = XMLval(opdrachten[i], "uurloon"); // NEW/UPD var opdrkenmerken = (opdrachten[i].getElementsByTagName("kenmerk")); // NEW/UPD var opdrregels = (opdrachten[i].getElementsByTagName("mld_opdr_materiaal")); // NEW/UPD/DEL Opdrachtregels. var kpn_key = -1; var mld_key = -1; // Maken we aan of bepalen we uit de melding/volgnr. var opdrvolgnr = -1; // Maken we aan of bepalen we uit de melding/volgnr. var opdr_key = -1; // Maken we aan of bepalen we uit de melding/volgnr. var oldstatus = -1; var mld_fields = []; // Bij te werken velden. var opdr_fields = []; // Bij te werken velden. if (opdrid == null) { // Voorkom problemen als key-attribuut ontbreekt/leeg! opdrid = ''; } if (externnr == null) { // Voorkom problemen als externnr-node ontbreekt/leeg! externnr = ''; } if (externopdrnr == null) { // Voorkom problemen als externopdrnr-node ontbreekt/leeg! externopdrnr = ''; } if (voor_email == null) { // Voorkom problemen als het emailadres ontbreekt/leeg! voor_email = ''; } // Zoek de voorkey op aan de hand van het emailadres tsql = "SELECT prs_perslid_key " + " FROM prs_v_aanwezigperslid " + " WHERE UPPER(prs_perslid_email) = UPPER(" + safe.quoted_sql(voor_email) + ")"; var oRs = Oracle.Execute(tsql); if (!oRs.eof) { voor_key = oRs("prs_perslid_key").Value; } oRs.Close(); // Kijk of er een opdracht bestaat met dit externe opdracht nummer. // Ben je bang dat het nummer vaker voorkomt dan kun je deze prefixen in de xsl tsql = "SELECT MIN(mld_opdr_key) mld_opdr_key, COUNT(*) aantal" + " FROM mld_opdr" + " WHERE mld_opdr_id ="+ safe.quoted_sql(externopdrnr); var oRs = Oracle.Execute(tsql); if (oRs("aantal").Value == 1) { tsql = "SELECT mld_melding_key || '/' || mld_opdr_bedrijfopdr_volgnr mld_opdr_nr" + " FROM mld_opdr" + " WHERE mld_opdr_key ="+ oRs("mld_opdr_key").Value; var oRs = Oracle.Execute(tsql); opdrid = oRs("mld_opdr_nr").Value; // Als het externe opdracht nummer al bestaat weten we zeker dat het om een update gaat. opdraction = "update"; } oRs.Close(); if (opdraction == "insert") { // Let op: mld_melding_externnr is niet gegarandeerd uniek: meerdere externe systemen // kunnen dezelfde (externe) nummering gebruiken // TODO: Bepalen meldingen beperken tot alleen die meldingen die zijn aangemaakt door betreffende API-user! // Of beter: WHERE ORDBOF schrijfrechten op de melding // Wel: verderop controleren we al wel of je canAddOpdr hebt tsql = "SELECT MIN(mld_melding_key) mld_melding_key, COUNT(*) aantal" + " FROM mld_melding" + " WHERE mld_melding_externnr="+ safe.quoted_sql(externnr); var oRs = Oracle.Execute(tsql); switch (oRs("aantal").Value) { case 0: // Automatisch melding aanmaken. // We ondersteunen hier alleen extreem simpele meldingen (alles default). // Wil je meer? Dan maak je maar zelf een melding aan via de MLDAPI. if (stdm_key && stdm_key > 0) { 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 = " + stdm_key + " AND sm.mld_stdmelding_verwijder IS NULL"; oRs = Oracle.Execute(tsql); if (oRs.eof) { resultcode = 3; resulttekst = "Undefined stdmelding " + stdm_key; } if (isNaN(voor_key)) { resultcode = 3; resulttekst = "Undefined 'voor': " + voor_email; } // Hier heb ik een geldige stdm_key. if (resultcode == -1) // Nog steeds geen fouten. { // Bepaal kostenplaats via voor-user // Als die voor exact één kostenplaats is gemandateerd dan gebruiken // we die kostenplaats. Anders laten we de kostenplaats gewoon leeg. sql = "SELECT pk.prs_kostenplaats_key, prs_kostenplaats_nr" + " FROM prs_perslidkostenplaats ppk," + " prs_kostenplaats pk" + " WHERE pk.prs_kostenplaats_key = ppk.prs_kostenplaats_key" + " AND ppk.prs_perslid_key = " + voor_key + " AND prs_kostenplaats_verwijder IS NULL" + " AND prs_perslidkostenplaats_boeken = 1"; var oRs = Oracle.Execute(sql); if (!oRs.Eof) { kpn_key = oRs("prs_kostenplaats_key").Value || -1; // Kan leeg zijn als voor alles gemandateerd kpn_nr = oRs("prs_kostenplaats_nr").Value; oRs.MoveNext(); if (!oRs.Eof) // Er zijn er meerdere { kpn_key = -1; __Log("Gemandateerd voor meerdere kostenplaatsen dus genegeerd."); } else __Log("Uitsluitend gemandateerd voor kostenplaats: " + kpn_nr); } } if (opdr_kpn && opdr_kpn != "") { tsql = "SELECT prs_kostenplaats_key" + " FROM prs_kostenplaats" + " WHERE prs_kostenplaats_verwijder IS NULL" + " AND (prs_kostenplaats_begin IS NULL" + " OR prs_kostenplaats_begin < SYSDATE)" + " AND (prs_kostenplaats_eind IS NULL" + " OR prs_kostenplaats_eind > SYSDATE)" + " AND prs_kostenplaats_upper = " + safe.quoted_sql_upper(opdr_kpn); // Unique oRs = Oracle.Execute(tsql); if (!oRs.EoF) { var opdr_kpn_key = oRs("prs_kostenplaats_key").Value; tsql = "SELECT ''" + " FROM prs_perslidkostenplaats" + " WHERE prs_perslidkostenplaats_boeken = 1" + " AND (prs_kostenplaats_key = " + opdr_kpn_key + " OR prs_kostenplaats_key IS NULL)" // Mandated for all + " AND prs_perslid_key = " + voor_key; oRs = Oracle.Execute(tsql); if (!oRs.EoF) // persoon gemandateerd voor gegeven kostenplaats kpn_key = opdr_kpn_key; } } if (resultcode == -1) // Nog steeds geen fouten. { var meld_oms = "Automatisch aangemaakte melding tbv. werkzaamheden geïnitieerd in extern systeem met referentie: "+ externnr; if (meldingtekst != null) { meld_oms = meld_oms + "\n" + meldingtekst; } mld_key = mld.insertmelding(stdm_key, { kostenplaats_key: kpn_key, perslid_key: voor_key, fields: [{ dbs: "mld_melding_externnr", typ: "varchar", val: externnr }, { dbs: "mld_melding_omschrijving", typ: "varchar", val: meld_oms }, { dbs: "mld_melding_onderwerp", typ: "varchar", val: onderwerp } ] }); // mld.insertmelding heeft al op status 2 (nieuw) gezet mld.setmeldingstatus(mld_key, 4); } } break; case 1: mld_key = oRs("mld_melding_key").Value; break; default: { // Te veel kunnen we nog niet echt aan? } } oRs.Close(); if (mld_key < 0) { // Tja, dan wordt het lastig? resultcode = 7; resulttekst = "Melding '{0}' cannot be identified uniquely".format(externnr); } if (resultcode == -1) // Nog steeds geen fouten. { var this_melding = mld.func_enabled_melding(mld_key); if (!this_melding.canAddOpdr) { resultcode = 4; resulttekst = "Not authorized"; } } // Hier heb ik een geldige mld_key (nieuw of bestaand). if (resultcode == -1) // Nog steeds geen fouten. { // Bepaal opdrachttype. tsql = "SELECT mld_typeopdr_key" + " FROM mld_typeopdr" + " WHERE mld_typeopdr_key="+ topdr_key; var oRs = Oracle.Execute(tsql); if (oRs.eof) { resultcode = 8; resulttekst = "Undefined opdrachttype "+ topdr_key; } oRs.Close(); } // Hier heb ik een geldige topdr_key. if (resultcode == -1) // Nog steeds geen fouten. { // Bepaal uitvoerende. tsql = "SELECT prs_bedrijf_key" + " FROM prs_bedrijf" + " WHERE prs_bedrijf_key="+ uitv_key + " AND prs_bedrijf_verwijder IS NULL"; var oRs = Oracle.Execute(tsql); if (oRs.eof) { resultcode = 8; resulttekst = "Undefined uitvoerende "+ uitv_key; } oRs.Close(); } // Hier heb ik een geldige uitv_key. if (resultcode == -1) // Nog steeds geen fouten. { // Alvast de nieuwe opdracht aanmaken. Rest komt later. var mld_info = mld.mld_melding_info(mld_key); var fields = [ { dbs: "mld_opdr_key", typ: "key", seq: "mld_s_mld_opdr_key" }, { dbs: "mld_opdr_module", typ: "varchar", val: "MLD" }, { dbs: "mld_melding_key", typ: "key", val: mld_key }, { dbs: "prs_kostenplaats_key", typ: "key", val: mld_info.kostenpl_key }, { dbs: "mld_uitvoerende_keys", typ: "key", val: uitv_key }, { dbs: "mld_typeopdr_key", typ: "key", val: topdr_key }, { dbs: "mld_opdr_bedrijfopdr_volgnr", typ: "sql", val: "mld.bepaalopdrmeldingvolgnr(" + mld_key +")" }, { dbs: "mld_opdr_datumbegin", typ: "datetime", val: new Date() } ]; if (opdrachttekst != null) { fields.push({ dbs: "mld_opdr_omschrijving", typ: "varchar", val: opdrachttekst, len: 4000 }); } // Flag, ignore if invalid if (!isNaN(flag) && flag >= 0 && flag < S("mld_opdracht_flags")) { fields.push({ dbs: "mld_opdr_flag", typ: "number", val: flag }); } var mldIns = buildInsert("mld_opdr", fields, { noValidateToken: true }); var sql = mldIns.sql; var err = Oracle.Execute(sql, true); if (err.friendlyMsg) { resultcode = 9; resulttekst = "Database error: "+ err.friendlyMsg; } opdr_key = mldIns.sequences["mld_opdr_key"]; // Hier heb ik de geldige opdr_key (igv. insert). tsql = "UPDATE mld_opdr" + " SET mld_opdr_id = " + safe.quoted_sql(externopdrnr) + " WHERE mld_opdr_key=" + opdr_key; Oracle.Execute(tsql); mld.setopdrachtstatus (opdr_key, 5); mld.updatemeldingstatus (mld_key, 0); } } else if (opdraction == "update" || opdraction == "note") { // Bestaande opdracht zoeken var idarr = opdrid.split('/'); mld_key = parseInt(idarr[0], 10); opdrvolgnr = parseInt(idarr[1], 10); if (isNaN (mld_key) || isNaN (opdrvolgnr)) { resultcode = 2; resulttekst = "Invalid opdracht id (key="+ opdrid +")"; } else { tsql = "SELECT mld_opdr_key" + " FROM mld_opdr" + " WHERE mld_melding_key="+ mld_key + " AND mld_opdr_bedrijfopdr_volgnr="+ opdrvolgnr; var oRs = Oracle.Execute(tsql); if (oRs.eof) { resultcode = 5; resulttekst = "Non existent opdracht"; } else { // Hier heb ik de geldige opdr_key (igv. update). opdr_key = oRs("mld_opdr_key").Value; } oRs.Close(); } // als de action note is dan vullen we alleen de notitie en zijn we verder klaar. if (resultcode == -1 && opdraction == "note") { tsql = "INSERT INTO mld_opdr_note(mld_opdr_key, prs_perslid_key, mld_opdr_note_omschrijving)" + " VALUES (" + opdr_key + "," + user_key + "," + safe.quoted_sql(opdropmerking) + ")"; Oracle.Execute(tsql); resultcode = 0; // we zijn klaar. } } else { resultcode = 2; resulttekst = "Undefined operation (type=" + opdraction + ")"; } if (resultcode == -1) { // Hier heb ik een geldige opdr_key. var this_opdr = mld.func_enabled_opdracht(opdr_key); if (!this_opdr.canChange) { resultcode = 4; resulttekst = "Not authorized"; } var mld_opdr = mld.mld_opdr_info(opdr_key); // Bevat alle info van de opdracht. var stdm_info = mld.mld_stdmeldinginfo(mld_opdr.stdm_key); // Initialiseer (nog eens) enkele opdrachtgegevens tbv. de response of vervolg. opdrid = mld_key + "/" + mld_opdr.mld_opdr_bedrijfopdr_volgnr; oldstatus = mld_opdr.opdr_status; topdr_key = mld_opdr.opdr_type; var autoorder = stdm_info.autoorder; if (autoorder) { if (MLDremark > 0) MLDremark |= 4; // 'Altijd' bitje zetten if (ORDremark > 0) ORDremark |= 4; // 'Altijd' bitje zetten } var mut_datum = new Date(); if (txt_mut_datum && mld_opdr.typeopdr_afmeldmarge>0) { var mut_datum = XMLtoJsDate(txt_mut_datum); var maxmarge = new Date(); maxmarge.setDate(maxmarge.getDate() - mld_opdr.typeopdr_afmeldmarge); if (mut_datum < maxmarge) mut_datum = maxmarge; // te lang geleden } // Dit zijn de wijzigingen, die voeren we alleen uit bij een geldige statuswijziging // of geen statuswijziging var canOpmChange = opdraction == "insert" || this_opdr.canOpmChange && ( S("mld_afhandeling_restrict_edit") == 0 // Hier mag het afhandeling veld altijd aangepast worden || opdrstatus != null && (oldstatus == 5 || oldstatus == 8) && // En anders alleen bij het afmelden, afwijzen of annuleren ( opdrstatus == 'ORDAFM' && this_opdr.canClose // Verifieer dat we gaan (en mogen) afmelden || opdrstatus == 'ORDCAN' && this_opdr.canCancel)); // Verifieer dat we gaan (en mogen) annuleren if (opdropmerking != null && canOpmChange) { // opmerking bij de opdracht var new_opm = opdropmerking; if (ORDremark == 5) // Append { sql = "SELECT mld_opdr_opmerking" + " FROM mld_opdr" + " WHERE mld_opdr_key = " + opdr_key; oRs = Oracle.Execute(sql); if (oRs("mld_opdr_opmerking").Value) new_opm = oRs("mld_opdr_opmerking").Value + "\n" + new_opm; oRs.Close(); } if (ORDremark == 5 || ORDremark == 6) { opdr_fields.push({ dbs: "mld_opdr_opmerking", typ: "varchar", val: new_opm, track: L("lcl_mld_inf_Opmerking"), len: 4000 }); } // opmerking bij de melding var new_mld_opm = opdropmerking; if (MLDremark == 5) // Append { sql = "SELECT mld_melding_opmerking" + " FROM mld_melding" + " WHERE mld_melding_key = " + mld_opdr.mld_key; oRs = Oracle.Execute(sql); if (oRs("mld_melding_opmerking").Value) new_mld_opm = oRs("mld_melding_opmerking").Value + "\n" + new_mld_opm; oRs.Close(); } if (MLDremark == 5 || MLDremark == 6) { mld_fields.push({ dbs: "mld_melding_opmerking", typ: "varchar", val: new_mld_opm, track: L("lcl_mld_inf_Opmerking"), len: 4000 }); } } if (opdrkosten != null && opdrkosten != 0) { if (this_opdr.iamBedrijfContact && opdrkosten > S("mld_max_kosten_extern")) { resultcode = 10; resulttekst = L("lcl_opdr_cost_exceed") + S("mld_max_kosten_extern"); } } if (opdrkosten != null && (opdraction == "insert" || this_opdr.canUrenMatChange)) opdr_fields.push({ dbs: "mld_opdr_kosten", typ: "float", val: opdrkosten, track: L("lcl_total_cost") }); if (opdruren != null && (opdraction == "insert" || this_opdr.canUrenMatChange)) opdr_fields.push({ dbs: "mld_opdr_uren", typ: "float", val: opdruren, track: L("lcl_hours") }); if (opdrmateriaal != null && (opdraction == "insert" || (this_opdr.typeopdr_materiaal < 2 && this_opdr.canUrenMatChange))) opdr_fields.push({ dbs: "mld_opdr_materiaal", typ: "float", val: opdrmateriaal, track: L("lcl_mld_material") }); if (opdruurloon != null) opdr_fields.push({ dbs: "mld_opdr_uurloon", typ: "float", val: opdruurloon, track: L("lcl_prs_person_uurloon") }); var ins_srtdiscipline_prefix = mld.mld_prefix(mld_key); var formattedID = ins_srtdiscipline_prefix + opdrid; var orddat_tracking = ""; if (opdrgereed != null && (opdraction == "insert" || this_opdr.canDatesChange)) { var old_einddatum = mld_opdr.mld_opdr_einddatum; var new_einddatum = XMLtoJsDate(opdrgereed); if (old_einddatum == null || old_einddatum.midnight().getTime() != new_einddatum.midnight().getTime()) // Difference? (Check Date only) { opdr_fields.push({ dbs: "mld_opdr_einddatum", typ: "datetime", val: new_einddatum }); orddat_tracking = L("lcl_ord_is_orddattrack").format(formattedID) + ": " + buildTrackText("date", old_einddatum, new_einddatum); } if (autoorder) // Ooit: net als appendRemark via json configureerbaar maken? mld_fields.push({ dbs: "mld_melding_einddatum", typ: "datetime", val: new_einddatum, track: L("lcl_mld_enddate") }); } // Plandatum wordt apart getracked want deze heeft zijn eigen tracking code (ORDPLD) var ordpld_tracking = ""; if (plandatum != null && (opdraction == "insert" || this_opdr.canPlanDatesChange)) { var new_plandatum; if (plandatum == "") { new_plandatum = null; } else { new_plandatum = XMLtoJsDate(plandatum); } var old_plandatum = mld_opdr.mld_opdr_plandatum; if ((old_plandatum != null || new_plandatum != null) && (old_plandatum == null || new_plandatum == null || old_plandatum.getTime() != new_plandatum.getTime())) // Difference? { opdr_fields.push({ dbs: "mld_opdr_plandatum", typ: "datetime", val: new_plandatum }); ordpld_tracking = L("lcl_ord_is_ordpldtrack").format(formattedID) + ": " + buildTrackText("datetime", old_plandatum, new_plandatum); } } // Plandatum2 wordt apart getracked want deze heeft zijn eigen tracking code (ORDPL2) var ordpl2_tracking = ""; if ((S("mld_use_plandate2") & 2 && plandatum2 != null) && (opdraction == "insert" || this_opdr.canPlanDatesChange)) { var new_plandatum2; if (plandatum2 == "") { new_plandatum2 = null; } else { new_plandatum2 = XMLtoJsDate(plandatum2); } var old_plandatum2 = mld_opdr.mld_opdr_plandatum2; if ((old_plandatum2 != null || new_plandatum2 != null) && (old_plandatum2 == null || new_plandatum2 == null || old_plandatum2.getTime() != new_plandatum2.getTime())) // Difference? { opdr_fields.push({ dbs: "mld_opdr_plandatum2", typ: "datetime", val: new_plandatum2 }); ordpl2_tracking = L("lcl_ord_is_ordpl2track").format(formattedID) + ": " + buildTrackText("datetime", old_plandatum2, new_plandatum2); } } if ((this_opdr.canHervatten && resume) || (this_opdr.canOnderbreken && halt)) { status_tracking_key = mld.opdr_hltrsm(opdr_key, { halt: halt, resume: resume }); // Zorgt voor het zetten van de mld_opdr.mld_opdr_halted waarde en het tracken van "ORDHLT" of "ORDRSM". } else if (resume || halt) { resultcode = 4; if (mld_opdr.opdr_status != 8) // Een halt of resume is alleen mogelijk in de opdrachtstatus Geaccepteerd(8). resulttekst = "Not authorized for" + (resume? " ORDRSM" : " ORDHLT"); else if (!this_opdr.canHervatten && resume && mld_opdr.halted) // Van halted naar resumed. resulttekst = "Not authorized for ORDRSM"; else if (!this_opdr.canOnderbreken && halt && !mld_opdr.halted) // Van resumed naar halted. resulttekst = "Not authorized for ORDHLT"; else { // De opdracht was al halted of resume. // Als er nog geen "ORDHLT" of "ORDRSM" tracking aanwezig was, dan moet deze tracking nu wel worden toegevoegd. // Dit moet in de functie opdr_hltrsm worden geforceerd, anders doet de functie dat niet. var forcetracking = false; var sql = "SELECT COUNT(*) aantal" + " FROM fac_tracking t" + " , fac_srtnotificatie sn" + " WHERE t.fac_srtnotificatie_key = sn.fac_srtnotificatie_key" + " AND t.fac_tracking_refkey = " + opdr_key + " AND sn.fac_srtnotificatie_xmlnode = 'opdracht'" + " AND sn.fac_srtnotificatie_code IN ('ORDHLT', 'ORDRSM')"; oRs = Oracle.Execute(sql); if (oRs("aantal").Value == 0) forcetracking = true; if (((halt && mld_opdr.halted) || (resume && !mld_opdr.halted)) && forcetracking) { // De status staat al op halted of resume maar er is nog geen "ORDHLT" of "ORDRSM" tracking aanwezig. // Dan deze tracking alsnog aanmaken m.b.v. de functie opdr_hltrsm. // De functie zorgt ook voor het leegmaken van verplichte onderbreek kenmerken bij het hervatten. status_tracking_key = mld.opdr_hltrsm(opdr_key, { halt: halt, resume: resume, forcetracking: true }); // Zorgt voor het zetten van de mld_opdr.mld_opdr_halted waarde en het tracken van "ORDHLT" of "ORDRSM". } resultcode = -1; // Hij was al halted of resumed, niet erg dus. } } if (S("mld_use_plandate2") & 2) { var latest_pld = new_plandatum || mld_opdr.mld_opdr_plandatum; var latest_pl2 = new_plandatum2 || mld_opdr.mld_opdr_plandatum2; if (latest_pld != null && latest_pl2 != null // We have a plan-start-date and a plan-end-date && (new_plandatum || new_plandatum2) // and at least 1 of them is new && latest_pld.getTime() > latest_pl2.getTime()) // plan-start-date is later than plan-end-date { resultcode = 6; resulttekst = L("lcl_opdr_plandate") + " (" + latest_pld + ") later than " + L("lcl_opdr_plandate2") + " (" + latest_pl2 + ")"; } } // Flag, ignore if invalid if (!isNaN(flag) && flag >= 0 && flag < S("mld_opdracht_flags")) { opdr_fields.push({ dbs: "mld_opdr_flag", typ: "number", val: flag }); } // We weten nu de updates, straks voeren we deze pas uit // Eerst de eventuele statuswijzigingen var newstatus = -1; if (opdrstatus != null) { // Er is dus wel een status meegegeven switch (opdrstatus) { case 'ORDACP' : if (oldstatus == 8) { // dan gewoon negeren } else // aanpassen { if (this_opdr.canAccept) { if (oldstatus == 5) { newstatus = 8; } else { resultcode = 2; resulttekst = "Invalid status change"; } } else { resultcode = 4; resulttekst = "Not authorized for ORDACP"; } } break; case 'ORDCAN' : if (oldstatus == 1) { // dan gewoon negeren } else // aanpassen { if (this_opdr.canCancel) { if (oldstatus == 5 || oldstatus == 8) { newstatus = 1; } else { resultcode = 2; resulttekst = "Invalid status change"; } } else { resultcode = 4; resulttekst = "Not authorized for ORDCAN"; } } break; case 'ORDAFM' : if (oldstatus == 6 || oldstatus == 7) { // al afgemeld of verwerkt, dan gewoon negeren } else // aanpassen { if (this_opdr.canClose) { if (oldstatus == 5 || oldstatus == 8 ) { newstatus = 6; } else { resultcode = 2; resulttekst = "Invalid status change"; } } else { resultcode = 4; resulttekst = "Not authorized for ORDAFM"; } } break; case 'ORDAFR' : if (oldstatus == 9) { // dan gewoon negeren } else { if (this_opdr.canFinish) { if (oldstatus == 6 ) { newstatus = 9; } else { resultcode = 2; resulttekst = "Invalid status change"; } } else { resultcode = 4; resulttekst = "Not authorized for ORDAFR"; } } break; default: resultcode = 3; resulttekst = "Invalid status"; } // switch } if (resultcode == -1) { // Nog steeds geen fouten // Construct the update if (this_opdr.canChange) { if (opdr_fields.length > 0) { var mldUpd = buildTrackingUpdate("mld_opdr", "mld_opdr_key = " + opdr_key, opdr_fields, { noValidateToken: true }); Oracle.Execute(mldUpd.sql); update_tracking_key = mld.trackopdrachtupdate(opdr_key, L("lcl_ord_is_updatedbysoap") + "\n" + mldUpd.trackarray.join("\n")); if (mut_datum) // Antedateren voor SLA rapportages. { var sql = "BEGIN fac.backtrackaction('ORDUPD', " + opdr_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;" Oracle.Execute(sql); } // Tracken en notificeren van de einddatum (ORDDAT) (notificeren aan de gebouwverantwoordelijke van het betreffende gebouw van de onderliggende melding). if (orddat_tracking != "") { datum_tracking_key = mld.trackopdreinddatumupdate(opdr_key, orddat_tracking); } // Tracken en notificeren van de geplande aanvang datum (ORDPLD) (notificeren aan interne contactpersoon). if (ordpld_tracking != "") { datum_tracking_key = mld.trackopdrplandatumupdate(opdr_key, ordpld_tracking); } // Tracken en notificeren van de geplande einddatum (ORDPL2) (notificeren aan interne contactpersoon). if (S("mld_use_plandate2") & 2 && ordpl2_tracking != "") { datum_tracking_key = mld.trackopdrplandatum2update(opdr_key, ordpl2_tracking); } } } var this_mld = mld.func_enabled_melding(mld_opdr.mld_key); // mag ik de melding ook aanpassen? if (this_mld.canClose && (autoorder || MLDremark > 0)) { if (mld_fields.length>0) { var mldUpd = buildTrackingUpdate("mld_melding", "mld_melding_key = " + mld_opdr.mld_key, mld_fields, { noValidateToken: true }); Oracle.Execute(mldUpd.sql); var formattedID = stdm_info.ins_srtdiscipline_prefix+mld_opdr.mld_key + " ("+ stdm_info.discipline_omschrijving + "/"+ stdm_info.stdmelding_omschrijving +")"; mld.trackmeldingupdate(mld_opdr.mld_key, L("lcl_mld_is_updatedbysoap").format(formattedID) + "\n" + mldUpd.trackarray.join("\n")); if (mut_datum) // Antedateren voor SLA rapportages. { var sql = "BEGIN fac.backtrackaction('MLDUPD', " + mld_opdr.mld_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;" Oracle.Execute(sql); } } } // De kenmerken. update_tracking_key = coalesce(update_tracking_key, upsertKenmerk(opdrkenmerken, topdr_key, opdr_key)); // De opdrachtregels. update_tracking_key = coalesce(update_tracking_key, upsertOpdrRegels(opdrregels, mld_opdr)); if (newstatus != -1) { add_note(); // zodat we note_key hebben mld.setopdrachtstatus(opdr_key, newstatus, null, note_key); // Hier terugchecken van de status tsql = "SELECT mld_statusopdr_key FROM mld_opdr" + " WHERE mld_opdr_key="+ opdr_key; oRs = Oracle.Execute(tsql); if (oRs("mld_statusopdr_key").Value == newstatus) { resulttekst = "Status set to " + opdrstatus; if (newstatus == 8) { // Opdracht is geaccepteerd ("ORDACP"). // Ik kan hier zelf bepalen of de actieve opdracht onderbroken moet worden (hltactive). // Als de opdrachten niet sequentieel uitgevoerd moeten worden, dan wordt er ook geen actieve opdracht gevonden. if (mld_opdr.contactpers_key < 0) var activeopdr = mld.getactiveopdracht(opdr_key, user_key, mld_opdr.uitvoerende_key); // Haal de actieve opdracht op. else var activeopdr = mld.getactiveopdracht(opdr_key); // Haal de actieve opdracht op. var activeopdr_key = activeopdr.opdr_key; var activeopdracht = activeopdr.opdracht; var hltactive = (activeopdr_key > 0); var onHold = ((mld_opdr.typeopdr_sequential & 4) == 4); // Staat "Onderbroken starten" aan? if (hltactive) { // Er is 1 actieve opdracht die onderbroken moet worden. Dit doen we door een "ORDHLT" tracking op die actieve opdracht te doen. Oracle.Execute("UPDATE mld_opdr SET mld_opdr_halted = 1 WHERE mld_opdr_key = " + activeopdr.opdr_key); shared.trackaction("ORDHLT", activeopdr.opdr_key); } else if (onHold) { // Als "Onderbroken starten" aan staat dan deze opdracht op "On Hold" zetten. Dan geen "ORDHLT" tracking genereren. Oracle.Execute("UPDATE mld_opdr SET mld_opdr_halted = 1 WHERE mld_opdr_key = " + opdr_key); } } if (mut_datum && opdrstatus) // Tracking antedateren voor SLA rapportages. { // 'Toevallig' loopt opdrstatus 1-op-1 met onze trackingcodes var sql = "BEGIN fac.backtrackaction("+safe.quoted_sql(opdrstatus)+", " + opdr_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;" Oracle.Execute(sql); // Statuswijzigingen wel even tracken var txt = { "ORDAFM": L("lcl_ord_is_ordafm"), "ORDACP": L("lcl_ord_is_ordacp"), "ORDAFR": L("lcl_ord_is_ordafr") }[opdrstatus]; update_tracking_key = coalesce(update_tracking_key, mld.trackopdrachtupdate(opdr_key, L("lcl_ord_is_ordupd") + "\n" + txt + L("lcl_trackto") + toDateTimeString(mut_datum))); } // Zijn er nog lopende opdrachten tsql = "SELECT COUNT ( * ) lopend FROM mld_opdr" + " WHERE mld_melding_key = " + mld_key + " AND mld_statusopdr_key NOT IN (1, 2, 6, 7, 9)"; // (1=afgewezen, 2=niet akkoord, 6=afgemeld, 7=verwerkt en 9=afgerond) oRs = Oracle.Execute(tsql); if (oRs("lopend").Value == 0) { // Er zijn alleen opdrachten met status 1 (Afgewezen) of 6/9 (Afgemeld/Afgerond) // Check of setting bij opdrachttype automatisch sluiten ALTIJD (= 2) toestaat. // Ondertussen kan de status van de opdracht aangepast zijn. // De waarde this_mld.canClose kan daarom niet meer juist zijn omdat deze van de status afhankelijk is. // Daarom moet de waarde opnieuw bepaald worden (PROR#90212 / PROR#90706). var this_mld2 = mld.func_enabled_melding(mld_opdr.mld_key); tsql = "SELECT mld_typeopdr_sluitmelding FROM mld_typeopdr" + " WHERE mld_typeopdr_key = " + topdr_key; var oRs = Oracle.Execute(tsql); // Afhankelijk van sluitmelding nu melding status zetten (0=nooit, 1=vragen en 2=altijd) // Als de laatste opdracht een cancel was dan wordt de melding niet afgemeld. if ((oRs("mld_typeopdr_sluitmelding").Value == 2 || oRs("mld_typeopdr_sluitmelding").Value == 1) && this_mld2.canClose && opdrstatus != 'ORDCAN') { mld.setmeldingstatus (mld_key, 5); // Afgemeld var sql = "BEGIN fac.backtrackaction('MLDAFM', " + mld_key + ", " + user_key + ", " + mut_datum.toSQL(true) +"); END;" Oracle.Execute(sql); // Statuswijzigingen wel even tracken mld.trackmeldingupdate(mld_key, L("lcl_mld_is_mldupd") + "\n" + L("lcl_mld_is_mldafm") + L("lcl_trackto") + toDateTimeString(mut_datum)); // Handle workflow actions for completion: mld.nextworkflowstep(mld_key, 1); // 1 = completed } else // Dan zetten we de Melding hier terug naar Geaccepteerd indien die Uitgegeven was // Zodat die bij de FO weer onder Inbehandeling valt. mld.setmeldingstatus (mld_key, 4); // Geaccepteerd } } else { resultcode = 1; resulttekst = "Status not set to "+opdrstatus+" (is "+oRs("mld_statusopdr_key").Value+")"; } } } } if (resultcode == -1) // Nog steeds geen fouten. { var tracking_key = coalesce(coalesce(status_tracking_key, datum_tracking_key), update_tracking_key); // volgorde van belangrijkheid add_note(tracking_key); // voor als nog niet eerder gebeurd resultcode = 0; // Ik heb gedaan wat ik moest en mocht doen voor deze opdracht. } else if (resultcode > 0) { var logtxt = "api_opdrsoap fail.\nResultcode: {0}\nReturntekst: {1}\nOpdracht: {2}\nOldstatus: {3}".format(resultcode, resulttekst, opdrid, oldstatus); if (resulttekst.match(/^Not authorized/)) // Dit komt heel vaak voor door updates op gesloten opdrachten. __Log(logtxt); // Het vervuilt de logfile veel te veel else __DoLog(logtxt, "#00FF00"); } var binfo = { returncode: resultcode, returntekst: resulttekst, // executed:sql, // debug datum: nowtxt, externnr: externnr } var FCLTBody = xmlResp.createElement("opdracht"); // 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 opdracht-nodes zijn behandeld. // Voeg een notitie toe en koppel hem eventueel direct aan tracking_key function add_note(tracking_key) { if (/*global*/ note_key > 0) return; // hadden we het al gedaan if (opdraction == "update" && opdrnote != null) { var fields = [ { dbs: "mld_opdr_note_key", typ: "key", seq: "mld_s_mld_opdr_note_key" }, { dbs: "mld_opdr_key", typ: "key", val: opdr_key }, { dbs: "prs_perslid_key", typ: "key", val: user_key }, { dbs: "mld_opdr_note_flag", typ: "number", val: opdrnoteflag || 4 }, // default alleen uitvoerende, +1 voor FE-zichtbaar { dbs: "mld_opdr_note_omschrijving", typ: "varchar", val: opdrnote, len: 4000 } ]; var noteIns = buildInsert("mld_opdr_note", fields, { noValidateToken: true }); note_key = noteIns.sequences["mld_opdr_note_key"]; Oracle.Execute(noteIns.sql); if (!(tracking_key > 0)) { // Er is alleen een losse notitie. De opdracht is niet aangepast. if ((opdrnoteflag & 1) == 1) // voor FE-zichtbaar tracking_key = mld.trackmeldingaddnote(mld_key); // MLDNOT tracking. else tracking_key = mld.trackopdrachtaddnote(opdr_key); // ORDNOB tracking. } var sql = "UPDATE mld_opdr_note" + " SET fac_tracking_key = " + tracking_key + " WHERE mld_opdr_note_key = " + note_key; Oracle.Execute(sql); } } // Als key1 geldig is heeft die de voorkeur, anders keys function coalesce(key1, key2) { if (key1 > 0) return key1; return key2; } function upsertKenmerk(kenmerken, topdr_key, opdr_key) { //Response.Write("lengte:"+ kenmerken.length); var flextrack = []; // eventuele tracking for (var j = 0; j < kenmerken.length; j++) { // Er kan op drie manieren aangegeven worden om welk kenmerk het gaat var kenmerk_attr_key = parseInt(kenmerken[j].getAttribute("key"), 10); var kenmerk_attr_code = kenmerken[j].getAttribute("code"); var kenmerk_naam = kenmerken[j].getAttribute("naam"); // default srtkenmerk on name var srtkenmerk_key_code_omschr = " AND sk.mld_srtkenmerk_upper = " + safe.quoted_sql_upper(kenmerk_naam); if (kenmerk_attr_key > 0) srtkenmerk_key_code_omschr = " AND sk.mld_srtkenmerk_key = " + kenmerk_attr_key; else if (kenmerk_attr_code) srtkenmerk_key_code_omschr = " AND UPPER(sk.mld_srtkenmerk_code) = " + safe.quoted_sql_upper(kenmerk_attr_code); if (kenmerken[j].childNodes.length > 0) var kenmerk_waarde = kenmerken[j].childNodes[0].nodeValue; else var kenmerk_waarde = ""; //Response.Write(kenmerk_naam); //Response.Write(kenmerk_waarde); // Kenmerk_key opzoeken ksql = "SELECT k.mld_kenmerk_key" + " , COALESCE (" + lcl.xsql("k.mld_kenmerk_omschrijving", "k.mld_kenmerk_key") + " , " + lcl.xsql("sk.mld_srtkenmerk_omschrijving", "sk.mld_srtkenmerk_key") + ") kenmerk_omschrijving" + " , sk.mld_srtkenmerk_kenmerktype" + " , sk.mld_srtkenmerk_lengte" + " , sk.fac_kenmerkdomein_key" + " FROM mld_kenmerk k" + " , mld_srtkenmerk sk" + " WHERE (k.mld_typeopdr_key = " + topdr_key + " OR k.mld_kenmerk_niveau = 'P')" + " AND k.mld_srtkenmerk_key = sk.mld_srtkenmerk_key" + " AND k.mld_kenmerk_verwijder IS NULL" + srtkenmerk_key_code_omschr; var oRs = Oracle.Execute(ksql); if (!oRs.eof) { var kenmerk_key = oRs("mld_kenmerk_key").Value; var label = oRs("kenmerk_omschrijving").Value; var kenmerk_type = oRs("mld_srtkenmerk_kenmerktype").Value; var kenmerk_lengte = oRs("mld_srtkenmerk_lengte").Value; var kenmerkdomein_key = oRs("fac_kenmerkdomein_key").Value; // Was het flexkenmerk er al? ksql = "SELECT ko.mld_kenmerkopdr_key, mld_kenmerkopdr_waarde " + " FROM mld_kenmerkopdr ko " + " WHERE ko.mld_opdr_key = " + opdr_key + " AND ko.mld_kenmerk_key = " + kenmerk_key; oRs.Close(); var oRs = Oracle.Execute(ksql); switch (kenmerk_type) { case 'R': case 'r': case 'S': { // read reference fields if (kenmerk_waarde != "") { var kenmerk_ref = kenmerken[j].getAttribute("ref"); if (kenmerk_ref) { kenmerk_waarde = getKenmerkKeyByRef(kenmerkdomein_key, kenmerk_ref, kenmerk_waarde); } } } // geen break, doorvallen naar bijwerken van de kenmerken case 'C': case 'X': case 'N': case 'V': { // We ondersteunen alleen nog maar karakter- en bestandsnaam-velden. // AEG: Maar wat maakt een nummer nu anders dan een karakter ? var vnew = kenmerk_waarde; if (kenmerk_type == 'R' || kenmerk_type == 'r' || kenmerk_type == 'S') { if (vnew) { var oRsd = Oracle.Execute("SELECT fac.getdomeinwaarde(" + kenmerkdomein_key + ", " + safe.quoted_sql(vnew) + ") domeinwaarde FROM DUAL"); vnew = oRsd("domeinwaarde").Value; oRsd.Close(); } } if (!oRs.eof) { var kenmerkopdr_key = oRs("mld_kenmerkopdr_key").Value; var vold = oRs("mld_kenmerkopdr_waarde").Value; // Voor tracking if (kenmerk_type == 'R' || kenmerk_type == 'r' || kenmerk_type == 'S') { if (vold) { var oRsd = Oracle.Execute("SELECT fac.getdomeinwaarde(" + kenmerkdomein_key + ", " + safe.quoted_sql(vold) + ") domeinwaarde FROM DUAL"); vold = oRsd("domeinwaarde").Value; oRsd.Close(); } } if (kenmerk_waarde == "") { // delete characteristic when empty ksql = "DELETE FROM mld_kenmerkopdr WHERE mld_kenmerkopdr_key = " + kenmerkopdr_key; } else { ksql = "UPDATE mld_kenmerkopdr SET mld_kenmerkopdr_waarde = " + safe.quoted_sql(kenmerk_waarde) + " WHERE mld_kenmerkopdr_key = " + kenmerkopdr_key; } Oracle.Execute(ksql); if (vold != vnew) flextrack.push(label + ": " + buildTrackText("varchar", vold, vnew, {nodiff: (kenmerk_type != "C")})); } else { if (kenmerk_waarde != "") { // write a new characteristic with a value only ksql = "INSERT INTO mld_kenmerkopdr (mld_kenmerk_key, mld_opdr_key, mld_kenmerkopdr_waarde) " + "VALUES (" + kenmerk_key + ", " + opdr_key + ", " + safe.quoted_sql(kenmerk_waarde) + ")"; Oracle.Execute(ksql); flextrack.push(label + ": " + buildTrackText("varchar", null, vnew, {nodiff: (kenmerk_type != "C")})); } } } break; // niet doorvallen naar bijlagen case "M": // Folder met bijlagen { //Response.Write(kenmerk_naam); var bijlagen = kenmerken[j].getElementsByTagName("bijlage"); var bi; __Log ('bijlagen.length:' + bijlagen.length); 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"); var Encoding = XMLval(bijlagen[bi], "encoding", true); //Response.Write("Name: " + Name + " size: " + Size); if (Attachment && Name && Size) { var SafeName = safe.filename(Name); var params = flexProps("MLD", opdr_key, String(kenmerk_key), "O"); if (!params.isAllowedName(SafeName)) { __DoLog("Unsafe SOAP file '{0}' ignored.".format(SafeName), "#FFFF00"); } else { __Log("Start saving: " + params.AttachPath + SafeName); CreateFullPath(params.AttachPath); if (Encoding == 'base64') { encodedString2File(params.AttachPath + SafeName, Attachment, "bin.base64"); } else { encodedString2File(params.AttachPath + SafeName, Attachment, "bin.hex"); } var oCrypto = new ActiveXObject("SLNKDWF.Crypto"); var sql = "BEGIN " + " flx.setflexbijlage" + "(" + safe.quoted_sql("MLD") // MLD | RES | .... + ", " + kenmerk_key + ", " + opdr_key + ", " + safe.quoted_sql(params.AttachSubPath) + ", " + "NULL" // diskfilename + ", " + safe.quoted_sql(SafeName) + ", " + fso.GetFile(params.AttachPath + SafeName).Size + ", " + "SYSDATE" + ", " + safe.quoted_sql(oCrypto.hex_sha1_file(params.AttachPath + SafeName)) + ");" + " END;"; Oracle.Execute(sql); __Log("Done saving: " + params.AttachPath + SafeName); flextrack.push(L("lcl_shared_attachment_add").format(label, SafeName)); } } } } } } oRs.Close(); } // Via de GUI komt dit in hetzelfde tracking record als de vaste-velden-wijziging. // Hier komt het in een eigen tracking record. Daar kan ik mee leven. if (flextrack.length) return mld.trackopdrachtupdate(opdr_key, L("lcl_ord_is_updatedbysoap") + "\n" + flextrack.join("\n")); return -1; // else geen trackingkey } function isGoodCurrency(str) { var anum = /^([-\+]?\d{1,6}[.,]?|[-\+]?\d{0,6}[.,]\d{1,7})$/ return anum.test(str); } function upsertOpdrRegels(regels, mld_opdr) { var opdr_key = mld_opdr.opdr_key; var mat_key_list = []; var mat_tracking_arr = []; var tracking_key = -1; for (var r = 0; r < regels.length; r++) { var mat_fields = []; // Bij te werken velden. var id = parseInt(regels[r].getAttribute("id"), 10); var aantal = XMLval(regels[r], "aantal", true); var aantalval = parseFloat(XMLval(regels[r], "aantal")? XMLval(regels[r], "aantal").replace(/,/g,".") : XMLval(regels[r], "aantal")); var eenheidcode = XMLval(regels[r], "eenheidcode", true); var eenheid = XMLval(regels[r], "eenheid", true); var prijs = XMLval(regels[r], "prijs", true); var prijsval = parseFloat(XMLval(regels[r], "prijs")? XMLval(regels[r], "prijs").replace(/,/g,".") : XMLval(regels[r], "prijs")); var btw = XMLval(regels[r], "btw", true); var btwval = parseFloat(XMLval(regels[r], "btw")? XMLval(regels[r], "btw").replace(/,/g,".") : XMLval(regels[r], "btw")); var matcode = XMLval(regels[r], "matcode", true); var omschr = XMLval(regels[r], "omschr", true); var info = XMLval(regels[r], "info", true); var groep = XMLval(regels[r], "groep", true); var extra1 = XMLval(regels[r], "extra1", true); var extra2 = XMLval(regels[r], "extra2", true); var extra3 = XMLval(regels[r], "extra3", true); var extra4 = XMLval(regels[r], "extra4", true); // Zijn er elementen binnen de node "mld_opdr_materiaal_id" //var elementaantal = regels.getElementsByTagName("mld_opdr_materiaal_id")[r].childNodes.length; var sql = "SELECT mld_opdr_materiaal_key" + " FROM mld_opdr_materiaal" + " WHERE mld_opdr_key = " + opdr_key + " AND mld_opdr_materiaal_id = " + id; var oRs = Oracle.Execute(sql); if (aantal && (isNaN (aantalval) || !shared.isGoodNumber(aantalval, false, false, 8, 2))) { resultcode = 10; resulttekst = "Order line " + id + ": Invalid number"; break; } else if (prijs && (isNaN(prijsval) || prijsval < 0 || !isGoodCurrency(prijsval))) { resultcode = 11; resulttekst = "Order line " + id + ": Invalid price"; break; } else if (btw && (isNaN(btwval) || btwval < 0)) { resultcode = 12; resulttekst = "Order line " + id + ": Invalid btw"; break; } else if (aantal == "") { // Aantal is leeg of 0. Opdrachtregel verwijderen (Delete). // Als het aantal niet is meegegeven dan blijft het aantal hetzelfde. if (!oRs.eof) { // Opdrachtregel is aanwezig. var materiaal_key = oRs("mld_opdr_materiaal_key").Value; var sql_del = "DELETE mld_opdr_materiaal" + " WHERE mld_opdr_materiaal_key = " + materiaal_key; Oracle.Execute(sql_del); } else { // Opdrachtregel is niet aanwezig en kan dus niet verwijderd worden. resultcode = 13; resulttekst = "Order line not present. Order line can't be deleted."; break; } } else { // Aantal is meegegeven (Update of Insert). if (oRs.eof) { // Opdrachtregel bestaat niet (Insert). if (!omschr) { resultcode = 14; resulttekst = "Order line " + id + ": Invalid omschr. Omschr not filled"; break; } else { mat_fields = mat_fields.concat( [ { dbs: "mld_opdr_materiaal_key", typ: "key", seq: "mld_s_mld_opdr_materiaal_key" }, { dbs: "mld_opdr_key", typ: "key", val: opdr_key }, { dbs: "mld_opdr_materiaal_id", typ: "number", val: id }, { dbs: "mld_opdr_materiaal_aantal", typ: "float", val: aantalval }, { dbs: "mld_opdr_materiaal_eenheidcode", typ: "varchar", val: eenheidcode, len: 10 }, { dbs: "mld_opdr_materiaal_eenheid", typ: "varchar", val: eenheid, len: 30 }, { dbs: "mld_opdr_materiaal_prijs", typ: "float", val: prijs? prijsval : "" }, { dbs: "mld_opdr_materiaal_code", typ: "varchar", val: matcode, len: 30 }, { dbs: "mld_opdr_materiaal_omschr", typ: "varchar", val: omschr, len: 255 }, { dbs: "mld_opdr_materiaal_info", typ: "varchar", val: info, len: 4000 }, { dbs: "mld_opdr_materiaal_groep", typ: "varchar", val: groep, len: 60 }, { dbs: "mld_opdr_materiaal_extra1", typ: "varchar", val: extra1, len: 60 }, { dbs: "mld_opdr_materiaal_extra2", typ: "varchar", val: extra2, len: 60 }, { dbs: "mld_opdr_materiaal_extra3", typ: "varchar", val: extra3, len: 4000 }, { dbs: "mld_opdr_materiaal_extra4", typ: "varchar", val: extra4, len: 4000 } ]); if ((btw || btw == 0) && (!isNaN (btwval) && btwval >= 0)) { var sql_btw = "SELECT btw.fin_btwtabelwaarde_key" + " FROM fin_btwtabelwaarde btw" + " WHERE btw.fin_btwtabelwaarde_perc = " + btwval + " AND btw.fin_btwtabelwaarde_verwijder IS NULL" + " AND (btw.fin_btwtabelwaarde_verlegd IS NULL OR btw.fin_btwtabelwaarde_verlegd = 0)" + " ORDER BY btw.fin_btwtabel_key"; var oRs_btw = Oracle.Execute(sql_btw); if (!oRs_btw.eof) mat_fields.push({ dbs: "fin_btwtabelwaarde_key", typ: "key", val: oRs_btw("fin_btwtabelwaarde_key").Value, track: L("lcl_mld_opdr_btw"), foreign: "fin_btwtabelwaarde" }); else { resultcode = 12; resulttekst = "Order line " + id + ": Invalid btw"; break; } oRs_btw.Close(); } else if (btw == "") mat_fields.push({ dbs: "fin_btwtabelwaarde_key", typ: "key", val: -1, track: L("lcl_mld_opdr_btw"), foreign: "fin_btwtabelwaarde" }); var matIns = buildInsert("mld_opdr_materiaal", mat_fields, { noValidateToken: true }); var mat_key = matIns.sequences["mld_opdr_materiaal_key"]; var sql = matIns.sql; var err = Oracle.Execute(sql, true); if (err.friendlyMsg) { resultcode = 9; resulttekst = "Order line " + id + ": Database error: "+ err.friendlyMsg; break; } mat_key_list.push(mat_key); } } else { // Opdrachtregel bestaat (Update). // Aantal is groter dan 0. Opdrachtregel toevoegen (Update). // Als aantal 0 is dan is de materiaalregel al verwijderd en kom je hier niet. mat_fields = mat_fields.concat( [ { dbs: "mld_opdr_materiaal_aantal", typ: "float", savewhen: aantal !== null, track: L("lcl_mld_opdr_aantal"), val: aantalval }, { dbs: "mld_opdr_materiaal_eenheidcode", typ: "varchar", savewhen: eenheidcode !== null, track: L("lcl_mld_opdr_eenheidcode"), val: eenheidcode, len: 10 }, { dbs: "mld_opdr_materiaal_eenheid", typ: "varchar", savewhen: eenheid !== null, track: L("lcl_mld_opdr_eenheid"), val: eenheid, len: 30 }, { dbs: "mld_opdr_materiaal_prijs", typ: "float", savewhen: prijs !== null, track: L("lcl_mld_opdr_prijs"), val: (prijs? prijsval : null) }, { dbs: "mld_opdr_materiaal_code", typ: "varchar", savewhen: matcode !== null, track: L("lcl_mld_opdr_code"), val: matcode, len: 30 }, { dbs: "mld_opdr_materiaal_omschr", typ: "varchar", savewhen: omschr !== null, track: L("lcl_mld_opdr_omschr"), val: omschr, len: 255 }, { dbs: "mld_opdr_materiaal_info", typ: "varchar", savewhen: info !== null, track: L("lcl_mld_opdr_info"), val: info, len: 4000 }, { dbs: "mld_opdr_materiaal_groep", typ: "varchar", savewhen: groep !== null, track: L("lcl_mld_opdr_groep"), val: groep, len: 60 }, { dbs: "mld_opdr_materiaal_extra1", typ: "varchar", savewhen: extra1 !== null, track: L("lcl_mld_opdr_extra1"), val: extra1, len: 60 }, { dbs: "mld_opdr_materiaal_extra2", typ: "varchar", savewhen: extra2 !== null, track: L("lcl_mld_opdr_extra2"), val: extra2, len: 60 }, { dbs: "mld_opdr_materiaal_extra3", typ: "varchar", savewhen: extra3 !== null, track: L("lcl_mld_opdr_extra3"), val: extra3, len: 4000 }, { dbs: "mld_opdr_materiaal_extra4", typ: "varchar", savewhen: extra4 !== null, track: L("lcl_mld_opdr_extra4"), val: extra4, len: 4000 } ]); if ((btw || btw == 0) && (!isNaN (btwval) && btwval >= 0)) { var sql_btw = "SELECT btw.fin_btwtabelwaarde_key" + " FROM fin_btwtabelwaarde btw" + " WHERE btw.fin_btwtabelwaarde_perc = " + btwval + " AND btw.fin_btwtabelwaarde_verwijder IS NULL" + " AND (btw.fin_btwtabelwaarde_verlegd IS NULL OR btw.fin_btwtabelwaarde_verlegd = 0)" + " ORDER BY btw.fin_btwtabel_key"; var oRs_btw = Oracle.Execute(sql_btw); if (!oRs_btw.eof) mat_fields.push({ dbs: "fin_btwtabelwaarde_key", typ: "key", val: oRs_btw("fin_btwtabelwaarde_key").Value, track: L("lcl_mld_opdr_btw"), foreign: "fin_btwtabelwaarde" }); else { resultcode = 12; resulttekst = "Order line " + id + ": Invalid btw"; break; } oRs_btw.Close(); } else if (btw == "") mat_fields.push({ dbs: "fin_btwtabelwaarde_key", typ: "key", val: -1, track: L("lcl_mld_opdr_btw"), foreign: "fin_btwtabelwaarde" }); var materiaal_key = oRs("mld_opdr_materiaal_key").Value; mat_key_list.push(materiaal_key); var matUpd = buildTrackingUpdate("mld_opdr_materiaal", "mld_opdr_materiaal_key = " + materiaal_key, mat_fields, { noValidateToken: true }); // Zijn er velden die gewijzigd moeten worden? Als matUpd null is, dan waren alle savewhen condities false en hoeft er niets geupdate te worden. if (matUpd && matUpd.sql && matUpd.trackarray.length) { // Als trackarray.length === 0 dan is er effectief niets aangepast (we tracken alles) Oracle.Execute(matUpd.sql); mat_tracking_arr.push(L("lcl_ord_is_upd_material").format(id) + "\n" + matUpd.trackarray.join("\n")); } } } oRs.Close(); // 1) Nieuwe materiaalbedrag in de opdracht opslaan. // 2) De totaalwaarde opnieuw berekenen want het materiaalbedrag is aangepast. // Dan hebben we het correctie bedrag ook nodig. Dit correctie bedrag moet hetzelfde blijven. var correctie = mld_opdr.corr_cost; var sql_total = "UPDATE mld_opdr" + " SET mld_opdr_materiaal = (SELECT SUM(mld_opdr_materiaal_prijs)" + " FROM mld_opdr_materiaal" + " WHERE mld_opdr_key = " + opdr_key + ")" + " , mld_opdr_kosten = ((COALESCE(mld_opdr_uren, 0) * COALESCE(mld_opdr_uurloon, 0)) +" + " COALESCE((SELECT SUM(mld_opdr_materiaal_prijs)" + " FROM mld_opdr_materiaal" + " WHERE mld_opdr_key = " + opdr_key + "), 0)) +" + " " + correctie + " WHERE mld_opdr_key = " + opdr_key Oracle.Execute(sql_total); } if (mat_tracking_arr.length) { // Er zijn wijzigingen. tracking_key = mld.trackopdrachtupdate(opdr_key, L("lcl_ord_is_updatedbysoap") + "\n" + mat_tracking_arr.join("\n")); } if (mat_key_list.length) { var sql_del = "DELETE mld_opdr_materiaal" + " WHERE mld_opdr_key = " + opdr_key + " AND mld_opdr_materiaal_key NOT IN (" + mat_key_list.join(",") + ")"; Oracle.Execute(sql_del); } return tracking_key; } xmlResp.appendChild(FCLTElement); if (API.apidata.errorhandling == 1 && user.errorhandling() == 1) { if (resultcode > 0) // -1 en 0 zijn 'goed' { Response.Status = '400 Bad Request'; } } 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(); %>