Files
Facilitor/APPL/Shared/save2db.inc
Koen Reefman dfaff61126 FCLT#63770 known_adotypes aangevuld met color, symbol, file & icon
svn path=/Website/branches/v2023.2/; revision=60989
2023-06-29 13:35:34 +00:00

801 lines
38 KiB
PHP

<% /*
$Revision$
$Id$
File: save2db.inc
Description: functions to save records to database
Context: Form u2 action from reserv_Change.asp form
Note:
*/
%>
<!-- #include file="../Shared/adovbs.inc"-->
<%
/* TODO: Kunnen/willen we dit generiek herschrijven naar bind-variabelen?
(of recordset operatie: handig voor tracking oude waarden)
fields is een array van bij te werken velden
telkens een tuple met:
dbs: veldnaam in database
typ: key, altijd integer number. Als -1 of "" dan wordt NULL opgeslagen
date, Tijd wordt er af gestript
datetime, Inclusief tijd
float, Accepteert punten en komma's
number,
varchar Quotes worden escaped
memo Quotes worden escaped
check "on" wordt 1, "" wordt "null". Let op: moet aangemaakt zijn met iface.inc/CHECKBOX
check0 "on" wordt 1, "" wordt 0. Let op: moet aangemaakt zijn met iface.inc/CHECKBOX
time millisecs sinds middernacht
sql voorgedefinieerd, wordt ongewijzigd gebruikt
len: varchar wordt hier op afgekapt
-- een van de volgende view (verplicht) --
frm: Request.Form veld. Als niet meegesubmit dan ook niet opgeslagen!
seq: naam van een sequence
qrs: (nog niet ondersteund!) vergelijk frm maar dan voor QueryString
val: kant en klare waarde, zelf berekend
track: "een tekst" waaronder wijzigingen getrackt moeten worden
of: true waardoor wel oldjsval wordt bepaald maar niet getrackt (mld_behandelaar_key)
foreign: bij tracking nodig als typ=="key", een waarde uit onderstaande foreignKeyTable
of: een functie, voorals we zelf de waarde naar een (andere) tekst willen vertalen
params: vooralsnog geen
result: een sqlstatement met alvast het woord WHERE er achter (opdat het het niet vergeten)
*/
// Zorg dat tbl ook eventueel verwijderde records bevat. Anders kan
// de tracking de oude waarde niet naar tekst omzetten
var __foreignKeyTable; // Indirect om te voorkomen dat bij API's te vroeg lcl.xsql wordt uitgevoerd
function foreignKeyTable(field)
{
if (!__foreignKeyTable)
{
__foreignKeyTable
= {
"ALG_DISTRICT" : { tbl: "alg_district", key: "alg_district_key", desc: "alg_district_omschrijving" },
"ALG_GEBOUW" : { tbl: "alg_gebouw", key: "alg_gebouw_key", desc: "alg_gebouw_code", name: "alg_gebouw_naam" },
"ALG_LOCATIE" : { tbl: "alg_locatie", key: "alg_locatie_key", desc: "alg_locatie_code", name: "alg_locatie_omschrijving" },
"ALG_REGIO" : { tbl: "alg_regio", key: "alg_regio_key", desc: "alg_regio_omschrijving" },
"ALG_RUIMTE" : { tbl: "alg_ruimte", key: "alg_ruimte_key", desc: "alg_ruimte_nr" },
"ALG_SRTGEBOUW" : { tbl: "alg_srtgebouw", key: "alg_srtgebouw_key", desc: lcl.xsql("alg_srtgebouw_omschrijving", "alg_srtgebouw_key") },
"ALG_SRTRUIMTE" : { tbl: "alg_srtruimte", key: "alg_srtruimte_key", desc: lcl.xsql("alg_srtruimte_omschrijving", "alg_srtruimte_key") },
"ALG_SRTTERREINSECTOR" : { tbl: "alg_srtterreinsector", key: "alg_srtterreinsector_key", desc: lcl.xsql("alg_srtterreinsec_omschrijving", "alg_srtterreinsector_key") },
"ALG_TERREINSECTOR" : { tbl: "alg_terreinsector", key: "alg_terreinsector_key", desc: "alg_terreinsector_code", name: "alg_terreinsector_naam"},
"ALG_V_PLAATSAANDUIDING" : { tbl: "alg_v_plaatsaanduiding", key: "alg_onroerendgoed_keys", desc: "alg_plaatsaanduiding" },
"ALG_VERDIEPING" : { tbl: "alg_verdieping", key: "alg_verdieping_key", desc: "alg_verdieping_code", name: "alg_verdieping_code" },
"BES_BESTELOPDR" : { tbl: "bes_bestelopdr", key: "bes_bestelopdr_key", desc: "bes_bestelopdr_id" },
"BES_SRTPROD" : { tbl: "bes_srtprod", key: "bes_srtprod_key", desc: "bes_srtprod_omschrijving" },
"BEZ_ACTIE" : { tbl: "bez_actie", key: "bez_actie_key", desc: lcl.xsql("bez_actie_omschrijving", "bez_actie_key") },
"BEZ_AFSPRAAK" : { tbl: "bez_afspraak", key: "bez_afspraak_key", desc: "'Appointment ' || TO_CHAR(bez_afspraak_datum, 'YYYY-MM-DD HH24:MI')" },
"BEZ_ACTIE_GROEP" : { tbl: "bez_actie_groep", key: "bez_actie_groep_key", desc: "bez_actie_groep_omschrijving" },
"CNT_CONTRACT" : { tbl: "cnt_contract", key: "cnt_contract_key", desc: "cnt_contract_nummer_intern" },
"CNT_CONTRACT_PLAATS" : { tbl: "cnt_contract_plaats", key: "cnt_contract_plaats_key", alias: "plaats",
desc: "(SELECT cp.cnt_plaats_omschrijving"
+ " FROM cnt_v_aanwezigcontract_plaats ap, cnt_v_contract_plaats cp "
+ " WHERE ap.cnt_contract_plaats_key = plaats.cnt_contract_plaats_key"
+ " AND cp.cnt_plaats_key = ap.cnt_alg_plaats_key"
+ " AND cp.cnt_plaats_code = ap.cnt_alg_plaats_code) cnt_plaats_omschrijving" },
"CNT_DISCIPLINE" : { tbl: "cnt_discipline", key: "ins_discipline_key", desc: "ins_discipline_omschrijving" },
"CNT_TERMIJN" : { tbl: "cnt_termijn", key: "cnt_termijn_key", desc: lcl.xsql("cnt_termijn_omschrijving", "cnt_termijn_key" )},
"CTR_DISCIPLINE" : { tbl: "ctr_discipline", key: "ins_discipline_key", desc: "ins_discipline_omschrijving" },
"FAC_FUNCTIE" : { tbl: "fac_functie", key: "fac_functie_key", desc: "lcl.l(fac_functie_omschrijving, 1) || ' (' || fac_functie_code || ')'" },
"FAC_GROEP" : { tbl: "fac_groep", key: "fac_groep_key", desc: "fac_groep_omschrijving" },
"FAC_NOTE_GROUP" : { tbl: "fac_note_group", key: "fac_note_group_key", desc: "fac_note_group_omschrijving"},
"FAC_PROFIEL" : { tbl: "fac_profiel", key: "fac_profiel_key", desc: "fac_profiel_omschrijving" },
"FAC_SRTNOTIFICATIE" : { tbl: "fac_srtnotificatie", key: "fac_srtnotificatie_key", desc: "fac_srtnotificatie_code" },
"FAQ_DISCIPLINE" : { tbl: "ins_tab_discipline", key: "ins_discipline_key", desc: "ins_discipline_omschrijving" },
"FIN_BTWTABEL" : { tbl: "fin_btwtabel", key: "fin_btwtabel_key", desc: "fin_btwtabel_omschrijving" },
"FIN_BTWTABELWAARDE" : { tbl: "fin_btwtabelwaarde", key: "fin_btwtabelwaarde_key", desc: lcl.xsql("fin_btwtabelwaarde_oms", "fin_btwtabelwaarde_key") },
"INS_CONTROLEMODE" : { tbl: "ins_controlemode", key: "ins_controlemode_key", desc: "ins_controlemode_oms" },
"INS_DEEL" : { tbl: "ins_deel", key: "ins_deel_key", desc: "ins_deel_omschrijving" },
"INS_DISCIPLINE" : { tbl: "ins_discipline", key: "ins_discipline_key", desc: "ins_discipline_omschrijving"},
"INS_SRTDEEL" : { tbl: "ins_srtdeel", key: "ins_srtdeel_key", desc: "ins_srtdeel_omschrijving" },
"INS_SRTDISCIPLINE" : { tbl: "ins_srtdiscipline", key: "ins_srtdiscipline_key", desc: "ins_srtdiscipline_omschrijving"},
"INS_SRTGROEP" : { tbl: "ins_srtgroep", key: "ins_srtgroep_key", desc: "ins_srtgroep_omschrijving" },
"MLD_ADRES" : { tbl: "mld_adres", key: "mld_adres_key", desc: "mld_adres_naam" },
"MLD_DIENSTNIVEAU" : { tbl: "mld_dienstniveau", key: "mld_dienstniveau_key", desc: lcl.xsql("mld_dienstniveau_omschr", "mld_dienstniveau_key") },
// Altijd met de prefix ervoor
"MLD_DISCIPLINE" : { tbl: "mld_discipline",
key: "ins_discipline_key",
desc: "ins_discipline_omschrijving",
alias: "sdiscipline",
name: "(SELECT (NVL2(ins_srtdiscipline_prefix,ins_srtdiscipline_prefix||'-','')) || ins_discipline_omschrijving"
+ " FROM ins_srtdiscipline isd"
+ " WHERE isd.ins_srtdiscipline_key = sdiscipline.ins_srtdiscipline_key) ins_discipline_omschrijving" },
/* de prefix komt zo niet mee met de desc van opdracht: */
"MLD_OPDR" : { tbl: "mld_opdr", key: "mld_opdr_key", desc: "COALESCE(mld_opdr_id, mld_melding_key||'/'||mld_opdr_bedrijfopdr_volgnr)", alias: "o" },
"MLD_STDMELDING" : { tbl: "mld_stdmelding", key: "mld_stdmelding_key", desc: lcl.xsql("mld_stdmelding_omschrijving", "mld_stdmelding_key") },
"MLD_TYPEOPDR" : { tbl: "mld_typeopdr", key: "mld_typeopdr_key", desc: lcl.xsql("mld_typeopdr_omschrijving", "mld_typeopdr_key") },
"MLD_UITVOERENDE" : { tbl: "mld_v_uitvoerende", key: "mld_uitvoerende_key", desc: "naam" },
"MLD_V_AFLEVERADRES" : { tbl: "mld_adres", key: "mld_adres_key", desc: "mld_adres_naam" },
"MLD_V_FACTUURADRES" : { tbl: "mld_adres", key: "mld_adres_key", desc: "mld_adres_naam" },
"PRS_AFDELING" : { tbl: "prs_v_afdeling", key: "prs_afdeling_key", desc: S("prs_dep_string"), alias: "d"},
"PRS_BEDRIJF" : { tbl: "prs_bedrijf", key: "prs_bedrijf_key", desc: "prs_bedrijf_naam" },
"PRS_CONTACTPERSOON" : { tbl: "prs_contactpersoon", key: "prs_contactpersoon_key", desc: S("prs_contactpers_string"), alias: "cp"},
"PRS_DIENST" : { tbl: "prs_dienst", key: "prs_dienst_key", desc: lcl.xsql('prs_dienst_omschrijving', 'prs_dienst_key') },
"PRS_KOSTENPLAATS" : { tbl: "prs_kostenplaats", key: "prs_kostenplaats_key", desc: S("prs_kpn_string"), alias: "k"},
"PRS_KOSTENPLAATSGRP" : { tbl: "prs_kostenplaatsgrp", key: "prs_kostenplaatsgrp_key", desc: "prs_kostenplaatsgrp_oms"},
"PRS_KOSTENSOORT" : { tbl: "prs_kostensoort", key: "prs_kostensoort_key", desc: "prs_kostensoort_oms"},
"PRS_KOSTENSOORTGRP" : { tbl: "prs_kostensoortgrp", key: "prs_kostensoortgrp_key", desc: "prs_kostensoortgrp_oms"},
"PRS_PERSLID" : { tbl: "prs_v_perslid_fullnames_all", key: "prs_perslid_key", desc: "prs_perslid_naam_full"},
"PRS_SRTPERSLID" : { tbl: "prs_srtperslid", key: "prs_srtperslid_key", desc: "prs_srtperslid_omschrijving"},
"PRS_RELATIETYPE" : { tbl: "prs_relatietype", key: "prs_relatietype_key", desc: "prs_relatietype_omschrijving" },
"PRS_WERKPLEK" : { tbl: "prs_werkplek", key: "prs_werkplek_key", desc: "prs_werkplek_omschrijving" },
"RES_ACTIVITEIT" : { tbl: "res_activiteit", key: "res_activiteit_key", desc: lcl.xsql("res_activiteit_omschrijving", "res_activiteit_key") },
"RES_ARTIKEL" : { tbl: "res_artikel", key: "res_artikel_key", desc: "res_artikel_omschrijving" },
"RES_DEEL" : { tbl: "res_deel", key: "res_deel_key", desc: "res_deel_omschrijving" },
"RES_DISCIPLINE" : { tbl: "res_discipline", key: "ins_discipline_key", desc: "ins_discipline_omschrijving" },
"RES_OPSTELLING" : { tbl: "res_opstelling", key: "res_opstelling_key", desc: lcl.xsql("res_opstelling_omschrijving", "res_opstelling_key") },
"RES_RUIMTE" : { tbl: "res_ruimte", key: "res_ruimte_key", desc: lcl.xsql("res_ruimte_nr", "res_ruimte_key") },
"RES_RSV_RUIMTE" : { tbl: "res_rsv_ruimte", key: "res_rsv_ruimte_key", desc: "res_reservering_key || '/' || res_rsv_ruimte_volgnr" },
"RES_SRTACTIVITEIT" : { tbl: "res_srtactiviteit", key: "res_srtactiviteit_key", desc: "res_srtactiviteit_omschrijving" }
};
}
return __foreignKeyTable[field.toUpperCase()];
}
function buildUpdate(tabel, fields, params)
{
return buildTrackingUpdate(tabel, null, fields, params).sql;
}
function shorttxt(txt, len)
{
len = len || S("max_tracking_length");
if (txt.length < len)
return txt;
else
return txt.substr(0, len-4) + "...";
}
function getForeignText(key, foreign)
{
var sql = "SELECT " + foreign.desc
+ " FROM " + foreign.tbl + " " + (foreign.alias||"");
if (foreign.where)
sql += " WHERE " + foreign.where + " AND ";
else
sql += " WHERE ";
sql += foreign.key + " = " + key;
var oRs = Oracle.Execute(sql);
if (oRs.EOF)
{
__DoLog("Foreign record not found?", "#FF0000");
__DoLog(sql);
var oldtxt = "<????>"; // Beter dan een AiAi
}
else
{
var oldtxt = oRs(0).Value;
oRs.MoveNext();
if (!oRs.EOF)
{
__DoLog(sql);
__DoLog("Multiple foreign records with key {0} found in {1}\nFirst is {2}, second is {3}?".format(key, foreign.tbl, oldtxt, oRs(0).Value), "#FF0000");
}
}
oRs.Close();
return oldtxt;
}
// tracktxt.push(buildTrackText(tupel.field.typ, oldjsval, tupel.jsval, oRs(tupel.field.dbs).DefinedSize));
// bouw een mooie tekst die de van-naar wijziging beschrijft
// params: nodiff: geen L("lcl_trackappend") of L("lcl_trackpercent")
// foreign: info over de te toeken foreign key
function buildTrackText(typ, oldjsval, newjsval, params)
{
params = params || {};
var oldtxt = oldjsval;
var newtxt = newjsval;
if (typeof params.foreign == "function")
{
oldtxt = params.foreign(oldjsval, params.oldjsvals);
newtxt = params.foreign(newjsval);
}
else
{
switch (typ)
{
case "datetime":
{
var oldtxt = toDateTimeString(oldjsval);
var newtxt = toDateTimeString(newjsval);
break;
}
case "date":
{
var oldtxt = toDateString(oldjsval);
var newtxt = toDateString(newjsval);
break;
}
case "time":
{
var oldtxt = toTimeString(oldjsval);
var newtxt = toTimeString(newjsval);
break;
}
case "key": // hash foreign moet ook gedefinieerd zijn
{
var foreign = params.foreign;
if (!foreign)
abort_with_warning("INTERNAL ERROR:\nForeign key for tracking " + oldjsval + " to "+newjsval+" is not defined");
if (typeof foreign == 'string')
foreign = foreignKeyTable(params.foreign);
if (!foreign)
abort_with_warning("INTERNAL ERROR:\nForeign key for tracking " + params.foreign.toUpperCase()+" is not defined in foreignKeyTable");
if (oldjsval)
oldtxt = getForeignText(oldjsval, foreign)
if (newjsval)
newtxt = getForeignText(newjsval, foreign)
break;
}
}
}
if (oldjsval === null || oldjsval === "") oldtxt = L("lcl_trackfromempty");
if (newjsval === null || newjsval === "") newtxt = L("lcl_tracktoempty");
// oke, en hoe gaan we het verschil presenteren?
var tracktxt = null;
switch (typ)
{
case "memo":
case "varchar":
{
if (oldjsval == null || oldjsval == "") // leeg naar iets
var txt = oldtxt + L("lcl_trackto") + shorttxt(newjsval);
else if (newjsval == null || newjsval == "") // iets naar leeg
var txt = shorttxt(oldjsval) + L("lcl_trackto") + newtxt;
else if (params.nodiff || (oldjsval.length < S("max_tracking_length") && newjsval.length < S("max_tracking_length"))) // korte tekst: gewoon oud-->nieuw
var txt = shorttxt(oldtxt) + L("lcl_trackto") + shorttxt(newtxt)
else if (newjsval.indexOf(oldjsval) == 0) // lange tekst aangevuld
var txt = L("lcl_trackappend") + shorttxt(newjsval.substr(oldjsval.length));
else // lange tekst gewijzigd: percentage verschil noemen
{
// Helemaal naar Oracle om dit te berekenen is niet echt efficient natuurlijk
// maar voor met name lange strings fors sneller dan een js-functie
var sqldiff = "SELECT UTL_MATCH.EDIT_DISTANCE_SIMILARITY("+safe.quoted_sql(String(oldjsval))
+","+safe.quoted_sql(String(newjsval))+") FROM DUAL";
try
{
var oRs = Oracle.Execute(sqldiff);
var diff = 100 - oRs(0).Value;
oRs.Close();
}
catch(e)
{ // 10.2.0.4? Crasht sporadisch bij extreem lange teksten UWVA#19894
__DoLog("Bad UTL_MATCH.EDIT_DISTANCE_SIMILARITY call #19894");
var diff = "??"; // beter dan niet kunnen opslaan
}
var txt = String(diff) + L("lcl_trackpercent");
}
tracktxt = txt;
break;
}
default:
tracktxt = oldtxt + L("lcl_trackto") + newtxt;
}
return tracktxt;
}
// Die is wat specifiekers omdat een andere stdm dezelfde tekst kan hebben
// maar dan onder een andere vakgroep of vakgroeptype
// Een vakgroep(type)wissel wil je eventueel ook tracken
function buildStdmTrackText(typ, oldjsval, newjsval, params)
{
var old_disc_key = Oracle.Get("mld_ins_discipline_key", "mld_stdmelding", oldjsval);
var new_disc_key = Oracle.Get("mld_ins_discipline_key", "mld_stdmelding", newjsval);
var old_srtdisc_key = Oracle.Get("ins_srtdiscipline_key", "mld_discipline", "ins_discipline_key", old_disc_key);
var new_srtdisc_key = Oracle.Get("ins_srtdiscipline_key", "mld_discipline", "ins_discipline_key", new_disc_key);
var oldsrtdisctxt = getForeignText(old_srtdisc_key, foreignKeyTable("ins_srtdiscipline"));
var newsrtdisctxt = getForeignText(new_srtdisc_key, foreignKeyTable("ins_srtdiscipline"));
var olddisctxt = getForeignText(old_disc_key, foreignKeyTable("mld_discipline"));
var newdisctxt = getForeignText(new_disc_key, foreignKeyTable("mld_discipline"));
var oldstdmtxt = getForeignText(oldjsval, foreignKeyTable("mld_stdmelding"));
var newstdmtxt = getForeignText(newjsval, foreignKeyTable("mld_stdmelding"));
var returntextArr = [];
if (oldsrtdisctxt == newsrtdisctxt)
oldsrtdisctxt = newsrtdisctxt = "";
if (olddisctxt == newdisctxt)
olddisctxt = newdisctxt = "";
if (oldstdmtxt == newstdmtxt)
oldstdmtxt = newstdmtxt = "";
if (newsrtdisctxt)
returntextArr.push (L("lcl_vakgroup_type") + ": " + oldsrtdisctxt + L("lcl_trackto") + newsrtdisctxt);
if (newdisctxt)
returntextArr.push (L("lcl_vakgroup") + ": " + olddisctxt + L("lcl_trackto") + newdisctxt);
if (newstdmtxt)
returntextArr.push (L("lcl_complain") + ": " + oldstdmtxt + L("lcl_trackto") + newstdmtxt);
return returntextArr.join("\n");
}
var known_adotypes =
{
key: ['NUMBER'],
date: ['DATE'],
datetime: ['DATE'],
number: ['NUMBER'],
float: ['NUMBER'],
memo: ['VARCHAR2'],
icon: ['VARCHAR2'],
file: ['VARCHAR2'],
color: ['VARCHAR2'],
symbol: ['VARCHAR2'],
varchar: ['VARCHAR2'],
check: ['NUMBER'],
check0: ['NUMBER'],
time: ['DATE'],
sql: []
};
// automatische debugging tool als logging aan staat
// controleert of field-lijst klopt met echte veldtypes
function checkFieldTypes(tabel, fields)
{
var i, j;
var oRs = Oracle.RealConnection.Execute("SELECT column_name || CASE"
+ " WHEN attr_name IS NOT NULL"
+ " THEN '.' || attr_name"
+ " ELSE ''"
+ " END column_name"
+ " , COALESCE(attr_type_name, data_type) data_type"
+ " , data_scale"
+ " , attr_name"
+ " FROM user_tab_columns utc"
+ " , user_type_attrs uta"
+ " WHERE table_name = " + safe.quoted_sql(tabel.toUpperCase())
+ " AND utc.data_type = uta.type_name(+)");
if (oRs.eof) // dan kunnen we niets
{
oRs.Close();
return;
}
for (i=0; i < fields.length; i++)
{
var field = fields[i];
var val = field.val;
var dbs = field.dbs;
var dbfield = null;
while (!oRs.eof)
{
if (oRs("column_name").value == dbs.toUpperCase())
{
dbfield = { name: oRs("column_name").value,
Type: oRs("data_type").value,
NumericScale: oRs("data_scale").value
};
}
//else
//__Log(oRs.Fields(j).Name.toUpperCase() + " is het niet?");
oRs.MoveNext();
}
if (!dbfield)
{
__Log(tabel + "." + dbs + " niet gevonden in recordset?");
continue;
}
var ok_types = known_adotypes[field.typ];
var found = false;
for (j in ok_types)
{
if (ok_types[j] == dbfield.Type)
found = true;
}
if (!found && field.typ != "sql")
{
__SafeLog("<span style='background-color: #00FFFF;'>" + dbs + " is opgegeven als type '" + field.typ + "' maar is: " + dbfield.Type + "</span>");
}
else
{
if (field.typ == "number" && dbfield.NumericScale > 0)
{
__SafeLog("<span style='background-color: #00FFFF;'>"
+ dbs + " is gedefinieerd als 'number' maar heeft " + dbfield.NumericScale
+ " decimalen dus 'float' ligt meer voor de hand</span>");
}
}
oRs.MoveFirst(); // voor de volgende
}
oRs.Close();
}
// where is bijvoorbeeld 'MLD_MELDING_KEY=1234'
// params bevat eventueel
// dialect_key: 134
function buildTrackingUpdate(tabel, where, xfields, params)
{
params = params || {};
if (!params.noValidateToken) // Uit API's
protectRequest.validateToken(); // Alle _edit_ schermen horen IFACE.FORM_END aan het einde te hebben
if (xfields instanceof Array)
var fields = xfields;
else // Uit API2
{
var fields = [];
for (var fld in xfields)
fields.push(xfields[fld]);
}
if (!fields.length)
{
__Log("Nothing to update in buildTrackingUpdate?");
return { sql: "BEGIN NULL; END;", trackarray: [], oldjsvals: [] }
}
if (__Logging & 1)
{
checkFieldTypes(tabel, fields)
}
var result = _buildFields(fields, params, tabel, where);
var tupels = result.tupels;
// we hebben nooit sequences bij updates?
var updates = [];
var i;
var trackfields = [];
for (i=0; i < tupels.length; i++)
{
var tupel = tupels[i];
if (tupel.field.dbs)
{
updates.push("xx." + tupel.field.dbs + " = " + tupel.sql);
}
if (where && tupel.field.track)
trackfields.push(tupel.field.dbs);
}
var trackarray = [];
var oldjsvals = [];
if (updates.length && trackfields.length)
{
var sqlt = "SELECT xx." + trackfields.join(", xx.")
+ " FROM " + tabel + " xx"
+ " WHERE " + where;
var oRs = Oracle.Execute(sqlt);
for (i in tupels)
{
var tupel = tupels[i];
if (tupel.field.track)
{
switch (tupel.field.typ)
{
case "datetime":
case "date":
case "time":
// Waarde kan ook null zijn en moet dat dan ook blijven.
var oldjsval = (oRs(tupel.field.dbs).Value!=null? new Date(oRs(tupel.field.dbs).Value) : null);
break;
case "sql":
ERROR_CANNOT_TRACK_TYP_SQL;
default:
var oldjsval = oRs(tupel.field.dbs).Value;
}
var different = false;
switch (tupel.field.typ)
{
case "datetime":
case "date":
case "time":
// Beide waarden kunnen null zijn.
var different = (oldjsval !=null || tupel.jsval != null)
&& ((oldjsval == null && tupel.jsval != null)
|| (oldjsval != null && tupel.jsval == null)
|| (oldjsval.getTime() != tupel.jsval.getTime()))
break
case "memo":
case "varchar":
var different = (oldjsval||"") != (tupel.jsval||"");// bij Oracle tekst is null gelijk aan ""
break
default:
var different = oldjsval != tupel.jsval;
}
// Waarden converteren naar gebruikersvriendelijke teksten
if (typeof tupel.field.track == "string" && different)
{
var lbl = tupel.field.track;
// if (params.dialect_key)
// lbl = lcl.x(tupel.field.track, params.dialect_key);
if (tupel.field.buildTrackText)
var tracktxt = tupel.field.buildTrackText(tupel.field.typ, oldjsval, tupel.jsval, { foreign: tupel.field.foreign, oldjsvals: oldjsvals } );
else
var tracktxt = lbl + ": " + buildTrackText(tupel.field.typ, oldjsval, tupel.jsval, { foreign: tupel.field.foreign, oldjsvals: oldjsvals } );
trackarray.push( (params.includeName ? params.includeName + "; " : "") + tracktxt);
}
oldjsvals[tupel.field.dbs] = oldjsval;
}
}
oRs.Close();
}
if (!updates.length) // bijvoorbeeld als alle fields verwijzen naar een Form-parameter die niet is meegestuurd
{
__Log("Effectively nothing to update in buildTrackingUpdate?");
return { sql: "BEGIN NULL; END;", trackarray: [], oldjsvals: [] }
}
var sql = "UPDATE " + tabel + " xx"
+ " SET " + updates.join(", ")
+ " WHERE " + (where||"");
return { sql: sql, trackarray: trackarray, oldjsvals: oldjsvals };
}
function buildInsert(tabel, xfields, params)
{
params = params || {};
if (!params.noValidateToken) // Uit API's
protectRequest.validateToken(); // Alle _edit_ schermen horen IFACE.FORM_END aan het einde te hebben
if (xfields instanceof Array)
var fields = xfields;
else // Uit API2
{
var fields = [];
for (var fld in xfields)
fields.push(xfields[fld]);
}
var result = _buildFields(fields, params);
var tupels = result.tupels;
var first = true;
var cols = "",vals="";
var i;
var obj = [];
for (i=0; i < tupels.length; i++)
{
if (tupels[i].field.obj)
{ // Object typen hier verzamelen en later toevoegen aan cols en vals.
var objfield = tupels[i].field.dbs.split(".") // objfield = kolom_object.object_field
var obj_identifier = tupels[i].field.obj + "." + objfield[0]; // obj_identifier = object_type.object_field
if (!obj[obj_identifier])
obj[obj_identifier] = [];
obj[obj_identifier].push(objfield[1] + "=>" + tupels[i].sql);
}
else
{
if (tupels[i].field.dbs)
{
if (!first) { cols += ", "; vals += ", " };
first = false;
cols += tupels[i].field.dbs;
vals += tupels[i].sql;
}
}
}
// De verzamelde object type nog toevoegen aan cols en vals: OBJECT_TYPE(field1 => val1, field2 => val2).
for (var obj_i in obj)
{
if (cols != "") { cols += ", "; vals += ", " };
var obj_identifier = obj_i.split(".");
cols += obj_identifier[1];
vals += obj_identifier[0] + "(" + obj[obj_i] + ")";
}
var sql = "INSERT INTO "+tabel+"("+cols+") VALUES ("+vals+")";
return { sql: sql, sequences: result.sequences};
}
// Return new_price OR price +/- percentage
function calculatePrice(price, new_price)
{
if (new_price.match('%'))
{
return (price + price * parseFloat(new_price) / 100).toFixed(2);
}
else
{
if (new_price.match(/^-{2}|\+{2}/)) //match ++ or -- at beginning
{
return price + parseFloat(new_price.replace("++", "+").replace("--", "-"));
}
else
{
return new_price == "" ? new_price : parseFloat(new_price);
}
}
}
// Bouw het field-array om naar { tupels: tupels, sequences: sequences }
// met tupels { dbs: veldnaam, jsval: js-value, sql: sql-value }
// en sequences[veldnaam] = seq-value
// alleen velden die in de Form-collection voorkwamen worden
// gebruikt
// params wordt nog niet gebruikt.
function _buildFields(fields, params, tabel, where)
{
params = params || {};
var tupels = [];
var sequences = [];
var i;
for (i=0; i < fields.length; i++)
{
var field = fields[i];
var val = field.val;
if (typeof field.savewhen != "boolean")
{
if (typeof field.savewhen == "string")
field.savewhen = Request.Form(field.savewhen).count > 0;
else if (field.frm)
{
if (field.typ=="check" || field.typ=="check0") // Zie iface.inc/CHECKBOX: we hebben een hidden field has_xxxx toegevoegd
field.savewhen = Request.Form("has_" + field.frm).count==1;
else
field.savewhen = Request.Form(field.frm).count > 0;
}
else
field.savewhen = true;
}
if (!field.savewhen)
continue; // helemaal niet opnemen
if (field.frm)
{
if (field.typ=="check" || field.typ=="check0")
{
var val = (Request.Form(field.frm).count==1);
}
else
{
var val = Request.Form(field.frm)(1);
}
}
if (field.seq)
{
var sql="select "+field.seq+".nextval from dual";
var oRs = Oracle.Execute( sql );
var seq_key = oRs(0).value;
oRs.Close();
sequences[field.dbs] = seq_key;
var val = seq_key;
}
var tupel = { field: field }; // 'teruggeven'
switch (field.typ)
{
case "sql":
{
tupel.sql = val;
break;
}
case "memo":
case "icon":
case "file":
case "color":
case "symbol":
case "varchar":
{
if (val == "" || val === null)
tupel.sql = " NULL"
else
{
var val2 = String(val);
val2 = val2.replace(/^\s+/,""); // trim spaties aan begin
val2 = val2.replace(/\s+$/,""); // trim spaties aan einde
tupel.jsval = val2;
tupel.sql = safe.quoted_sql(val2, field.len);
}
break;
}
case "key":
{ // Pas op: *zeer* sporadisch komt een key==0 voor!
if (val === "" || val === null || parseInt(val, 10)==-1)
tupel.sql = " NULL"
else
{
tupel.sql = parseInt(val, 10);
if (isNaN(tupel.sql))
abort_with_warning("Unexpected error: " + field.dbs + " is not a key but " + val);
}
break;
}
case "bool":
{
if (val == "" || val === null || val == "0")
tupel.sql = " NULL"
else
tupel.sql = " 1"
break;
}
case "number":
{
if (val === "" || val === null)
tupel.sql = " NULL"
else
{ tupel.sql = parseInt(val, 10);
if (isNaN(tupel.sql))
abort_with_warning("Unexpected error: " + field.dbs + " is not a number but " + val);
}
break;
}
case "float":
{
if (val === "" || val === null)
tupel.sql = " NULL"
else if (field.relativeValuesAllowed) // calculate (relative) price
{
var oldval_oRs = Oracle.Execute("SELECT " + field.dbs + " FROM " + tabel + " WHERE " + (where||""));
if (oldval_oRs.EOF)
{
tupel.sql = calculatePrice(0, val);
}
else
{
tupel.sql = calculatePrice(oldval_oRs(field.dbs).Value, val);
}
oldval_oRs.Close();
}
else
{
if (typeof val == "string")
val = val.replace(/,/g,".");
tupel.sql = parseFloat(val);
if (isNaN(tupel.sql))
abort_with_warning("Unexpected error: " + field.dbs + " is not a float but " + val);
}
break;
}
case "check":
case "check0":
{
if (val) // ((val && !field.inverse) || (!val && field.inverse))
tupel.sql = " 1"
else
tupel.sql = (field.typ == "check"? " NULL" : 0)
break;
}
case "date":
case "datetime":
{
if (val == "" || val === null)
tupel.sql = " NULL"
else
{
tupel.jsval = (val instanceof Date)?val:new Date(parseInt(val, 10));
tupel.sql = tupel.jsval.toSQL(field.typ=="datetime");
}
break;
}
case "time": // Laat datum-deel ongemoeid!!
{
if (val == "" || val === null)
tupel.sql = " TRUNC("+field.dbs+")";
else
{
tupel.jsval = (val instanceof Date)?val:new Date(parseInt(val, 10));
var tm = tupel.jsval.getHours()*60+tupel.jsval.getMinutes();
tupel.sql = " TRUNC("+field.dbs+") + " + tm + "/24/60";
}
break;
}
case "processingtime":
{
tupel.sql = " MLD_T_UITVOERTIJD(tijdsduur => {0}, eenheid => {1})".format(val.duration, safe.quoted_sql(val.unit));
break;
}
default: ERROR_UNSUPPORTED_FIELDTYP;
}
if (typeof tupel.jsval == "undefined")
{
if (tupel.sql == " NULL")
tupel.jsval = null;
else
tupel.jsval = tupel.sql; // default;
}
tupels.push(tupel);
}
return { tupels: tupels, sequences: sequences };
}
%>