771 lines
51 KiB
Plaintext
771 lines
51 KiB
Plaintext
<%@language = "javascript" %>
|
|
<% /*
|
|
|
|
LET OP: Dit bestand kan moeilijk te beantwoorden vragen opwerpen
|
|
en is dan ook een 'undocumented' feature.
|
|
|
|
$Revision$
|
|
$Id$
|
|
|
|
File: appl/fac/fac_verify.asp
|
|
Description: Verify Facilitor database consistency
|
|
Parameters:
|
|
Context: Manual call to check database consistency
|
|
Note: FACTAB authorization is required
|
|
tenzij we in de ontwikkelomgeving zitten
|
|
TODO: - userraps die niet als view/tabel terug te vinden zijn
|
|
- mld_melding records waar de mld_ins_disicpline niet match met std_melding (gebeurt al?)
|
|
- idem voor ins_deel.ins_discipline_key en ins_deel.alg_locatie_key
|
|
*/ %>
|
|
|
|
<%
|
|
if (Application("otap_environment") == "O")
|
|
ANONYMOUS_Allowed = 1;
|
|
%>
|
|
|
|
<!--#include file="../Shared/common.inc"-->
|
|
<%
|
|
if (Application("otap_environment") != "O")
|
|
{
|
|
var autfunction = "WEB_FACTAB";
|
|
var authparams = user.checkAutorisation(autfunction);
|
|
}
|
|
|
|
if (Server.ScriptTimeout<600) Server.ScriptTimeout=600; // 10 minuten moet lukken
|
|
%>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
th, td {
|
|
font-family: Verdana;
|
|
font-size: smaller;
|
|
color: #000000;
|
|
padding: 2px;
|
|
background-color: #D6D8E8;
|
|
}
|
|
table.inside td
|
|
{
|
|
padding: 0px;
|
|
}
|
|
</style>
|
|
<title>FACILITOR database consistency verifier</title>
|
|
<script>
|
|
function toggle(id)
|
|
{
|
|
var itm = document.getElementById(id);
|
|
if (itm.style.display == 'none')
|
|
itm.style.display = 'block';
|
|
else
|
|
itm.style.display = 'none';
|
|
}
|
|
function reload()
|
|
{
|
|
var hrefBase = window.location.href;
|
|
window.location.href = hrefBase;
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
Dit kan even duren....
|
|
<% Response.Flush();
|
|
|
|
resultcodes = { ok: "No problem",
|
|
fatal: "No further checks possible, fix and recheck",
|
|
error: "Error, fix and recheck",
|
|
warning: "Warning: Facilitor may run sub-optimal",
|
|
inform: "Information only"
|
|
}
|
|
|
|
function checker (description, fnCheck, toggler)
|
|
{
|
|
if (typeof cnt_id == "undefined") cnt_id = 1;
|
|
cnt_id ++;
|
|
if (typeof last__GROUP == "undefined" || __GROUP != last__GROUP)
|
|
{
|
|
Response.Write("\n<tr><td colspan='3'><strong>"+__GROUP+"</strong></td></tr>");
|
|
last__GROUP = __GROUP;
|
|
}
|
|
|
|
if (toggler)
|
|
Response.Write("\n<tr onClick='toggle(\"div"+cnt_id+"\")'><td>");
|
|
else
|
|
Response.Write("\n<tr><td>");
|
|
Response.Write(description);
|
|
try
|
|
{
|
|
var res = fnCheck();
|
|
}
|
|
catch (e)
|
|
{
|
|
Response.Write("<br/><em>"+e.description+"</em>");
|
|
Response.Write("<td style='color:red'>Internal error</tr></table>");
|
|
Response.Write("<h1 style='color:red'>Verify aborted</h1>");
|
|
Response.End;
|
|
}
|
|
|
|
if (toggler)
|
|
{
|
|
var matches = res.message.match(/<tr/g); // try to match <tr
|
|
var count = matches?matches.length:0; // this is how many!
|
|
Response.Write(" (click for details, " + count + " lines)");
|
|
}
|
|
|
|
Response.Write("<div id='div"+cnt_id+"' "+(toggler?"style=\"display:none\"":"")+"style='padding-left: 20px'><em>"+(res.message||'')+"</em></div>");
|
|
Response.Write("</td>");
|
|
Response.Write("<td>"+(res.info||'')+"</td>");
|
|
switch (res.result)
|
|
{
|
|
case resultcodes.ok:
|
|
Response.Write("<td style='color:green'>Ok</td>");
|
|
break;
|
|
case resultcodes.warning:
|
|
Response.Write("<td style='color:yellow'>Warning</td>");
|
|
break;
|
|
case resultcodes.error:
|
|
Response.Write("<td style='background-color:red'>Error</td>");
|
|
break;
|
|
case resultcodes.fatal:
|
|
Response.Write("<td style='background-color:red'>Error</td></tr></table>");
|
|
Response.Write("<h1 style='background-color:red'>Verify aborted</h1>");
|
|
Response.End;
|
|
break;
|
|
default:
|
|
Response.Write("<td style='color:red'>Unknown</td>");
|
|
break;
|
|
}
|
|
Response.Write("</tr>");
|
|
Response.Flush(); // Haalt weinig uit trouwens, IE wacht toch op de hele tabel.
|
|
}
|
|
|
|
%><table>
|
|
<thead><tr><th>fac_verify_data.asp $Revision$ <input type='button' onclick='reload()' value='Refresh'>
|
|
<br>Checking <%= (new Date).toLocaleString() %>
|
|
<br>Customer: <%=customerId%>
|
|
<br>Database: <%=Oracle.RealConnection.Properties("User Name")+'@'+Oracle.RealConnection.Properties("Data source") %>
|
|
<% if (user_key > 0) Response.Write("<br>User: " + user.naam()); %>
|
|
</th>
|
|
<th>Information</th><th>Result</th></tr></thead>
|
|
<%
|
|
|
|
//------------------------------------------------------------------------------
|
|
__GROUP = "DATABASE CONSISTENTIE";
|
|
// check the disc_params tables that should have an equal number of records
|
|
checker("Controle xxx-disc_params",
|
|
function ()
|
|
{
|
|
var noResults = [{ k1: "mld_ins_discipline_key", t1: "mld_disc_params",
|
|
k2: "ins_discipline_key", t2: "mld_discipline"
|
|
},
|
|
{ k1: "res_ins_discipline_key", t1: "res_disc_params",
|
|
k2: "ins_discipline_key", t2: "res_discipline"
|
|
},
|
|
{ k1: "bes_ins_discipline_key", t1: "bes_disc_params",
|
|
k2: "ins_discipline_key", t2: "bes_discipline"
|
|
},
|
|
{ k1: "cnt_ins_discipline_key", t1: "cnt_disc_params",
|
|
k2: "ins_discipline_key", t2: "cnt_discipline"
|
|
},
|
|
{ k1: "ctr_ins_discipline_key", t1: "ctr_disc_params",
|
|
k2: "ins_discipline_key", t2: "ctr_discipline"
|
|
},
|
|
{ k1: "ins_discipline_key", t1: "ins_disc_params",
|
|
k2: "ins_discipline_key", t2: "ins_discipline"
|
|
}
|
|
]
|
|
|
|
var messages = [];
|
|
for (noResult in noResults)
|
|
{
|
|
var rr = noResults[noResult];
|
|
var sql = "SELECT " + rr.k1 + " FROM " + rr.t1 + " MINUS SELECT " + rr.k2 + " FROM " + rr.t2;
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.Eof)
|
|
messages.push(rr.t1 + " has more records than " + rr.t2 + "<br>" + sql);
|
|
var sql = "SELECT " + rr.k2 + " FROM " + rr.t2 + " MINUS SELECT " + rr.k1 + " FROM " + rr.t1;
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.Eof)
|
|
messages.push(rr.t2 + " has more records than " + rr.t1 + "<br>" + sql);
|
|
var sql = "SELECT " + rr.k1 + ", COUNT(*) FROM " + rr.t1 + " GROUP BY " + rr.k1 + " HAVING COUNT(*) > 1";
|
|
var oRs = Oracle.Execute(sql);
|
|
if (!oRs.Eof)
|
|
messages.push(rr.t1 + " has duplicate " + rr.k1 + " records<br>" + sql);
|
|
oRs.Close();
|
|
}
|
|
if (!messages.length)
|
|
return { result: resultcodes.ok,
|
|
info: String(noResults.length*3) + " checks",
|
|
message: "No problems detected" };
|
|
else
|
|
return { result: resultcodes.error, message: messages.join("<br>") };
|
|
}
|
|
)
|
|
|
|
// Check for other queries that should yield no records
|
|
checker("Controle: queries die geen records mogen opleveren",
|
|
function ()
|
|
{
|
|
var noResults = [{ msg: "FAC_VERSION is niet goed gevuld",
|
|
sql: "SELECT * FROM fac_version"
|
|
+ " WHERE fac_version_cust IS NULL"
|
|
+ " OR fac_version_custnr IS NULL"
|
|
// Deprecated + " OR fac_version_otap IS NULL"
|
|
+ " OR fac_version_lang IS NULL"
|
|
},
|
|
{ msg: "Datatype MLD_T_UITVOERTIJD.TIJDSDUUR is te klein (gebruik DB23aTO23b.sql)",
|
|
sql: "SELECT type_name, attr_name, precision"
|
|
+ " FROM user_type_attrs"
|
|
+ " WHERE type_name = 'MLD_T_UITVOERTIJD' "
|
|
+ " AND attr_name = 'TIJDSDUUR'"
|
|
+ " AND precision < 12"
|
|
},
|
|
// meldingen met flexkenmerken van verschillende stdmeldingen *tegelijk*
|
|
// Dit is in de praktijk ook problematisch (FSN#18613):
|
|
{ msg: "meldingen met mld-flexkenmerken van verschillende stdmeldingen. Problematisch (FSN#18613)",
|
|
sql: "SELECT mld_melding_key, COUNT ( * )"
|
|
+ " FROM ( SELECT mld_melding_key, mld_stdmelding_key, COUNT ( * )"
|
|
+ " FROM mld_kenmerkmelding v, mld_kenmerk vk"
|
|
+ " WHERE v.mld_kenmerk_key = vk.mld_kenmerk_key"
|
|
+ " AND mld_kenmerk_niveau = 'S'"
|
|
+ " GROUP BY mld_melding_key, mld_stdmelding_key)"
|
|
+ " GROUP BY mld_melding_key"
|
|
+ " HAVING COUNT ( * ) > 1"
|
|
},
|
|
{ msg: "meldingen met mld-flexkenmerken van verschillende vakgroepen",
|
|
sql: "SELECT mld_melding_key, COUNT ( * )"
|
|
+ " FROM ( SELECT mld_melding_key, mld_stdmelding_key, COUNT ( * )"
|
|
+ " FROM mld_kenmerkmelding v, mld_kenmerk vk"
|
|
+ " WHERE v.mld_kenmerk_key = vk.mld_kenmerk_key"
|
|
+ " AND mld_kenmerk_niveau = 'D'"
|
|
+ " GROUP BY mld_melding_key, mld_stdmelding_key)"
|
|
+ " GROUP BY mld_melding_key"
|
|
+ " HAVING COUNT ( * ) > 1"
|
|
},
|
|
{ msg: "meldingen met mld-flexkenmerken van andere stdmeldingen",
|
|
sql: " SELECT v.mld_melding_key,"
|
|
+ " v.mld_kenmerk_key,"
|
|
+ " vk.mld_stdmelding_key stdm_bij_kenmerk,"
|
|
+ " mm.mld_stdmelding_key stdm_bij_melding"
|
|
+ " FROM mld_kenmerkmelding v, mld_kenmerk vk, mld_melding mm"
|
|
+ " WHERE v.mld_kenmerk_key = vk.mld_kenmerk_key"
|
|
+ " AND v.mld_melding_key = mm.mld_melding_key"
|
|
+ " AND mld_kenmerk_niveau = 'S'"
|
|
+ " AND vk.mld_stdmelding_key <> mm.mld_stdmelding_key"
|
|
+ " ORDER BY mm.mld_melding_key"
|
|
},
|
|
{ msg: "Melding kenmerken waarvan de soort-kenmerk is verwijderd maar de kenmerk niet",
|
|
sql: "SELECT mld_kenmerk_key, mld_kenmerk_niveau, mk.mld_srtkenmerk_key, mld_srtkenmerk_omschrijving, mld_srtkenmerk_verwijder,mk.*, msk.*"
|
|
+ " FROM mld_kenmerk mk,"
|
|
+ " mld_srtkenmerk msk"
|
|
+ " WHERE mk.mld_srtkenmerk_key = msk.mld_srtkenmerk_key"
|
|
+ " AND mld_kenmerk_verwijder IS NULL"
|
|
+ " AND mld_srtkenmerk_verwijder IS NOT NULL"
|
|
},
|
|
{ msg: "Meldingen die rechtstreeks naar zichzelf wijzen. Geeft oneindige recursie in make_xml bij bonnen!",
|
|
sql: "SELECT mld_melding_key"
|
|
+ " , mld_melding_omschrijving"
|
|
+ " , mld_melding_status"
|
|
+ " FROM mld_melding"
|
|
+ " WHERE mld_melding_key = mld_melding_kto_key"
|
|
},
|
|
// JGL: Volgens mij gaat een constraint het volgende tegenwoordig wel tegen
|
|
{ msg: "Melding kenmerken dubbel bij een stdmelding. Met 5.3.3 problematisch bij workflow maar opgelost met FSN#27550",
|
|
sql: "SELECT mld_srtkenmerk_key,"
|
|
+ " mld_kenmerk_niveau,"
|
|
+ " kk.mld_stdmelding_key,"
|
|
+ " kk.mld_kenmerk_groep,"
|
|
+ " COUNT ( * )"
|
|
+ " FROM mld_kenmerk kk"
|
|
+ " WHERE kk.mld_kenmerk_verwijder IS NULL"
|
|
+ " AND mld_stdmelding_key IS NOT NULL"
|
|
+ " GROUP BY mld_srtkenmerk_key, mld_kenmerk_niveau, kk.mld_stdmelding_key, kk.mld_kenmerk_groep"
|
|
+ " HAVING COUNT ( * ) > 1"
|
|
},
|
|
{ msg: "Melding kenmerken waar de default groter is dan de maximale lengte",
|
|
sql: "SELECT * "
|
|
+ " FROM mld_kenmerk mk, mld_srtkenmerk msk "
|
|
+ " WHERE mk.mld_srtkenmerk_key = msk.mld_srtkenmerk_key "
|
|
+ " AND mld_srtkenmerk_kenmerktype = 'C' "
|
|
+ " AND LENGTH (mld_kenmerk_default) > mld_srtkenmerk_lengte "
|
|
+ " AND mld_kenmerk_default NOT LIKE '##SQL##%' "
|
|
+ " AND mld_kenmerk_verwijder IS NULL "
|
|
},
|
|
{ msg: "Vastgelopen workflows",
|
|
sql: "SELECT m.mld_melding_key, mld_stdmelding_omschrijving"
|
|
+ " FROM mld_melding m, mld_stdmelding msm"
|
|
+ " WHERE mld_melding_status NOT IN (1, 5, 6)"
|
|
+ " AND m.mld_melding_key = mld_melding_start_key"
|
|
+ " AND m.mld_stdmelding_key = msm.mld_stdmelding_key"
|
|
+ " AND m.mld_melding_key NOT IN"
|
|
+ " (SELECT m.mld_melding_start_key"
|
|
+ " FROM mld_melding m"
|
|
+ " WHERE mld_melding_status NOT IN (1, 5, 6)"
|
|
+ " AND m.mld_melding_key != mld_melding_start_key)"
|
|
},
|
|
{ msg: "Opdrachten waar statusveld leeg is",
|
|
sql: " SELECT mld_melding_key, mld_opdr_key"
|
|
+ " FROM mld_opdr"
|
|
+ " WHERE mld_statusopdr_key IS NULL"
|
|
},
|
|
{ msg: "Afspraken zonder bezoekers (niet problematisch)",
|
|
sql: "SELECT bez_afspraak_key " +
|
|
" FROM bez_afspraak a " +
|
|
" WHERE NOT EXISTS (SELECT bez_afspraak_key " +
|
|
" FROM bez_bezoekers b " +
|
|
" WHERE a.bez_afspraak_key = b.bez_afspraak_key) "
|
|
},
|
|
|
|
{ msg: "Reserveerbare ruimtes zonder opbouw uit alg_ruimtes",
|
|
sql: "SELECT res_ruimte_key, res_ruimte_nr, res_ruimte_omschrijving"
|
|
+ " FROM res_ruimte"
|
|
+ " WHERE res_ruimte_verwijder IS NULL"
|
|
+ " AND res_ruimte_key NOT IN (SELECT res_ruimte_key"
|
|
+ " FROM res_alg_ruimte"
|
|
+ " WHERE res_alg_ruimte_verwijder IS NULL)"
|
|
},
|
|
{ msg: "Reserveerbare ruimtes (verwijderde) zonder opbouw uit alg_ruimtes",
|
|
sql: "SELECT res_ruimte_key, res_ruimte_nr, res_ruimte_omschrijving"
|
|
+ " FROM res_ruimte"
|
|
+ " WHERE res_ruimte_verwijder IS NOT NULL"
|
|
+ " AND res_ruimte_key NOT IN (SELECT res_ruimte_key"
|
|
+ " FROM res_alg_ruimte"
|
|
+ " WHERE (res_alg_ruimte_verwijder IS NULL" // zal er nooit zijn want:
|
|
+ " OR res_alg_ruimte_verwijder = res_ruimte_verwijder))" // dit doet de trigger
|
|
},
|
|
{ msg: "Reserveerbare ruimtes zonder gedefinieerde opstelling(en)",
|
|
sql: "SELECT res_ruimte_key, res_ruimte_nr, res_ruimte_omschrijving"
|
|
+ " FROM res_ruimte"
|
|
+ " WHERE res_ruimte_verwijder IS NULL"
|
|
+ " AND res_ruimte_key NOT IN"
|
|
+ " (SELECT res_ruimte_key FROM res_ruimte_opstelling)"
|
|
},
|
|
{ msg: "Reservering activiteiten waarvan de soort-activiteit is verwijderd (zie je wel in facmgt maar niet in de interface)",
|
|
sql: " SELECT res_activiteit_omschrijving, res_srtactiviteit_omschrijving"
|
|
+ " FROM res_activiteit a, res_srtactiviteit sa"
|
|
+ " WHERE res_activiteit_verwijder IS NULL"
|
|
+ " AND res_srtactiviteit_verwijder IS NOT NULL"
|
|
+ " AND a.res_srtactiviteit_key = sa.res_srtactiviteit_key"
|
|
},
|
|
{ msg: "Reserveringen met zowel res_ruimte_opstel_key als alg_ruimte_key (FSN#31382)",
|
|
sql: "SELECT *"
|
|
+ " FROM res_rsv_ruimte"
|
|
+ " WHERE res_ruimte_opstel_key IS NOT NULL"
|
|
+ " AND alg_ruimte_key IS NOT NULL"
|
|
},
|
|
{ msg: "Reserveringen zonder res_ruimte_opstel_key of alg_ruimte_key, afgelopen jaar",
|
|
sql: "SELECT *"
|
|
+ " FROM res_rsv_ruimte"
|
|
+ " WHERE res_ruimte_opstel_key IS NULL"
|
|
+ " AND alg_ruimte_key IS NULL"
|
|
+ " AND res_rsv_ruimte_tot > sysdate - 365"
|
|
},
|
|
{ msg: "Reserveerbare objecten gekoppeld aan een *ruimte*-catalogus (FSN#31716)",
|
|
sql: "SELECT itd.ins_discipline_key,"
|
|
+ " ins_discipline_omschrijving,"
|
|
+ " ins_discipline_min_level,"
|
|
+ " ins_deel_omschrijving"
|
|
+ " FROM res_discipline itd, res_deel rd, ins_deel id"
|
|
+ " WHERE ins_discipline_verwijder IS NULL"
|
|
+ " AND ins_discipline_module = 'RES'"
|
|
+ " AND ins_discipline_min_level != 1" // object
|
|
+ " AND rd.res_discipline_key = itd.ins_discipline_key"
|
|
+ " AND rd.res_ins_deel_key = id.ins_deel_key"
|
|
},
|
|
{ msg: "Fysieke objecten die door meerdere reserveerbare objecten gebruikt worden. Dat mag, het zullen verschillende catalogi zijn maar misschien toch even naar kijken.",
|
|
sql: " SELECT ins_deel_key, ins_deel_omschrijving, COUNT ( * ) " +
|
|
" FROM (SELECT * " +
|
|
" FROM ins_deel d, res_deel rd " +
|
|
" WHERE rd.res_ins_deel_key = d.ins_deel_key " +
|
|
" AND rd.res_deel_verwijder IS NULL) " +
|
|
" GROUP BY ins_deel_key, ins_deel_omschrijving " +
|
|
" HAVING COUNT ( * ) > 1 "
|
|
},
|
|
{ msg: "Afdelingen die niet terugkomen in prs_v_afdeling (zichzelf als parent_key?)",
|
|
sql: "SELECT prs_afdeling_key"
|
|
+ " FROM prs_afdeling"
|
|
+ " WHERE prs_afdeling_key NOT IN"
|
|
+ " (SELECT prs_afdeling_key FROM prs_v_afdeling)"
|
|
},
|
|
{ msg: "Opgeslagen lege melding kenmerken (problematisch bij wijzigen)",
|
|
sql: "SELECT *"
|
|
+ " FROM mld_kenmerkmelding"
|
|
+ " WHERE mld_kenmerkmelding_waarde IS NULL"
|
|
},
|
|
{ msg: "Melding referentie kenmerken die niet numeriek zijn (komt in de logging) FSN#28966",
|
|
sql: "SELECT m.mld_melding_key,"
|
|
+ " mld_melding_datum,"
|
|
+ " mld_kenmerkmelding_waarde,"
|
|
+ " fac_kenmerkdomein_omschrijving,"
|
|
+ " fu.fac_usrtab_naam"
|
|
+ " FROM mld_melding m,"
|
|
+ " mld_kenmerkmelding mkm,"
|
|
+ " mld_kenmerk mk,"
|
|
+ " mld_srtkenmerk msk,"
|
|
+ " fac_kenmerkdomein fkd,"
|
|
+ " fac_usrtab fu"
|
|
+ " WHERE m.mld_melding_key = mkm.mld_melding_key"
|
|
+ " AND mkm.mld_kenmerk_key = mk.mld_kenmerk_key"
|
|
+ " AND mk.mld_srtkenmerk_key = msk.mld_srtkenmerk_key"
|
|
+ " AND msk.fac_kenmerkdomein_key = fkd.fac_kenmerkdomein_key"
|
|
+ " AND fac_kenmerkdomein_kolomnaam = 'FAC_USRDATA_KEY'"
|
|
+ " AND fac.safe_to_number (mld_kenmerkmelding_waarde) IS NULL"
|
|
+ " AND mld_kenmerk_verwijder IS NULL"
|
|
+ " AND mld_srtkenmerk_verwijder IS NULL"
|
|
+ " AND mld_kenmerk_niveau = 'S'"
|
|
+ " AND m.mld_stdmelding_key = mk.mld_stdmelding_key"
|
|
+ " AND fkd.fac_usrtab_key = fu.fac_usrtab_key"
|
|
+ " ORDER BY m.mld_melding_key "
|
|
},
|
|
{ msg: "Meldingen met spoed/lage prio waarvan uitvoertijd leeg (max 2 jaar oud). Edit/opslaan kan problematisch zijn CUST#30092",
|
|
sql: "SELECT mld_melding_key, m.mld_melding_datum, mld_melding_spoed, ms.mld_stdmelding_omschrijving"
|
|
+ " FROM mld_melding m, mld_stdmelding ms"
|
|
+ " WHERE m.mld_stdmelding_key = ms.mld_stdmelding_key"
|
|
+ " AND (CASE mld_melding_spoed"
|
|
+ " WHEN 1 THEN ms.mld_stdmelding_t_uitvtijd_pr1.tijdsduur"
|
|
+ " WHEN 2 THEN ms.mld_stdmelding_t_uitvtijd_pr2.tijdsduur"
|
|
+ " WHEN 3 THEN ms.mld_stdmelding_t_uitvoertijd.tijdsduur"
|
|
+ " WHEN 4 THEN ms.mld_stdmelding_t_uitvtijd_pr4.tijdsduur"
|
|
+ " ELSE NULL"
|
|
+ " END) IS NULL"
|
|
+ " AND mld_melding_datum > SYSDATE - 730"
|
|
+ " ORDER BY mld_melding_datum"
|
|
},
|
|
// TODO: eigenlijk voor alle modules doen.
|
|
{ msg: "Melding referentie kenmerksoorten zonder kenmerkdomein CUST#29780",
|
|
sql: "SELECT *"
|
|
+ " FROM mld_srtkenmerk"
|
|
+ " WHERE mld_srtkenmerk_kenmerktype IN ('R','S')"
|
|
+ " AND fac_kenmerkdomein_key IS NULL"
|
|
+ " AND mld_srtkenmerk_verwijder IS NULL"
|
|
},
|
|
{ msg: "INS referentie kenmerksoorten zonder kenmerkdomein CUST#29780",
|
|
sql: "SELECT *"
|
|
+ " FROM ins_srtkenmerk"
|
|
+ " WHERE ins_srtkenmerk_kenmerktype IN ('R','S')"
|
|
+ " AND fac_kenmerkdomein_key IS NULL"
|
|
+ " AND ins_srtkenmerk_verwijder IS NULL"
|
|
},
|
|
{ msg: "RES referentie kenmerksoorten met ongeldige default",
|
|
sql: "SELECT rk.res_kenmerk_key, res_srtkenmerk_omschrijving, res_srtkenmerk_kenmerktype, res_kenmerk_default"
|
|
+ " FROM res_kenmerk rk, res_srtkenmerk rsk "
|
|
+ " WHERE rk.res_srtkenmerk_key = rsk.res_srtkenmerk_key "
|
|
+ " AND rsk.res_srtkenmerk_kenmerktype IN ('R', 'S') "
|
|
+ " AND res_kenmerk_default IS NOT NULL "
|
|
+ " AND res_kenmerk_verwijder IS NULL "
|
|
+ " AND fac.safe_to_number (res_kenmerk_default) IS NULL "
|
|
},
|
|
{ msg: "MLD referentie kenmerksoorten met ongeldige default",
|
|
sql: "SELECT mk.mld_kenmerk_key, mld_srtkenmerk_omschrijving, mld_srtkenmerk_kenmerktype, mld_kenmerk_default"
|
|
+ " FROM mld_kenmerk mk, mld_srtkenmerk msk "
|
|
+ " WHERE mk.mld_srtkenmerk_key = msk.mld_srtkenmerk_key "
|
|
+ " AND msk.mld_srtkenmerk_kenmerktype IN ('R', 'S') "
|
|
+ " AND mld_kenmerk_default IS NOT NULL "
|
|
+ " AND mld_kenmerk_verwijder IS NULL "
|
|
+ " AND fac.safe_to_number (mld_kenmerk_default) IS NULL "
|
|
},
|
|
{ msg: "Vreemde e-mail adressen (zonder @)",
|
|
sql: "SELECT prs_perslid_key, prs_perslid_naam, prs_perslid_email"
|
|
+ " FROM prs_perslid"
|
|
+ " WHERE prs_perslid_verwijder IS NULL"
|
|
+ " AND prs_perslid_email IS NOT NULL"
|
|
+ " AND prs_perslid_email NOT LIKE '%@%'"
|
|
+ " AND prs_perslid_email NOT LIKE '%$%'" // SGF internally anonymized
|
|
},
|
|
{ msg: "Personen waarvan de achternaam begint met een spatie (lastig te vinden in de interface)",
|
|
sql: "SELECT prs_perslid_key, prs_perslid_naam, prs_perslid_voornaam"
|
|
+ " FROM prs_perslid"
|
|
+ " WHERE prs_perslid_verwijder IS NULL"
|
|
+ " AND prs_perslid_naam LIKE ' %'"
|
|
},
|
|
{ msg: "Rechten beperkt tot een afdelingsniveau wat de klant helemaal niet gebruikt. Vreemd!!",
|
|
sql: " SELECT MAX (fac_gebruiker_prs_level_read), fac_groep_omschrijving, fac_functie_omschrijving"
|
|
+ " FROM fac_groep fg, fac_groeprechten g, fac_functie ff, ins_tab_discipline itd"
|
|
+ " WHERE g.FAC_FUNCTIE_KEY = FF.FAC_FUNCTIE_KEY"
|
|
+ " AND fg.FAC_GROEP_KEY = g.fac_groep_key"
|
|
+ " AND BITAND (FF.FAC_FUNCTIE_MIN_LEVEL, 4) = 4" // PRS
|
|
+ " AND fac_gebruiker_prs_level_read > (SELECT MAX(niveau) FROM prs_v_afdeling_boom)"
|
|
+ " AND fac_gebruiker_prs_level_read < 9"
|
|
+ " GROUP BY fac_groep_omschrijving,fac_functie_omschrijving"
|
|
},
|
|
{ msg: "Personen gekoppeld aan afdelingen op niveau XX waarvan de rechten beperkt op een *lagere* afdeling. Vreemd!!",
|
|
sql: "SELECT niveau, prs_perslid_naam, prs_perslid_oslogin"
|
|
+ " FROM prs_perslid pp, prs_v_afdeling_boom ab"
|
|
+ " WHERE pp.prs_afdeling_key = ab.prs_afdeling_key"
|
|
+ " AND prs_perslid_key IN"
|
|
+ " (SELECT prs_perslid_key"
|
|
+ " FROM fac_v_webgebruiker fw, fac_functie ff"
|
|
+ " WHERE FW.FAC_FUNCTIE_KEY = FF.FAC_FUNCTIE_KEY"
|
|
+ " AND BITAND (FF.FAC_FUNCTIE_MIN_LEVEL, 4) = 4" // PRS
|
|
+ " AND fac_gebruiker_prs_level_read > niveau"
|
|
+ " AND fac_gebruiker_prs_level_read < 9" // ==9 is weer een ander probleem, zie volgende test
|
|
+ " AND pp.prs_perslid_key = fw.prs_perslid_key)"
|
|
},
|
|
{ msg: "Groepen met geen leesrechten op PRS-scope Vreemd!!",
|
|
sql: "SELECT G.FAC_GROEP_OMSCHRIJVING,"
|
|
+ " FW.FAC_FUNCTIE_OMSCHRIJVING,"
|
|
+ " ITD.INS_DISCIPLINE_OMSCHRIJVING,"
|
|
+ " gr.*"
|
|
+ " FROM fac_groeprechten gr,"
|
|
+ " fac_groep g,"
|
|
+ " fac_functie fw,"
|
|
+ " ins_tab_discipline itd"
|
|
+ " WHERE g.fac_groep_key = gr.fac_groep_key"
|
|
+ " AND fw.FAC_FUNCTIE_KEY = gr.fac_functie_key"
|
|
+ " AND ITD.INS_DISCIPLINE_KEY = GR.INS_DISCIPLINE_KEY"
|
|
+ " AND BITAND (FAC_FUNCTIE_MIN_LEVEL, 4) = 4" // PRS
|
|
+ " AND fac_gebruiker_prs_level_read = 9"
|
|
},
|
|
{ msg: "Groepen met geen leesrechten op ALG-scope Vreemd!!",
|
|
sql: "SELECT G.FAC_GROEP_OMSCHRIJVING,"
|
|
+ " FW.FAC_FUNCTIE_OMSCHRIJVING,"
|
|
+ " ITD.INS_DISCIPLINE_OMSCHRIJVING,"
|
|
+ " gr.*"
|
|
+ " FROM fac_groeprechten gr,"
|
|
+ " fac_groep g,"
|
|
+ " fac_functie fw,"
|
|
+ " ins_tab_discipline itd"
|
|
+ " WHERE g.fac_groep_key = gr.fac_groep_key"
|
|
+ " AND fw.FAC_FUNCTIE_KEY = gr.fac_functie_key"
|
|
+ " AND ITD.INS_DISCIPLINE_KEY = GR.INS_DISCIPLINE_KEY"
|
|
+ " AND BITAND (FAC_FUNCTIE_MIN_LEVEL, 8) = 8" // PRS
|
|
+ " AND fac_gebruiker_prs_level_read = 9"
|
|
},
|
|
{ msg: "Verwijderde res_rsv_artikel waar de res_rsv_ruimte niet is verwijderd",
|
|
sql: "SELECT *"
|
|
+ " FROM res_rsv_artikel rra, res_rsv_ruimte rrr"
|
|
+ " WHERE rra.res_rsv_ruimte_key = rrr.res_rsv_ruimte_key"
|
|
+ " AND rra.res_rsv_artikel_verwijder IS NOT NULL"
|
|
+ " AND rrr.res_rsv_ruimte_verwijder IS NULL"
|
|
},
|
|
{ msg: "Verwijderde res_rsv_deel waar de res_rsv_ruimte niet is verwijderd",
|
|
sql: "SELECT *"
|
|
+ " FROM res_rsv_deel rrd, res_rsv_ruimte rrr"
|
|
+ " WHERE rrd.res_rsv_ruimte_key = rrr.res_rsv_ruimte_key"
|
|
+ " AND rrd.res_rsv_deel_verwijder IS NOT NULL"
|
|
+ " AND rrr.res_rsv_ruimte_verwijder IS NULL"
|
|
},
|
|
{ msg: "Bestelregel kenmerken gedefinieerd op niet bestaande artikelen (FSN#30485)",
|
|
sql: "SELECT bes_srtkenmerk_omschrijving, bes_kenmerk_key, bk.bes_srtinstallatie_key"
|
|
+ " FROM bes_kenmerk bk, bes_srtkenmerk bsk"
|
|
+ " WHERE bes_kenmerk_verwijder IS NULL"
|
|
+ " AND bes_kenmerk_niveau = 'S'"
|
|
+ " AND bk.bes_srtkenmerk_key = bsk.bes_srtkenmerk_key"
|
|
+ " AND bk.bes_srtinstallatie_key NOT IN"
|
|
+ " (SELECT bes_srtdeel_key FROM bes_srtdeel)"
|
|
},
|
|
{ msg: "Kenmerkdomeinen waarvan de verwezen tabel niet bestaat",
|
|
sql: "SELECT * " +
|
|
" FROM fac_kenmerkdomein " +
|
|
" WHERE fac_kenmerkdomein_verwijder IS NULL " +
|
|
" AND NOT EXISTS " +
|
|
" (SELECT object_name " +
|
|
" FROM user_objects " +
|
|
" WHERE UPPER (fac_kenmerkdomein_objectnaam) = object_name " +
|
|
" AND object_type IN ('VIEW', 'TABLE')) "
|
|
},
|
|
{ msg: "Kenmerkdomeinen (verwijderde) waarvan de verwezen tabel niet bestaat",
|
|
sql: "SELECT * " +
|
|
" FROM fac_kenmerkdomein " +
|
|
" WHERE fac_kenmerkdomein_verwijder IS NOT NULL " +
|
|
" AND NOT EXISTS " +
|
|
" (SELECT object_name " +
|
|
" FROM user_objects " +
|
|
" WHERE UPPER (fac_kenmerkdomein_objectnaam) = object_name " +
|
|
" AND object_type IN ('VIEW', 'TABLE')) "
|
|
},
|
|
{ msg: "Rapportages waarvan de verwezen view niet bestaat (procs niet gecontroleerd)",
|
|
sql: "SELECT * " +
|
|
" FROM fac_usrrap " +
|
|
" WHERE fac_usrrap_functie NOT IN (2, 3) " +
|
|
" AND NOT EXISTS " +
|
|
" (SELECT object_name " +
|
|
" FROM user_objects " +
|
|
" WHERE UPPER (fac_usrrap_view_name) = object_name " +
|
|
" AND object_type IN ('VIEW', 'TABLE')) "
|
|
},
|
|
{ msg: "Menuopties die onterecht met een slash beginnen",
|
|
sql: "SELECT fac_menu_key, fac_menu_volgnr, fac_menu_altlabel, fac_menu_alturl " +
|
|
" FROM fac_menu " +
|
|
" WHERE fac_menu_alturl LIKE '/%'"
|
|
},
|
|
{ msg: "Menuopties naar _edit_ bestanden, moeten meestal naar een wrapper",
|
|
sql: "SELECT fac_menu_key, fac_menu_volgnr, fac_menu_altlabel, fac_menu_alturl " +
|
|
" FROM fac_menu " +
|
|
" WHERE lower(fac_menu_alturl) like '%_edit_%'" +
|
|
" AND lower(fac_menu_alturl) <> 'appl/fac/fac_edit_template.asp'"
|
|
|
|
},
|
|
{ msg: "Bedrijf-adressen zonder protocol. Opdrachten zullen nooit verstuurd worden.",
|
|
sql: " SELECT prs_bedrijf_naam," +
|
|
" prs_bedrijfadres_type," +
|
|
" prs_bedrijfadres_url," +
|
|
" prs_bedrijfadres_xsl," +
|
|
" prs_bedrijf_verwijder" +
|
|
" FROM prs_bedrijfadres pba, prs_bedrijf pb" +
|
|
" WHERE INSTR (prs_bedrijfadres_url, ':') = 0" +
|
|
" AND pba.prs_bedrijf_key = pb.prs_bedrijf_key" +
|
|
" ORDER BY prs_bedrijf_naam"
|
|
},
|
|
{ msg: "Uitvoerende bedrijven met B/C kanaal maar geen O-kanaal.",
|
|
sql: "SELECT b.prs_bedrijf_key," +
|
|
" b.prs_bedrijf_naam," +
|
|
" ba.prs_bedrijfadres_type," +
|
|
" ba.prs_bedrijfadres_url" +
|
|
" FROM prs_bedrijfadres ba, prs_bedrijf b" +
|
|
" WHERE b.prs_bedrijf_key = ba.prs_bedrijf_key" +
|
|
" AND b.prs_bedrijf_uitvoerende = 1" +
|
|
" AND b.prs_bedrijf_verwijder IS NULL" +
|
|
" AND ba.prs_bedrijfadres_type != 'O'" +
|
|
" AND b.prs_bedrijf_key NOT IN (SELECT ba.prs_bedrijf_key" +
|
|
" FROM prs_bedrijfadres ba" +
|
|
" WHERE ba.prs_bedrijfadres_type = 'O')"
|
|
},
|
|
{ msg: "Leverancier bedrijven met O/C kanaal maar geen B-kanaal.",
|
|
sql: "SELECT b.prs_bedrijf_key," +
|
|
" b.prs_bedrijf_naam," +
|
|
" ba.prs_bedrijfadres_type," +
|
|
" ba.prs_bedrijfadres_url" +
|
|
" FROM prs_bedrijfadres ba, prs_bedrijf b" +
|
|
" WHERE b.prs_bedrijf_key = ba.prs_bedrijf_key" +
|
|
" AND b.prs_bedrijf_leverancier = 1" +
|
|
" AND b.prs_bedrijf_verwijder IS NULL" +
|
|
" AND ba.prs_bedrijfadres_type != 'B'" +
|
|
" AND b.prs_bedrijf_key NOT IN (SELECT ba.prs_bedrijf_key" +
|
|
" FROM prs_bedrijfadres ba" +
|
|
" WHERE ba.prs_bedrijfadres_type = 'B')"
|
|
},
|
|
{ msg: "Contract bedrijven met B/O kanaal maar geen C-kanaal.",
|
|
sql: "SELECT b.prs_bedrijf_key," +
|
|
" b.prs_bedrijf_naam," +
|
|
" ba.prs_bedrijfadres_type," +
|
|
" ba.prs_bedrijfadres_url" +
|
|
" FROM prs_bedrijfadres ba, prs_bedrijf b" +
|
|
" WHERE b.prs_bedrijf_key = ba.prs_bedrijf_key" +
|
|
" AND b.prs_bedrijf_contract = 1" +
|
|
" AND b.prs_bedrijf_verwijder IS NULL" +
|
|
" AND ba.prs_bedrijfadres_type != 'C'" +
|
|
" AND b.prs_bedrijf_key NOT IN (SELECT ba.prs_bedrijf_key" +
|
|
" FROM prs_bedrijfadres ba" +
|
|
" WHERE ba.prs_bedrijfadres_type = 'C')"
|
|
}];
|
|
if (S("prs_werkplek_implicit") == 1)
|
|
noResults.push({ msg: "Er zijn werkplekken met meerdere personen er op, foutief als prs_werkplek_implicit = 1",
|
|
sql: "SELECT prs_werkplek_key, COUNT ( * )"
|
|
+ " FROM prs_perslidwerkplek"
|
|
+ " GROUP BY prs_werkplek_key"
|
|
+ " HAVING COUNT ( * ) > 1"
|
|
},
|
|
{ msg: "Er zijn werkplekken zonder personen er op, foutief als prs_werkplek_implicit = 1 (maar niet problematisch)",
|
|
sql: "SELECT prs_werkplek_key FROM prs_werkplek"
|
|
+ " MINUS"
|
|
+ " SELECT prs_werkplek_key FROM prs_perslidwerkplek"
|
|
}
|
|
)
|
|
|
|
var messages = [];
|
|
for (noResult in noResults)
|
|
{
|
|
if (!Response.IsClientConnected)
|
|
{
|
|
__DoLog("Response.IsClientConnected false, Aborting.", "#00FF00");
|
|
Response.End;
|
|
}
|
|
var oRs = Oracle.Execute("SELECT COUNT(*) FROM ("+noResults[noResult].sql+")");
|
|
var cnt = oRs(0);
|
|
if (cnt>0)
|
|
{
|
|
var txt = [noResults[noResult].msg + " ("+cnt+")",
|
|
noResults[noResult].sql];
|
|
if (cnt < 10) // Dan tonen we de data
|
|
{
|
|
oRs.Close();
|
|
var oRs = Oracle.Execute(noResults[noResult].sql);
|
|
tbl = ["<table>"];
|
|
while (!oRs.Eof)
|
|
{
|
|
tbl.push("<tr>");
|
|
for (var i = 0; i < oRs.Fields.Count && i < 5; i++)
|
|
{
|
|
tbl.push("<td>" + safe.html(oRs(i).Value) + "</td>");
|
|
}
|
|
tbl.push("</tr>");
|
|
oRs.MoveNext();
|
|
}
|
|
tbl.push("</table>");
|
|
txt.push(tbl.join(""));
|
|
}
|
|
messages.push(txt.join("<br>"));
|
|
}
|
|
oRs.Close();
|
|
}
|
|
if (!messages.length)
|
|
return { result: resultcodes.ok,
|
|
info: String(noResults.length) + " checks",
|
|
message: "No problems detected" };
|
|
else
|
|
return { result: resultcodes.error,
|
|
info: String(noResults.length) + " checks",
|
|
message: messages.join("\n<p>") };
|
|
}
|
|
)
|
|
|
|
// RWSN#18903: flexkenmerken van type "R" waarvan de waarde niet terug te vinden is
|
|
checker("Controle: melding flexkenmerken van type 'R,S' waarvan de waarde niet terug te vinden is",
|
|
function ()
|
|
{
|
|
var sql = "SELECT *"
|
|
+ " FROM mld_kenmerk mk,"
|
|
+ " mld_srtkenmerk msk,"
|
|
+ " fac_kenmerkdomein mrsk"
|
|
+ " WHERE mk.mld_srtkenmerk_key = msk.mld_srtkenmerk_key"
|
|
+ " AND mld_srtkenmerk_kenmerktype IN ('R','S')"
|
|
+ " AND mld_kenmerk_verwijder IS NULL"
|
|
+ " AND mld_srtkenmerk_verwijder IS NULL"
|
|
+ " AND msk.fac_kenmerkdomein_key = mrsk.fac_kenmerkdomein_key"
|
|
var oRs = Oracle.Execute(sql);
|
|
noResults = [];
|
|
while (!oRs.Eof)
|
|
{
|
|
var fsql = "SELECT TO_CHAR(" + oRs("fac_kenmerkdomein_kolomnaam").Value + ") waarde"
|
|
+ " FROM " + oRs("fac_kenmerkdomein_objectnaam").Value;
|
|
var wheres = [];
|
|
if (oRs("fac_kenmerkdomein_objectnaam").Value == "FAC_USRDATA" && oRs("fac_usrtab_key").Value )
|
|
fsql += " WHERE FAC_USRTAB_KEY=" + oRs("fac_usrtab_key").Value;
|
|
noResults.push({ msg: "meldingen met R/S-flex die niet is terug te vinden. Kenmerk_key: " + oRs("mld_kenmerk_key").Value + ", srtkey: " + oRs("mld_srtkenmerk_key").Value + " ("+oRs("mld_srtkenmerk_omschrijving")+")" ,
|
|
sql: "SELECT * FROM mld_kenmerkmelding mkm"
|
|
+ " WHERE mkm.mld_kenmerk_key = " + oRs("mld_kenmerk_key").Value
|
|
+ " AND mld_kenmerkmelding_waarde NOT IN ("+fsql+")"
|
|
});
|
|
oRs.MoveNext();
|
|
}
|
|
oRs.Close();
|
|
|
|
var messages = [];
|
|
for (noResult in noResults)
|
|
{
|
|
if (!Response.IsClientConnected)
|
|
{
|
|
__DoLog("Response.IsClientConnected false, Aborting.", "#00FF00");
|
|
Response.End;
|
|
}
|
|
var oRs = Oracle.Execute(noResults[noResult].sql);
|
|
if (!oRs.Eof)
|
|
messages.push(noResults[noResult].msg + "\n<br>"+noResults[noResult].sql);
|
|
oRs.Close();
|
|
}
|
|
if (!messages.length)
|
|
return { result: resultcodes.ok,
|
|
info: String(noResults.length) + " checks",
|
|
message: "No problems detected" };
|
|
else
|
|
return { result: resultcodes.error,
|
|
info: String(noResults.length) + " checks",
|
|
message: messages.join("\n<p>") };
|
|
}
|
|
)
|
|
|
|
//------------------------------------------------------------------------------
|
|
// cad/label thema views die niet terug zijn te vinden
|
|
%></table><%
|
|
%>
|
|
</body>
|
|
</html> |