Files
Database/FAC/FAC_PAC.SRC
Maarten van der Heide 5d7de63e6e FSN#23620 Correctie datumtijdnaaruitvoertijd bij begindatum > einddatum
svn path=/Database/trunk/; revision=22875
2014-10-09 13:56:06 +00:00

4506 lines
194 KiB
Plaintext
Raw Blame History

/* $Revision$
* $Id$
*/
/*
* FAC.remember_: Functions voor het bewaren en teruggeven van primary keys binnen triggers.
* Dit om in de after-update nog te weten welke records er nog een nabehandeling hoeven
* Dit kan vaak niet direct omdat de muutatie dan nog bezig is of omdat je pas aan het einde weet of en wat.
*
* De volgende functies zijn beschikbaar:
* - ResetSelectie(TableName) RETURN BOOLEAN:
* Verwijderd de vorige selectie van de Primary-keys van de tabel. Hou hier rekening met multi-user dmv. de
* huidige SessionId. Retourneerd of het gelukt (TRUE) is of niet (FALSE).
* Deze moet aangeroepen worden in de BEFORE-statement-trigger,
* bijvoorbeeld: BEFORE INSERT OR UPDATE OR DELETE ON mld_opdr.
* - SavePrimaryKey(TableName, PrimaryKey) RETURN BOOLEAN:
* Onthou de PrimaryKey-waarde, hou hiet ook rekening met multi-user dmv. de huidige SessionId. Retourneerd
* of het gelukt (TRUE) is of niet (FALSE).
* Deze moet aangeroepen worden in de BEFORE-row-trigger,
* bijvoorbeeld: BEFORE INSERT OR UPDATE ON mld_opdr FOR EACH ROW
* EN : BEFORE DELETE ON mld_opdr FOR EACH ROW
* - GetPrimaryKey(TableName, IndexNr) RETURN NUMBER:
* Geef de nth onthouden PrimaryKey terug, hou hiet ook rekening met multi-user dmv. de huidige SessionId.
* Het IndexNr begint met 1 en loopt door totdat er geen volgende PrimaryKey onthouden is.
* Retourneert de gevonden PrimaryKey of NULL (als er geen volgende is).
* Deze moet aangeroepen worden in de AFTER-statement-trigger,
* bijvoorbeeld: AFTER INSERT OR UPDATE OR DELETE ON mld_opdr.
*
*/
#include "comsql.h"
#include "fac_pacx.src"
#include "fac_pacf.src"
#include "fac_pacl.src"
CREATE OR REPLACE PACKAGE fac AS
BeginWerkUur NUMBER(4,2);
EindWerkUur NUMBER(4,2);
-- Maak de vorige selectie van de tabel en de huidige sessie leeg.
FUNCTION Remember_ResetSelectie( TableName IN VARCHAR2 ) RETURN BOOLEAN;
-- Onthou de primary key van de tabel en de huidige sessie.
FUNCTION Remember_SavePrimaryKey( TableName IN VARCHAR2, PrimaryKey IN NUMBER ) RETURN BOOLEAN;
-- Geef de nth primary key van de tabel en de huidige sessie. IndexNr begint met 1.
FUNCTION Remember_GetPrimaryKey( TableName IN VARCHAR2, IndexNr IN NUMBER ) RETURN NUMBER;
-- Onthou naast Primary key ook de datum i.v.m. een eventuele UNDO vanuit AutoCAD.
FUNCTION Remember_SavePrimaryKeyAndDate( TableName IN VARCHAR2, PrimaryKey IN NUMBER, Datum IN Date ) RETURN BOOLEAN;
-- Geef verwijderdatum of NULL terug van primary key i.v.m. eventuele UNDO vanuit AutoCAD.
FUNCTION Remember_GetDate( TableName IN VARCHAR2, PrimaryKey IN NUMBER ) RETURN DATE;
PRAGMA RESTRICT_REFERENCES (Remember_GetPrimaryKey,WNDS, WNPS);
FUNCTION addMonths (pdate1 IN DATE, padd_mon IN NUMBER) RETURN DATE;
FUNCTION safe_To_Integer( str IN VARCHAR2 ) RETURN NUMBER;
FUNCTION safe_To_Number( str IN VARCHAR2 ) RETURN NUMBER;
FUNCTION safe_To_Date ( pchar IN VARCHAR2, pfmt IN VARCHAR2 ) RETURN DATE;
FUNCTION getweekdaynum (d IN DATE) RETURN NUMBER;
FUNCTION getdomeinwaarde (dkey IN NUMBER, waarde IN VARCHAR2, ignorewhenxmlnode IN NUMBER DEFAULT 0) RETURN VARCHAR2;
FUNCTION count_Work_Days ( pdate1 IN DATE , pdate2 IN DATE ) RETURN NUMBER;
FUNCTION count_Work_Days_InclTime ( pdate1 IN DATE , pdate2 IN DATE ) RETURN NUMBER;
FUNCTION datumtijdplusuitvoertijd (begindatum IN DATE, uitvoertijd IN NUMBER, uitvoertijdtype IN VARCHAR2) RETURN DATE;
FUNCTION datumtijdplusuitvoertijd (begindatum IN DATE, uitvoertijd IN NUMBER, uitvoertijdtype IN VARCHAR2,
pBeginWerkUur IN NUMBER, pEindWerkUur IN NUMBER, pMode IN NUMBER) RETURN DATE;
FUNCTION datumtijdnaaruitvoertijd (begindatum IN DATE, einddatum IN DATE, uitvoertijdtype IN VARCHAR2) RETURN MLD_T_UITVOERTIJD;
FUNCTION datumtijdnaaruitvoertijd (begindatum IN DATE, einddatum IN DATE, uitvoertijdtype IN VARCHAR2,
pBeginWerkUur IN NUMBER, pEindWerkUur IN NUMBER, pMode IN NUMBER) RETURN MLD_T_UITVOERTIJD;
FUNCTION getdatemillisec (i_date IN DATE) RETURN NUMBER;
FUNCTION usrrap_query (p_tabelnaam IN VARCHAR2) RETURN VARCHAR2;
FUNCTION usrrap_orderby (p_tabelnaam IN VARCHAR2) RETURN VARCHAR2;
PROCEDURE tabelize_usrraps;
PROCEDURE imp_getfield ( p_parseline IN OUT VARCHAR2,
p_fielddelimitor IN VARCHAR2,
p_field OUT VARCHAR2
);
PROCEDURE imp_getfield_nr (p_parseline IN VARCHAR2,
p_fielddelimitor IN VARCHAR2,
p_nr IN NUMBER,
p_field OUT VARCHAR2
);
PROCEDURE imp_writelog( p_import_key IN NUMBER,
pLevel IN VARCHAR2,
pMsg IN VARCHAR2,
pHint IN VARCHAR2
);
PROCEDURE writelog( pAppl IN VARCHAR2,
pLevel IN VARCHAR2,
pMsg IN VARCHAR2,
pHint IN VARCHAR2
);
PROCEDURE imp_alg_delete_onrgoed (p_import_key IN NUMBER, p_mode IN NUMBER);
PROCEDURE imp_prs_delete_organisatie (p_import_key IN NUMBER, p_mode IN NUMBER);
PROCEDURE imp_mld_delete_mld (p_import_key IN NUMBER, p_mode IN NUMBER);
PROCEDURE fac_perfmon_incr(limiet IN NUMBER, zwaarte IN NUMBER);
PROCEDURE putnotificationprio (pfrom NUMBER, pto NUMBER, pmessage VARCHAR2, pmode NUMBER,
poptemail VARCHAR2, poptmobile VARCHAR2, pprio NUMBER, pattach VARCHAR2 DEFAULT NULL);
PROCEDURE putnotification (pfrom NUMBER, pto NUMBER, pmessage VARCHAR2, pmode NUMBER,
poptemail VARCHAR2, poptmobile VARCHAR2);
PROCEDURE putsystemnotification (pmessage VARCHAR2, pmode NUMBER);
PROCEDURE putnotificationsrtprio (pfrom NUMBER, pto NUMBER, pcode VARCHAR2, pref NUMBER,
poptmessage VARCHAR2, poptstatus NUMBER, poptemail VARCHAR2, poptmobile VARCHAR2, pxref NUMBER,
pprio NUMBER, psender VARCHAR2, pattach VARCHAR2 DEFAULT NULL);
PROCEDURE clrnotifications (pcode VARCHAR2, pref NUMBER);
PROCEDURE clrnotifications (pcode VARCHAR2, pref NUMBER, psubject VARCHAR2, preceiver NUMBER);
PROCEDURE putnotificationjobs (pcust VARCHAR2);
PROCEDURE putjobnotifications (pviewname VARCHAR2, pmode NUMBER, pflags NUMBER);
FUNCTION getMobile ( pkey IN NUMBER ) RETURN VARCHAR2;
PROCEDURE executeschedules;
PROCEDURE markorderassent(pxmlnode VARCHAR2, pkey NUMBER, presult NUMBER, presulttext VARCHAR2);
FUNCTION getSetting (pname IN VARCHAR2 ) RETURN VARCHAR2;
PROCEDURE trackaction (pcode VARCHAR2, prefkey NUMBER, puserkey NUMBER, pdatum DATE, poms VARCHAR2);
PROCEDURE backtrackaction (pcode VARCHAR2, prefkey NUMBER, puserkey NUMBER, pdatum DATE);
PROCEDURE notifytracking(psrtnotificatiekey NUMBER, pperslid_key NUMBER, ptracking_oms VARCHAR2, prefkey NUMBER);
FUNCTION gettrackingdate (peventcode IN VARCHAR2, pkey IN number) RETURN date;
FUNCTION gettrackinguserkey (peventcode IN VARCHAR2, pkey IN number) RETURN number;
PROCEDURE initsession (flcode IN VARCHAR2);
PROCEDURE registerversion (pmaj IN NUMBER, pmin IN NUMBER, ppatch IN VARCHAR2, pschema IN VARCHAR2, plang IN VARCHAR2);
PROCEDURE registercustversion (pcustid IN VARCHAR2, pcustnr IN NUMBER);
FUNCTION getdbversion RETURN VARCHAR2;
PROCEDURE processemail (pfrom IN VARCHAR2, pto IN VARCHAR2, psubject IN VARCHAR2, pbody IN VARCHAR2, pextra IN VARCHAR2);
FUNCTION isdatefeestdag(p_date IN DATE) RETURN BOOLEAN;
FUNCTION calcnextcyclusdate (p_date IN DATE, p_mode IN NUMBER, p_eenheid IN NUMBER, p_periode IN NUMBER, p_bits IN NUMBER) RETURN DATE;
FUNCTION nextcyclusdate (p_date IN DATE, p_mode IN NUMBER, p_eenheid IN NUMBER, p_periode IN NUMBER, p_bits IN NUMBER, p_steps IN NUMBER DEFAULT 0) RETURN DATE;
FUNCTION nextcyclusdate (p_insdeel IN NUMBER, p_srtcontrole IN NUMBER, p_steps IN NUMBER DEFAULT 0) RETURN DATE;
FUNCTION nextcyclusdatesteps (p_date IN DATE, p_mode IN NUMBER, p_eenheid IN NUMBER, p_periode IN NUMBER, p_bits IN NUMBER, p_steps IN NUMBER DEFAULT 1, p_enddate IN DATE DEFAULT SYSDATE) RETURN NUMBER;
FUNCTION nextcyclusdatesteps (p_insdeel IN NUMBER, p_srtcontrole IN NUMBER, p_steps IN NUMBER DEFAULT 1) RETURN NUMBER;
FUNCTION makehash (p_in VARCHAR2, method IN VARCHAR2 DEFAULT 'MD5') RETURN VARCHAR2;
FUNCTION testhash (p_hash VARCHAR2, p_in VARCHAR2) RETURN NUMBER;
END fac;
/
CREATE OR REPLACE PACKAGE BODY fac AS
FUNCTION remember_resetselectie (tablename IN VARCHAR2)
RETURN BOOLEAN
IS
sessionid VARCHAR2 (20);
BEGIN
sessionid := USERENV ('SESSIONID');
DELETE FROM fac_selectie
WHERE fac_selectie_node = sessionid AND fac_selectie_tabel = tablename;
RETURN TRUE;
EXCEPTION
WHEN OTHERS
THEN
RETURN FALSE;
END;
FUNCTION remember_saveprimarykey (tablename IN VARCHAR2, primarykey IN NUMBER)
RETURN BOOLEAN
IS
BEGIN
INSERT INTO fac_selectie (fac_selectie_node, fac_selectie_tabel, fac_selectie_key)
VALUES (USERENV ('SESSIONID'), tablename, primarykey);
RETURN TRUE;
EXCEPTION
WHEN OTHERS
THEN
RETURN FALSE;
END;
-- Geef de nth Fac_Selectie_Key van de geselecteerde records
-- terug. IndexNr begint met 1.
FUNCTION remember_getprimarykey (tablename IN VARCHAR2, indexnr IN NUMBER)
RETURN NUMBER
IS
CURSOR selectie
IS
SELECT DISTINCT fac_selectie_key
FROM fac_selectie
WHERE fac_selectie_node = USERENV ('SESSIONID') AND fac_selectie_tabel = tablename
ORDER BY fac_selectie_key;
selectierec selectie%ROWTYPE;
tmpindex NUMBER;
returnkey NUMBER (10);
BEGIN
returnkey := NULL;
tmpindex := 1;
FOR selectierec IN selectie
LOOP
IF indexnr = tmpindex
THEN
returnkey := selectierec.fac_selectie_key;
EXIT;
END IF;
tmpindex := tmpindex + 1;
END LOOP;
RETURN returnkey;
END;
FUNCTION remember_saveprimarykeyanddate (tablename IN VARCHAR2,
primarykey IN NUMBER,
datum IN DATE)
RETURN BOOLEAN
IS
BEGIN
INSERT INTO fac_selectie (fac_selectie_node,
fac_selectie_tabel,
fac_selectie_key,
fac_selectie_datum)
VALUES (USERENV ('SESSIONID'),
tablename,
primarykey,
datum);
RETURN TRUE;
EXCEPTION
WHEN OTHERS
THEN
RETURN FALSE;
END;
FUNCTION remember_getdate (tablename IN VARCHAR2, primarykey IN NUMBER)
RETURN DATE
IS
returndate DATE;
CURSOR selectie
IS
SELECT DISTINCT fac_selectie_datum
FROM fac_selectie
WHERE fac_selectie_node = USERENV ('SESSIONID')
AND fac_selectie_key = primarykey
AND fac_selectie_tabel = tablename;
selectierec selectie%ROWTYPE;
tmpindex NUMBER;
returnkey NUMBER (10);
BEGIN
returndate := NULL;
FOR selectierec IN selectie
LOOP
returndate := selectierec.fac_selectie_datum;
EXIT;
END LOOP;
RETURN returndate;
END;
-- This function is to be used instead of the native ADD_MONTHS function
-- If 29, 30 or 31 date doesn't exist in the month then de first of the next month is taken
FUNCTION addMonths (pdate1 IN DATE, padd_mon IN NUMBER) RETURN DATE IS
pdate2 date;
BEGIN
pdate2:= ADD_MONTHS(pdate1-1, padd_mon);
IF LAST_DAY(pdate1) = pdate1 OR LAST_DAY(pdate2) = pdate2
THEN
RETURN pdate2+1;
ELSE
RETURN ADD_MONTHS(pdate1, padd_mon);
END IF;
END;
-- This function is to be used instead of the native TO_NUMBER in situations
-- where the value might be an invalid number like '206E9547' ('Numeric overflow')
FUNCTION safe_To_Integer( str IN VARCHAR2 ) RETURN NUMBER IS
BEGIN
RETURN TO_NUMBER(REGEXP_SUBSTR(str, '^\d+') ); // alleen leading cijfers
EXCEPTION
WHEN OTHERS THEN RETURN NULL;
END;
-- This function is to be used instead of the native TO_NUMBER in situations
-- where the value might be an invalid number. This is the case for (FSN#203)
-- flexible properties as in FAC.SAFE_TO_NUMBER(alg_onrgoedkenmerk_waarde)<200
-- It returns NULL instead of an ORA1722:error (or even another error)
FUNCTION safe_To_Number( str IN VARCHAR2 ) RETURN NUMBER IS
BEGIN
RETURN TO_NUMBER(str);
EXCEPTION
WHEN OTHERS THEN RETURN NULL;
END;
FUNCTION safe_To_Date( pchar IN VARCHAR2, pfmt IN VARCHAR2 ) RETURN DATE IS
BEGIN
RETURN TO_DATE(pchar, pfmt);
EXCEPTION
WHEN OTHERS THEN RETURN NULL;
END;
-- Levert het dow-nummer op (1-7), op een nls-onafhankelijke wijze
FUNCTION getweekdaynum (d IN DATE) RETURN NUMBER IS
BEGIN
RETURN MOD (TO_CHAR (d, 'J') + 1, 7) + 1;
END;
/*
* Levert de gerefereerde waarde van een flexkenmerk op, gegeven de fac_kenmerkdomein_key en de waarde
* Ten behoeve van de XML-generatie is parameter ignorewhenxmlnode; daarmee kan worden aangegeven (1)
* dat in geval van een referentiekenmerk met een xmlnode niet de waarde maar gewoon de oorspronkelijke
* key moet worden teruggeven waarmee later een complete subnode wordt gemaakt. Het teruggeven van de naam
* zou die key kwijtmaken.
*/
FUNCTION getdomeinwaarde (dkey IN NUMBER, waarde IN VARCHAR2, ignorewhenxmlnode IN NUMBER DEFAULT 0)
RETURN VARCHAR2
IS
sresult VARCHAR2 (255);
kolomnaam fac_kenmerkdomein.fac_kenmerkdomein_kolomnaam%TYPE;
kolomtxt fac_kenmerkdomein.fac_kenmerkdomein_kolomtxt%TYPE;
objectnaam fac_kenmerkdomein.fac_kenmerkdomein_objectnaam%TYPE;
xmlnode fac_kenmerkdomein.fac_kenmerkdomein_xmlnode%TYPE;
resultvalue VARCHAR2 (1000);
BEGIN
IF waarde IS NULL
THEN
resultvalue := NULL; -- gauw klaar mee
ELSE
SELECT rsk.fac_kenmerkdomein_kolomnaam,
rsk.fac_kenmerkdomein_kolomtxt,
rsk.fac_kenmerkdomein_objectnaam,
rsk.fac_kenmerkdomein_xmlnode
INTO kolomnaam,
kolomtxt,
objectnaam,
xmlnode
FROM fac_kenmerkdomein rsk
WHERE rsk.fac_kenmerkdomein_key = dkey;
IF (xmlnode IS NOT NULL AND ignorewhenxmlnode = 1)
THEN
RETURN waarde;
END IF;
-- Optimalisatie: meestal is het dezelfde query op de usrdata-tabel
-- Dan hoeven we niet te bouwen en steeds te parsen (FSN#25653)
IF kolomtxt = 'FAC_USRDATA_OMSCHR'
AND objectnaam = 'FAC_USRDATA'
AND kolomnaam = 'FAC_USRDATA_KEY'
THEN
SELECT fac_usrdata_omschr
INTO resultvalue
FROM fac_usrdata
WHERE fac_usrdata_key = fac.safe_to_number(waarde);
ELSE
sresult := 'SELECT MIN(' || kolomtxt || ') FROM ' || objectnaam || ' WHERE ' || kolomnaam || ' = :bd_waarde';
EXECUTE IMMEDIATE sresult INTO resultvalue USING waarde;
END IF;
END IF;
RETURN resultvalue;
END;
-- Sluit weekend en vrije dagen uit
FUNCTION iswerkdag (begindatum IN DATE)
RETURN NUMBER
AS
dagvdweek NUMBER;
vrijedagen NUMBER;
BEGIN
dagvdweek := fac.getweekdaynum(begindatum);
IF dagvdweek = 1 OR dagvdweek = 7
THEN
RETURN 0;
END IF;
-- kijk of de begindatum op een vrije dag valt.
SELECT COUNT ( * )
INTO vrijedagen
FROM mld_vrije_dagen
WHERE mld_vrije_dagen_datum = TRUNC (begindatum);
IF vrijedagen = 1
THEN
RETURN 0;
ELSE
RETURN 1;
END IF;
END;
-- Return number of workdays between two dates, not including the startdate, weekends and holidays
FUNCTION count_Work_Days0( pdate1 IN DATE , pdate2 IN DATE, pInclTime IN BOOLEAN ) RETURN NUMBER IS
eikdag NUMBER;
v_date_from DATE;
v_date_to DATE;
v_time_from NUMBER;
v_time_to NUMBER;
v_extra_day NUMBER;
lbackwards BOOLEAN;
v_week NUMBER;
v_mod NUMBER;
v_day_from NUMBER;
v_day_to NUMBER;
v_holidays NUMBER;
BEGIN
-- Dit is een maandag, is dat volgens de huidige territory dag 2?
eikdag := TO_NUMBER (TO_CHAR (TO_DATE('01-01-2007', 'DD-MM-YYYY'), 'D'));
IF eikdag <> 2
THEN
-- WE MOETEN met zondag=1 werken (geen nieuwe eis, wel duidelijker probleem)
raise_application_error (-20000, 'Facilitor: Invalid NLS_TERRITORY');
END IF;
-- Remove time-part from dates (ie. set to 0:00) and set dates chronologically
IF pdate1 > pdate2 THEN
v_date_from := TRUNC(pdate2);
v_date_to := TRUNC(pdate1);
v_time_from := to_char(pdate2,'sssss');
v_time_to := to_char(pdate1,'sssss');
lbackwards := TRUE;
ELSE
v_date_from := TRUNC(pdate1);
v_date_to := TRUNC(pdate2);
v_time_from := to_char(pdate1,'sssss');
v_time_to := to_char(pdate2,'sssss');
lbackwards := FALSE;
END IF;
-- Determine whole weeks (v_week) and remaining days (v_mod) between FROM and TO
v_week := trunc((v_date_to - v_date_from)/7);
v_mod := mod((v_date_to - v_date_from),7);
-- Correct remaining days (v_mod) depending on the FROM and TO "day-number"
v_day_from := to_number(DATE_TO_CHAR(v_date_from,'d'));
v_day_to := to_number(DATE_TO_CHAR(v_date_to,'d'));
IF v_day_from = 1 THEN /* FROM is sunday */
IF v_day_to = 7 THEN /* TO is saturday */
v_mod := v_mod - 1; /* should always be 5! */
END IF;
ELSIF v_day_from = 7 THEN /* FROM is saturday */
IF v_day_to != 7 THEN /* TO is not saturday */
v_mod := v_mod - 1; /* exclude sunday succeeding FROM-saturday */
END IF;
ELSE /* FROM is workday */
IF v_day_to = 7 THEN /* TO is saturday */
v_mod := v_mod - 1; /* exclude TO-saturday */
ELSIF v_day_to < v_day_from THEN /* weekend between FROM and TO */
v_mod := v_mod - 2; /* exclude weekend */
END IF;
END IF;
-- Tbv. incltime-variant geldt extra dag als TO-tijd > FROM-tijd, behalve als TO
-- in het weekend of op een vrije dag valt!
SELECT COUNT(*)
INTO v_extra_day
FROM DUAL
WHERE v_time_to > v_time_from
AND v_day_to NOT IN (1, 7)
AND NOT EXISTS
(SELECT 1
FROM MLD_VRIJE_DAGEN
WHERE TRUNC (MLD_VRIJE_DAGEN_DATUM) = v_date_to);
-- Determine the registered holidays between FROM+1 (excluding startdate!) and TO
SELECT count(*)
INTO v_holidays
FROM MLD_VRIJE_DAGEN
WHERE MLD_VRIJE_DAGEN_DATUM BETWEEN v_date_from+1 AND v_date_to;
IF lbackwards THEN
RETURN 0 - (5 * v_week + v_mod + v_extra_day - v_holidays);
ELSE
RETURN 5 * v_week + v_mod + v_extra_day - v_holidays;
END IF;
EXCEPTION
WHEN OTHERS THEN RETURN NULL;
END;
FUNCTION count_Work_Days_InclTime( pdate1 IN DATE , pdate2 IN DATE ) RETURN NUMBER IS
BEGIN
RETURN count_Work_Days0(pdate1,pdate2, TRUE);
END;
FUNCTION count_Work_Days( pdate1 IN DATE , pdate2 IN DATE ) RETURN NUMBER IS
BEGIN
RETURN count_Work_Days0(pdate1,pdate2, FALSE);
END;
/*
** Bepaal een nieuwe datum van de begindatum waarbij de uitvoertijd is
** opgeteld. De uitvoertijd (UitvoerTijdType) kan in 'UREN' of in 'DAGEN' zijn.
** Er wordt rekening gehouden met Werkuren, BeginWerkTijd en EindWerkTijd en
** Weekenddagen (Zondag = 1, Zaterdag = 7) en Vrije dagen (MLD_VRIJE_DAGEN).
** Testscript beschikbaar: /SRC/SQL/_UTIL/test_datumtijd.sql.
*/
FUNCTION datumtijdplusuitvoertijd (begindatum IN DATE, uitvoertijd IN NUMBER, uitvoertijdtype IN VARCHAR2) RETURN DATE
IS
BEGIN
IF BeginWerkUur IS NULL OR EindWerkUur IS NULL
THEN
BeginWerkUur := fac.safe_to_number (fac.getsetting ('fac_t_startofworkday')); // half 8 is 7.5 en niet 7.30
EindWerkUur := fac.safe_to_number (fac.getsetting ('fac_t_endofworkday'));
DBMS_OUTPUT.put_line ('Recaching Werkuren ' || BeginWerkUur||'..'||EindWerkUur);
END IF;
RETURN datumtijdplusuitvoertijd (begindatum, uitvoertijd, uitvoertijdtype,
BeginWerkUur, EindWerkUur, 1); // 1=alleen werkdagen excl. vrije dagen
END;
-- Bereken de einddatum gegeven de begindatum en uitvoertijd. De mode bepaalt
-- hoe dagen/tijden meetellen als volgt:
-- 0 => alle dagen van de week excl. vrije dagen en uren tussen begin- en eindtijd
-- 1 => alleen werkdagen excl. vrije dagen en uren tussen begin- en eindtijd
-- 2 => 24/7 => alle 7 dagen van de week incl. vrije dagen en alle 24 uren per dag
FUNCTION datumtijdplusuitvoertijd (begindatum IN DATE,
uitvoertijd IN NUMBER,
uitvoertijdtype IN VARCHAR2,
pBeginWerkUur IN NUMBER,
pEindWerkUur IN NUMBER,
pMode IN NUMBER)
RETURN DATE
IS
returnval DATE;
eikdag NUMBER;
vrijedag NUMBER;
datumbegin DATE;
dagenperweek NUMBER;
weekdagbegin NUMBER;
olddatumgereed DATE;
newdatumgereed DATE;
delta NUMBER;
aantalwerkweken NUMBER;
aantaldagenover NUMBER;
weekdaggereed NUMBER;
urenperdag NUMBER (7, 4); -- 4 decimalen i.v.m. afrondingsfouten
aantalwerkdagen NUMBER;
aantalurenover NUMBER;
beginuur NUMBER (7, 4); -- 4 decimalen i.v.m. afrondingsfouten
gereeduur NUMBER (7, 4); -- 4 decimalen i.v.m. afrondingsfouten
BEGIN
returnval := NULL;
-- Dit is een maandag, is dat volgens de huidige territory dag 2?
eikdag :=
TO_NUMBER (TO_CHAR (TO_DATE ('01-01-2007', 'DD-MM-YYYY'), 'D'));
IF eikdag <> 2
THEN -- We MOETEN met zo=1 werken (geen nieuwe eis, wel duidelijker probleem).
raise_application_error (-20000, 'Facilitor: Invalid NLS_TERRITORY (should be AMERICA)');
END IF;
-- Veronderstelt NLS_TERRITORY='AMERICA'.
IF begindatum IS NOT NULL
AND uitvoertijd IS NOT NULL
AND pMode BETWEEN 0 AND 2
THEN
IF pMode = 2
THEN
-- Zo simpel kan het zijn (igv. 24/7)!
IF uitvoertijdtype IN ('D', 'DAGEN')
THEN
returnval := begindatum + uitvoertijd;
ELSIF uitvoertijdtype IN ('U', 'UREN')
THEN
returnval := begindatum + (uitvoertijd / 24);
ELSE
returnval := NULL;
END IF;
ELSIF pBeginWerkUur BETWEEN 0 AND 24
AND pEindWerkUur BETWEEN 0 AND 24
AND pEindWerkUur > pBeginWerkUur
THEN
-- Verschuif begindatum als deze valt [a] buiten de meegegeven uren of [b] op
-- een vrije dag. Dit geldt Kantoortijden- of Openingstijden-regime!
SELECT COUNT ( * )
INTO vrijedag
FROM mld_vrije_dagen
WHERE mld_vrije_dagen_datum = TRUNC (begindatum);
IF (begindatum > TRUNC (begindatum) + (pEindWerkUur / 24) OR vrijedag = 1)
THEN
-- Als begintijd na 'pEindWerkUur', dan naar 'pBeginWerkUur' volgende dag;
-- hetzelfde als begindag is een vrije dag.
-- En als deze volgende dag is een vrije dag, dan volgt vanzelf compensatie!
datumbegin := TRUNC (begindatum + 1) + (pBeginWerkUur / 24);
ELSIF (begindatum < TRUNC (begindatum) + (pBeginWerkUur / 24))
THEN
-- Als begintijd voor 'pBeginWerkUur', dan naar 'pBeginWerkUur' huidige dag.
datumbegin := TRUNC (begindatum) + (pBeginWerkUur / 24);
ELSE
-- Anders 1-op-1 overnemen.
datumbegin := begindatum;
END IF;
IF pMode = 0
THEN
-- Alle dagen van de week excl. vrije dagen (= alle dagen-variant van
-- Openingstijden-regime)!
dagenperweek := 7;
ELSE -- pMode = 1
-- Alleen werkdagen excl. vrije dagen (= Kantoortijden-regime en alleen
-- werkdagen-variant van Openingstijden-regime)!
dagenperweek := 5;
-- Verschuif (gewijzigde) datumbegin als deze in het weekend valt.
weekdagbegin := fac.getweekdaynum (datumbegin); -- zo=1 t/m za=7
IF weekdagbegin = 1
THEN
-- Als zo=1, dan schuif 1 dag door naar maandag 'pBeginWerkUur'.
datumbegin := TRUNC (datumbegin + 1) + (pBeginWerkUur / 24);
ELSIF weekdagbegin = 7
THEN
-- Als za=7, dan schuif 2 dagen door naar maandag 'pBeginWerkUur'.
datumbegin := TRUNC (datumbegin + 2) + (pBeginWerkUur / 24);
END IF;
END IF;
IF uitvoertijdtype IN ('D', 'DAGEN')
THEN
newdatumgereed := datumbegin;
delta := uitvoertijd;
-- Herhaal onderstaande zolang er een delta is:
-- [a] bereken datumgereed = datumbegin + delta-werkdagen.
-- [b] bepaal nieuwe delta = vrije dagen tussen datumbegin en datumgereed.
LOOP
olddatumgereed := newdatumgereed;
weekdagbegin := fac.getweekdaynum (olddatumgereed); -- ma=2 t/m vr=6
aantalwerkweken := TRUNC (delta / dagenperweek);
aantaldagenover := delta MOD dagenperweek;
-- Een/elke werkweek zorgt voor een doorlooptijd van 7 kalenderdagen.
newdatumgereed := olddatumgereed + (aantalwerkweken * 7) + aantaldagenover;
-- Verschuif newdatumgereed als gereedtijd buiten de meegegeven uren valt.
-- LET OP: Komt alleen voor als uitvoertijd decimalen bevat! Kan dat?
IF (newdatumgereed < TRUNC (newdatumgereed) + (pBeginWerkUur / 24))
THEN
-- Als gereedtijd voor 'pBeginWerkUur', dan naar 'pBeginWerkUur' huidige dag.
newdatumgereed := TRUNC (newdatumgereed) + (pBeginWerkUur / 24);
ELSIF (newdatumgereed > TRUNC (newdatumgereed) + (pEindWerkUur / 24))
THEN
-- Als gereedtijd na 'pEindWerkUur', dan naar 'pBeginWerkUur' volgende dag.
newdatumgereed := TRUNC (newdatumgereed + 1) + (pBeginWerkUur / 24);
END IF;
-- Compenseer eventueel (eind)weekend afhankelijk van 'aantaldagenover'.
weekdaggereed := fac.getweekdaynum (newdatumgereed); -- zo=1 t/m za=7
IF pMode = 1
AND (weekdaggereed = 7 OR weekdagbegin > weekdaggereed)
AND delta <> 0
THEN
-- Als za=7 of weekdagbegin > weekdaggereed, dan 2 dagen optellen!
newdatumgereed := newdatumgereed + 2;
END IF;
-- Bepaal nieuwe delta.
SELECT COUNT ( * )
INTO delta
FROM (SELECT * FROM mld_vrije_dagen
MINUS -- Igv. pMode=1 za+zo niet meetellen; deze worden sowieso geskipt!
SELECT * FROM mld_vrije_dagen
WHERE pMode = 1 AND fac.getweekdaynum (mld_vrije_dagen_datum) IN (1,7))
WHERE mld_vrije_dagen_datum BETWEEN TRUNC (olddatumgereed) AND newdatumgereed;
EXIT WHEN delta = 0;
END LOOP;
returnval := newdatumgereed;
ELSIF uitvoertijdtype IN ('U', 'UREN')
THEN
-- Bepaal gereedtijd, dan hoeft daarna alleen nog maar in werkdagen te worden geschoven!
urenperdag := pEindWerkUur - pBeginWerkUur;
aantalwerkdagen := TRUNC (uitvoertijd / urenperdag); -- werkdagen
aantalurenover := uitvoertijd MOD urenperdag; -- rest uren
beginuur := (datumbegin - TRUNC (datumbegin)) * 24;
gereeduur := beginuur + aantalurenover;
IF (gereeduur > pEindWerkUur)
THEN
-- Als gereeduur na 'pEindWerkUur', dan corrigeren en dus een extra dag.
gereeduur := pBeginWerkUur + aantalurenover - (pEindWerkUur - beginuur);
aantalwerkdagen := aantalwerkdagen + 1; -- inclusief extra dag
END IF;
newdatumgereed := datumtijdplusuitvoertijd (datumbegin, aantalwerkdagen, 'DAGEN', pBeginWerkUur, pEindWerkUur, pMode);
--Belangrijk: nu nog de eerder bepaalde gereedtijd zetten!
returnval := TRUNC (newdatumgereed) + (gereeduur / 24);
END IF;
END IF;
END IF;
RETURN returnval;
END;
-- datumtijdnaaruitvoertijd is bedoeld als 100% de inverse van datumtijdplusuitvoertijd
-- Invariant:
-- datumtijdplusuitvoertijd(begin, datumtijdnaaruitvoertijd(begin, eind, type), type) == eind
-- datumtijdnaaruitvoertijd(begin, datumtijdplusuitvoertijd(begin, uitvoertijd, type), type) == uitvoertijd
-- Is de luxe versie van count_Work_Days
FUNCTION datumtijdnaaruitvoertijd (begindatum IN DATE, einddatum IN DATE, uitvoertijdtype IN VARCHAR2) RETURN MLD_T_UITVOERTIJD
AS
BEGIN
IF BeginWerkUur IS NULL OR EindWerkUur IS NULL
THEN
BeginWerkUur := fac.safe_to_number (fac.getsetting ('fac_t_startofworkday')); // half 8 is 7.5 en niet 7.30
EindWerkUur := fac.safe_to_number (fac.getsetting ('fac_t_endofworkday'));
DBMS_OUTPUT.put_line ('Recaching Werkuren ' || BeginWerkUur||'..'||EindWerkUur);
END IF;
RETURN datumtijdnaaruitvoertijd (begindatum, einddatum, uitvoertijdtype,
BeginWerkUur, EindWerkUur, 1); // 1=alleen werkdagen excl. vrije dagen
END datumtijdnaaruitvoertijd;
FUNCTION datumtijdnaaruitvoertijd (begindatum IN DATE,
einddatum IN DATE,
uitvoertijdtype IN VARCHAR2,
pBeginWerkUur IN NUMBER,
pEindWerkUur IN NUMBER,
pMode IN NUMBER)
RETURN MLD_T_UITVOERTIJD
AS
uitvoertijd mld_stdmelding.mld_stdmelding_t_uitvoertijd%TYPE := MLD_T_UITVOERTIJD(NULL, NULL); -- constructor initialisatie
urenperdag NUMBER (10, 3);
eerstedag NUMBER (10, 3);
laatstedag NUMBER (10, 3);
heledagen NUMBER (10);
vrijedagen NUMBER;
BEGIN
IF begindatum IS NOT NULL
AND einddatum IS NOT NULL
AND pMode BETWEEN 0 AND 2
THEN
IF begindatum > einddatum
THEN
uitvoertijd := datumtijdnaaruitvoertijd (einddatum, begindatum, uitvoertijdtype, pBeginWerkUur, pEindWerkUur, pMode);
uitvoertijd.tijdsduur := -uitvoertijd.tijdsduur;
ELSIF pMode = 2
THEN
-- Zo simpel kan het zijn igv. 24/7!
IF uitvoertijdtype IN ('D', 'DAGEN')
THEN
-- Per 5.4.3 kunnen hier gebroken dagen worden teruggegeven!
uitvoertijd.tijdsduur := einddatum - begindatum;
uitvoertijd.eenheid := 'D';
ELSE -- default/uitvoertijdtype IN ('U', 'UREN')
uitvoertijd.tijdsduur := (einddatum - begindatum) * 24;
uitvoertijd.eenheid := 'U';
END IF;
ELSIF pBeginWerkUur BETWEEN 0 AND 24
AND pEindWerkUur BETWEEN 0 AND 24
AND pEindWerkUur > pBeginWerkUur
THEN
urenperdag := pEindWerkUur - pBeginWerkUur;
eerstedag := pEindWerkUur - (TRUNC (begindatum, 'MI') - TRUNC (begindatum)) * 24;
eerstedag := LEAST (GREATEST (0, eerstedag), urenperdag);
laatstedag := (TRUNC (einddatum, 'MI') - TRUNC (einddatum)) * 24 - pBeginWerkUur;
laatstedag := LEAST (GREATEST (0, laatstedag), urenperdag);
IF pMode = 0
THEN
-- Oppassen als begin/eind op een vrije dag valt,
-- dan moeten eerste/laatste dag gewoon 0 uur zijn.
SELECT COUNT ( * )
INTO vrijedagen
FROM mld_vrije_dagen
WHERE mld_vrije_dagen_datum = TRUNC (begindatum);
IF vrijedagen = 1
THEN
eerstedag := 0;
END IF;
SELECT COUNT ( * )
INTO vrijedagen
FROM mld_vrije_dagen
WHERE mld_vrije_dagen_datum = TRUNC (einddatum);
IF vrijedagen = 1
THEN
laatstedag := 0;
END IF;
IF TRUNC (begindatum) = TRUNC (einddatum)
THEN
IF eerstedag + laatstedag > 0 -- geen vrije dag!
THEN
-- Als begindatum=einddatum <20>n werkdag, dan 1 dag corrigeren!
heledagen := -1;
ELSE
-- Als begindatum=einddatum <20>n vrije dag, dan geen correctie!
heledagen := 0;
END IF;
ELSE
-- Als begindatum<>einddatum, dan alleen nog vrije dagen tussen
-- begin+1 en eind-1 corrigeren (en altijd 0 als begin+1=eind)!
SELECT COUNT ( * )
INTO vrijedagen
FROM mld_vrije_dagen
WHERE mld_vrije_dagen_datum BETWEEN TRUNC (begindatum + 1) AND einddatum - 1;
IF TRUNC (begindatum+1) = TRUNC (einddatum)
THEN
heledagen := 0;
ELSE
heledagen := TRUNC (begindatum + 1) - TRUNC (einddatum - 1) - vrijedagen;
END IF;
END IF;
ELSE -- pMode = 1
-- Oppassen als begin/eind in het weekend of zo valt,
-- dan moeten eerste/laatste dag gewoon 0 uur zijn.
IF iswerkdag (begindatum) = 0
THEN
eerstedag := 0;
END IF;
IF iswerkdag (einddatum) = 0
THEN
laatstedag := 0;
heledagen := fac.count_Work_Days (TRUNC (begindatum), TRUNC (einddatum));
ELSE
heledagen := fac.count_Work_Days (TRUNC (begindatum), TRUNC (einddatum)) - 1;
END IF;
END IF;
DBMS_OUTPUT.put_line ('Eerstedag ' || TO_CHAR (eerstedag));
DBMS_OUTPUT.put_line ('Laatstedag ' || TO_CHAR (laatstedag));
DBMS_OUTPUT.put_line ('Heledagen ' || TO_CHAR (heledagen));
IF uitvoertijdtype IN ('D', 'DAGEN')
THEN
-- Per 5.4.3 kunnen hier gebroken dagen worden teruggegeven!
uitvoertijd.tijdsduur := (eerstedag + laatstedag + heledagen * urenperdag) / urenperdag;
uitvoertijd.eenheid := 'D';
ELSE -- default/uitvoertijdtype IN ('U', 'UREN')
uitvoertijd.tijdsduur := eerstedag + laatstedag + heledagen * urenperdag;
uitvoertijd.eenheid := 'U';
END IF;
END IF;
END IF;
RETURN uitvoertijd;
END datumtijdnaaruitvoertijd;
FUNCTION getdatemillisec (i_date IN DATE)
RETURN NUMBER
IS
BEGIN
RETURN TO_NUMBER (TO_DATE (TO_CHAR ( (CAST (i_date AS TIMESTAMP WITH TIME ZONE)) AT TIME ZONE 'gmt', 'yyyy.mm.dd hh24:mi:ss'), 'yyyy.mm.dd hh24:mi:ss')
- TO_DATE ('01-01-1970', 'dd-mm-yyyy'))
* (24 * 60 * 60 * 1000);
END;
FUNCTION usrrap_query ( p_tabelnaam IN VARCHAR2 ) RETURN VARCHAR2 IS
QueryString VARCHAR2(4000);
Kolomnaam VARCHAR2(64);
mainuser VARCHAR2(80);
BEGIN
BEGIN
DECLARE
CURSOR Zoek_label IS
SELECT column_name
, data_type
FROM user_tab_columns
WHERE table_name = UPPER(p_tabelnaam)
ORDER BY COLUMN_ID;
BEGIN
QueryString := 'Select ';
FOR LabelRec in zoek_label LOOP
IF LabelRec.data_type = 'NUMBER'
THEN
QueryString := QueryString ||'to_number(TO_CHAR('|| LabelRec.column_name ||',''99999999D9999'')) "'||LabelRec.column_name||'",';
ELSE
QueryString := QueryString ||' ' || LabelRec.column_name ||',';
END IF;
END LOOP;
END;
END;
QueryString := Substr(QueryString,1,(LENGTH(QueryString)-1))||' from '|| p_tabelnaam ;
RETURN QueryString;
END usrrap_query;
FUNCTION usrrap_orderby ( p_tabelnaam IN VARCHAR2 ) RETURN VARCHAR2 IS
AantalRecords NUMBER(10);
OrderBy VARCHAR2(255);
mainuser VARCHAR2(80);
i NUMBER(10);
BEGIN
SELECT count(*)
INTO AantalRecords
FROM user_tab_columns
WHERE table_name = UPPER(p_tabelnaam);
--
OrderBy := '';
i := 1;
FOR i IN 1..AantalRecords LOOP
OrderBy := OrderBy||TO_CHAR(i)||',';
END LOOP;
OrderBy := SUBSTR(OrderBy,1,(LENGTH(OrderBy)-1));
RETURN ' ORDER BY ' || OrderBy;
END usrrap_orderby;
-- Re-tabelizes selected views (functie and 8) into tables
PROCEDURE tabelize_usrraps
IS
PRAGMA AUTONOMOUS_TRANSACTION;
CURSOR c1
IS
SELECT fac_usrrap_view_name
FROM fac_usrrap
WHERE BITAND (fac_usrrap_functie, 8) = 8;
dropddl VARCHAR2 (200);
createddl VARCHAR2 (200);
BEGIN
FOR rec1 IN c1
LOOP
dropddl := 'DROP TABLE T_' || SUBSTR (rec1.fac_usrrap_view_name, 1, 28)||' PURGE';
createddl :=
'CREATE TABLE T_'
|| SUBSTR (rec1.fac_usrrap_view_name, 1, 28)
|| ' AS SELECT * FROM '
|| rec1.fac_usrrap_view_name;
BEGIN
DBMS_OUTPUT.put_line (dropddl);
EXECUTE IMMEDIATE dropddl;
EXCEPTION
WHEN OTHERS
THEN
IF SQLCODE = -942
THEN
NULL;
ELSE
raise_application_error (-20001, 'Error trying to DROP: ' || SQLERRM);
END IF;
END;
DBMS_OUTPUT.put_line (createddl);
-- Dit moet om 1031 error te vermijden
--EXECUTE IMMEDIATE 'grant create table to '||user;
BEGIN
EXECUTE IMMEDIATE createddl;
EXCEPTION
WHEN OTHERS
THEN
IF SQLCODE = -1031 -- insufficient privileges
THEN
raise_application_error (
-20001,
'CREATE TABLE must be granted to this user: ' || USER);
ELSE
raise_application_error (-20001, 'Error trying to DROP: ' || SQLERRM);
END IF;
END;
END LOOP;
END;
PROCEDURE imp_getfield (
p_parseline IN OUT VARCHAR2,
p_fielddelimitor IN VARCHAR2,
p_field OUT VARCHAR2
)
AS
v_firstdelim NUMBER;
v_first_quote NUMBER;
v_next_quote NUMBER;
v_quote_count NUMBER;
v_found BOOLEAN;
BEGIN
v_firstdelim := INSTR (p_parseline, p_fielddelimitor, 1);
IF v_firstdelim = 0
THEN
-- no delimiter found, so this is the last field of the row
-- check if we start with a quote
IF INSTR (p_parseline, '"', 1) = 1
THEN
-- strip leading and trailing quote
-- we assume that the last character is a quote
p_field := substr2 (p_parseline, 2, LENGTH (p_parseline) - 2);
-- now we only have the unescape the double quotes
p_field := replace(p_field, '""', '"');
ELSE
p_field := substr2 (p_parseline, 1);
END IF;
p_parseline := '';
ELSE
-- we found a delimiter
p_field := SUBSTR (p_parseline, 1, v_firstdelim - 1);
v_first_quote := INSTR (p_field, '"', 1);
IF v_first_quote <> 1 OR p_field IS NULL
THEN
-- line does not start with a quote or field is empty
-- (two delimiters after each other)
p_parseline := substr2 (p_parseline, v_firstdelim + 1);
ELSE
-- double quote found. Search for the end double quote.
v_found := FALSE;
v_quote_count := 2;
WHILE v_found = FALSE
LOOP
-- look for the next double quote
v_next_quote := INSTR (p_parseline, '"', 1, v_quote_count);
IF v_next_quote = 0
THEN
-- no end quote found. So, it is the last field in the row
-- lets remove the leading quote
-- this should not happen since a quoted field should always have an end quote
p_field := substr2 (p_parseline, 2, LENGTH (p_parseline) - 1);
p_parseline := '';
v_found := TRUE;
ELSE
-- we have found a double quote, lets see what the next char is?
IF SUBSTR (p_parseline, v_next_quote + 1, 1) = '"'
THEN
-- two quotes found, so lets unescape the quote
v_quote_count := v_quote_count + 1;
p_parseline :=
SUBSTR (p_parseline, 1, v_next_quote)
|| SUBSTR (p_parseline, v_next_quote + 2);
ELSIF SUBSTR (p_parseline, v_next_quote + 1, 1) = p_fielddelimitor
THEN
-- quote + delimiter found
p_field := SUBSTR (p_parseline, 2, v_next_quote - 2);
p_parseline := SUBSTR (p_parseline, v_next_quote + 2);
v_found := TRUE;
ELSE
-- quote without delimiter found
-- this should never happen.
v_quote_count := v_quote_count + 1;
END IF;
END IF;
END LOOP;
END IF;
END IF;
END;
-- Retourneert het gegevens uit de kolom met volgnummer 'p_nr', beginnend met kolomnr 1.
-- 'Uiteraard' is deze functie gebaseerd op imp_getfield!
-- Verschil is dat p_parseline hier alleen IN-parameter is (en niet IN-OUT), en natuurlijk de extra parameter p_nr.
-- En de gelezen waarde wordt itt imp_getfield gewoon getrimd (weg met die overbodige spaties die alleen voor de rommel zorgen): VOD D'R MET!
PROCEDURE imp_getfield_nr (
p_parseline IN VARCHAR2,
p_fielddelimitor IN VARCHAR2,
p_nr IN NUMBER,
p_field OUT VARCHAR2
)
AS
l_parseline VARCHAR2(1024);
l_nr NUMBER(10);
l_field VARCHAR2(1024);
BEGIN
l_parseline :=p_parseline;
l_nr :=p_nr;
WHILE l_nr >= 1
LOOP
-- look for the next kolom in p_parseline
fac.imp_getfield (l_parseline, p_fielddelimitor, l_field);
l_nr := l_nr -1;
END LOOP;
-- Trimmen met die hap!
-- En nu pas het veld toekennen aan de parameter van de procedure
-- omdat de lengte korter kan zijn dan de lengte van de eerdere velden.
p_field:=TRIM(l_field);
END;
PROCEDURE imp_writelog (
p_import_key IN NUMBER,
plevel IN VARCHAR2,
pmsg IN VARCHAR2,
phint IN VARCHAR2
)
AS
BEGIN
INSERT INTO imp_log
(fac_import_key, imp_log_datum,
imp_log_status, imp_log_omschrijving, imp_log_hint
)
VALUES (p_import_key, SYSDATE,
plevel, pmsg, phint
);
END;
PROCEDURE writelog (
pAppl IN VARCHAR2,
plevel IN VARCHAR2,
pmsg IN VARCHAR2,
phint IN VARCHAR2
)
AS
BEGIN
INSERT INTO imp_log
(imp_log_applicatie, imp_log_datum,
imp_log_status, imp_log_omschrijving, imp_log_hint
)
VALUES (pAppl, SYSDATE,
plevel, pmsg, phint
);
END;
PROCEDURE imp_alg_delete_onrgoed (p_import_key IN NUMBER, p_mode IN NUMBER)
AS
v_errormsg VARCHAR2 (1000);
v_errorhint VARCHAR2 (1000);
oracle_err_num NUMBER;
oracle_err_mes VARCHAR2 (200);
BEGIN
DELETE FROM bez_bezoekers;
DELETE FROM bez_afspraak;
DELETE FROM res_rsv_deel;
DELETE FROM res_rsv_artikel;
DELETE FROM res_rsv_ruimte;
DELETE FROM res_reservering;
DELETE FROM res_kenmerkwaarde;
DELETE FROM res_alg_ruimte;
DELETE FROM res_ruimte_opstelling;
DELETE FROM res_ruimte;
DELETE FROM res_opstelling;
DELETE FROM res_activiteitdiscipline;
DELETE FROM res_disc_params;
DELETE FROM ins_tab_discipline
WHERE ins_discipline_module = 'RES' AND ins_discipline_min_level = '3';
DELETE FROM res_srtartikel_onrgoed;
DELETE FROM fin_factuur
WHERE mld_opdr_key IS NOT NULL;
DELETE FROM cnt_contract_plaats;
DELETE FROM cnt_contract_onrgoed;
DELETE FROM mld_kenmerkmelding;
DELETE FROM mld_melding_object;
DELETE FROM mld_opdr;
DELETE FROM mld_melding;
DELETE FROM mld_adres;
DELETE FROM prs_perslidwerkplek;
IF (p_mode < 2)
THEN
DELETE FROM prs_contactpersoon_locatie;
END IF;
DELETE FROM ins_verbinding;
DELETE FROM ins_deelkoppeling;
DELETE FROM ins_deel
WHERE ins_deel_parent_key IS NOT NULL;
DELETE FROM ins_deel
WHERE ins_alg_ruimte_type IS NOT NULL;
DELETE FROM alg_terreinsector;
DELETE FROM alg_srtterreinsector;
DELETE FROM alg_ruimte;
DELETE FROM alg_srtruimte;
DELETE FROM alg_verdieping;
IF (p_mode < 2)
THEN
DELETE FROM alg_onrgoedkenmerk;
DELETE FROM alg_gebouw;
DELETE FROM alg_srtgebouw;
DELETE FROM alg_locatie;
DELETE FROM alg_district;
DELETE FROM alg_regio;
ELSE
DELETE FROM alg_onrgoedkenmerk
WHERE alg_onrgoed_niveau IN ('R', 'T');
END IF;
EXCEPTION
WHEN OTHERS
THEN
oracle_err_num := SQLCODE;
oracle_err_mes := SUBSTR (SQLERRM, 1, 200);
IF (v_errormsg = '')
THEN
v_errormsg := 'Niet alle onroerendgoed gegevens zijn verwijderd!';
END IF;
v_errorhint :=
v_errorhint
|| ' (ORACLE error NUMBER = <'
|| oracle_err_num
|| '> ORACLE error message = <'
|| oracle_err_mes
|| '>)';
fac.imp_writelog (p_import_key, 'E', v_errormsg, v_errorhint);
COMMIT;
END;
PROCEDURE imp_prs_delete_organisatie (p_import_key IN NUMBER, p_mode IN NUMBER)
AS
v_errormsg VARCHAR2 (1000);
v_errorhint VARCHAR2 (1000);
oracle_err_num NUMBER;
oracle_err_mes VARCHAR2 (200);
v_bedrijf_key NUMBER(10);
v_srtperslid_key NUMBER(10);
v_afdeling_key NUMBER(10);
v_groep_key_def NUMBER(10);
v_groep_key_admin NUMBER(10);
v_perslid_key_gast NUMBER(10);
v_perslid_key_fac NUMBER(10);
v_functie_key_prssys NUMBER(10);
-- PRS_CONTACTPERSOON_LOCATIE
CURSOR c1
IS
SELECT prs_contactpersoon_locatie_key
FROM prs_contactpersoon_locatie;
rec1 c1%ROWTYPE;
-- PRS_CONTACTPERSOON
CURSOR c2
IS
SELECT prs_contactpersoon_key
FROM prs_contactpersoon;
rec2 c2%ROWTYPE;
-- PRS_BEDRIJFDIENSTLOCATIE
CURSOR c3
IS
SELECT prs_bedrijfdienstlocatie_key
FROM prs_bedrijfdienstlocatie;
rec3 c3%ROWTYPE;
-- PRS_PERSLIDWERKPLEK
CURSOR c4
IS
SELECT prs_perslidwerkplek_key
FROM prs_perslidwerkplek;
rec4 c4%ROWTYPE;
-- PRS_WERKPLEK
CURSOR c5
IS
SELECT prs_werkplek_key
FROM prs_werkplek;
rec5 c5%ROWTYPE;
-- PRS_PERSLID
CURSOR c6
IS
SELECT prs_perslid_key
FROM prs_perslid
WHERE prs_perslid_oslogin not in ('_GAST','_FACILITOR')
OR prs_perslid_oslogin IS NULL;
rec6 c6%ROWTYPE;
-- PRS_SRTPERSLID
CURSOR c7
IS
SELECT prs_srtperslid_key
FROM prs_srtperslid
where prs_srtperslid_upper <> 'ONBEKEND';
rec7 c7%ROWTYPE;
-- PRS_KOSTENPLAATS
CURSOR c8
IS
SELECT prs_kostenplaats_key
FROM prs_kostenplaats;
rec8 c8%ROWTYPE;
BEGIN
IF (p_mode <= 1)
THEN
FOR rec1 IN c1
LOOP
BEGIN
delete from prs_contactpersoon_locatie where prs_contactpersoon_locatie_key = rec1.prs_contactpersoon_locatie_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....';
END;
END LOOP;
commit;
FOR rec2 IN c2
LOOP
BEGIN
delete from prs_contactpersoon where prs_contactpersoon_key = rec2.prs_contactpersoon_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....';
END;
END LOOP;
commit;
FOR rec3 IN c3
LOOP
BEGIN
delete from prs_bedrijfdienstlocatie where prs_bedrijfdienstlocatie_key = rec3.prs_bedrijfdienstlocatie_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....';
END;
END LOOP;
commit;
END IF;
IF (p_mode <= 2)
THEN
FOR rec4 IN c4
LOOP
BEGIN
delete from prs_perslidwerkplek where prs_perslidwerkplek_key = rec4.prs_perslidwerkplek_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....'; -- agv prs_v_verplichting_all/fac_gebruikersgroep
END;
END LOOP;
commit;
FOR rec5 IN c5
LOOP
BEGIN
delete from prs_werkplek where prs_werkplek_key = rec5.prs_werkplek_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....'; --
END;
END LOOP;
commit;
FOR rec6 IN c6
LOOP
BEGIN
delete from prs_perslid where prs_perslid_key = rec6.prs_perslid_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....'; -- agv prs_v_verplichting_all/fac_gebruikersgroep/prs_perslidwerkplek
END;
END LOOP;
commit;
FOR rec7 IN c7
LOOP
BEGIN
delete from prs_srtperslid where prs_srtperslid_key = rec7.prs_srtperslid_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....'; -- agv prs_perslid
END;
END LOOP;
commit;
END IF;
IF (p_mode <= 1)
THEN
-- Verwijder ALLE afdelingen indien mogelijk. Doe dit wel in de 'juiste' volgorde.
DELETE FROM prs_afdeling
WHERE prs_afdeling_key IN (SELECT prs_afdeling_key
FROM prs_v_afdeling
WHERE niveau = 5) AND prs_afdeling_key NOT IN (SELECT prs_afdeling_key
FROM prs_perslid);
DELETE FROM prs_afdeling
WHERE prs_afdeling_key IN (SELECT prs_afdeling_key
FROM prs_v_afdeling
WHERE niveau = 4)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_key
FROM prs_perslid)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_parentkey
FROM prs_v_afdeling
WHERE niveau = 5);
DELETE FROM prs_afdeling
WHERE prs_afdeling_key IN (SELECT prs_afdeling_key
FROM prs_v_afdeling
WHERE niveau = 3)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_key
FROM prs_perslid)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_parentkey
FROM prs_v_afdeling
WHERE niveau = 4);
DELETE FROM prs_afdeling
WHERE prs_afdeling_key IN (SELECT prs_afdeling_key
FROM prs_v_afdeling
WHERE niveau = 2)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_key
FROM prs_perslid)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_parentkey
FROM prs_v_afdeling
WHERE niveau = 3);
DELETE FROM prs_afdeling
WHERE prs_afdeling_key IN (SELECT prs_afdeling_key
FROM prs_v_afdeling
WHERE niveau = 1)
AND prs_afdeling_upper <> 'ONBEKEND'
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_key
FROM prs_perslid)
AND prs_afdeling_key NOT IN (SELECT prs_afdeling_parentkey
FROM prs_v_afdeling
WHERE niveau = 2);
-- Verwijder ALLE bedrijven voor zover mogelijk
DELETE FROM prs_bedrijf
WHERE prs_bedrijf_key NOT IN (SELECT prs_bedrijf_key
FROM prs_afdeling)
AND prs_bedrijf_naam_upper <> 'ONBEKEND';
commit;
END IF;
-- Verwijder ALLE kostenplaatsen voor zover mogelijk
FOR rec8 IN c8
LOOP
BEGIN
delete from prs_kostenplaats where prs_kostenplaats_key = rec8.prs_kostenplaats_key;
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok, dan niet. Neem het volgende record ....';
END;
END LOOP;
COMMIT;
-- Maak initiele vulling aan
BEGIN
INSERT INTO prs_srtperslid (prs_srtperslid_omschrijving, prs_bedrijf_key)
VALUES ('Onbekend', NULL);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT prs_srtperslid_key
INTO v_srtperslid_key
FROM prs_srtperslid
WHERE prs_srtperslid_upper = 'ONBEKEND';
BEGIN
INSERT INTO prs_bedrijf (prs_bedrijf_naam, prs_bedrijf_intern)
VALUES ('Onbekend', 1);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT prs_bedrijf_key
INTO v_bedrijf_key
FROM prs_bedrijf
WHERE prs_bedrijf_naam_upper = 'ONBEKEND';
BEGIN
INSERT INTO prs_afdeling (prs_bedrijf_key, prs_afdeling_naam)
VALUES (v_bedrijf_key, 'Onbekend');
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT prs_afdeling_key
INTO v_afdeling_key
FROM prs_afdeling
WHERE prs_afdeling_upper = 'ONBEKEND';
BEGIN
INSERT INTO prs_perslid
(prs_perslid_module,
prs_srtperslid_key,
prs_afdeling_key,
prs_perslid_naam,
prs_perslid_oslogin,
prs_perslid_salt,
prs_perslid_wachtwoord_hash,
prs_perslid_dienstverband,
prs_perslid_ingangsdatum,
prs_perslid_login
)
VALUES ('PRS',
v_srtperslid_key,
v_afdeling_key,
'Gast',
'_GAST',
'tfYBQzSFECrhRcCgMhvVAgfgNtFaYZuh',
'6E52C06F3A8895E5BB79E36CC04502D7', /* nobodyknow$ */
100,
SYSDATE,
SYSDATE
);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT prs_perslid_key
INTO v_perslid_key_gast
FROM prs_perslid
WHERE prs_perslid_oslogin = '_GAST';
BEGIN
INSERT INTO prs_perslid
(prs_perslid_module,
prs_srtperslid_key,
prs_afdeling_key,
prs_perslid_naam,
prs_perslid_oslogin,
prs_perslid_salt,
prs_perslid_wachtwoord_hash,
prs_perslid_dienstverband,
prs_perslid_ingangsdatum,
prs_perslid_login
)
VALUES ('PRS',
v_srtperslid_key,
v_afdeling_key,
'Facilitor',
'_FACILITOR',
'wAxYpizzUNeWAFdkIkhcEbfzFAYvEpoH',
'9D8B5A6A8AED1496DF8C1CC54A9EBFF2', /* fictorial */
100,
SYSDATE,
SYSDATE
);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT prs_perslid_key
INTO v_perslid_key_fac
FROM prs_perslid
WHERE prs_perslid_oslogin = '_FACILITOR';
BEGIN
INSERT INTO fac_groep
(fac_groep_omschrijving)
VALUES ('_Default');
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT fac_groep_key
INTO v_groep_key_def
FROM fac_groep
WHERE fac_groep_upper = '_DEFAULT';
BEGIN
INSERT INTO fac_groep
(fac_groep_omschrijving)
VALUES ('_Admin');
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT fac_groep_key
INTO v_groep_key_admin
FROM fac_groep
WHERE fac_groep_upper = '_ADMIN';
BEGIN
INSERT INTO fac_gebruikersgroep
(fac_groep_key, prs_perslid_key)
VALUES (v_groep_key_def, v_perslid_key_gast);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
BEGIN
INSERT INTO fac_gebruikersgroep
(fac_groep_key, prs_perslid_key)
VALUES (v_groep_key_admin, v_perslid_key_fac);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
SELECT fac_functie_key
INTO v_functie_key_prssys
FROM fac_functie
WHERE fac_functie_code = 'WEB_PRSSYS';
BEGIN
INSERT INTO fac_groeprechten
(fac_groep_key,
fac_functie_key,
fac_gebruiker_prs_level_read,
fac_gebruiker_alg_level_read,
fac_gebruiker_prs_level_write,
fac_gebruiker_alg_level_write
)
VALUES (v_groep_key_admin, v_functie_key_prssys, -1, -1, -1, -1);
EXCEPTION
WHEN OTHERS THEN
v_errormsg := 'Ok. Kennelijk bestaat het record al';
END;
commit;
EXCEPTION
WHEN OTHERS
THEN
oracle_err_num := SQLCODE;
oracle_err_mes := SUBSTR (SQLERRM, 1, 200);
IF (v_errormsg = '')
THEN
v_errormsg := 'Niet alle bedrijven zijn verwijderd';
END IF;
v_errorhint :=
v_errorhint
|| ' (ORACLE error NUMBER = <'
|| oracle_err_num
|| '> ORACLE error message = <'
|| oracle_err_mes
|| '>)';
fac.imp_writelog (p_import_key, 'E', v_errormsg, v_errorhint);
COMMIT;
END;
PROCEDURE imp_mld_delete_mld (p_import_key IN NUMBER, p_mode IN NUMBER)
AS
v_errormsg VARCHAR2 (1000);
v_errorhint VARCHAR2 (1000);
oracle_err_num NUMBER;
oracle_err_mes VARCHAR2 (200);
BEGIN
delete from mld_opdr;
delete from mld_melding;
delete from mld_stdmelding;
delete from prs_kostensoort;
delete from mld_disc_params;
delete from ins_tab_discipline where ins_discipline_module='MLD';
delete from ins_srtdiscipline;
EXCEPTION
WHEN OTHERS
THEN
oracle_err_num := SQLCODE;
oracle_err_mes := SUBSTR (SQLERRM, 1, 200);
v_errormsg := 'Niet alle servicedesk gegevens zijn verwijderd!';
v_errorhint :=
v_errorhint
|| ' (ORACLE error NUMBER = <'
|| oracle_err_num
|| '> ORACLE error message = <'
|| oracle_err_mes
|| '>)';
fac.imp_writelog (p_import_key, 'E', v_errormsg, v_errorhint);
COMMIT;
END; -- imp_mld_delete_mld
PROCEDURE fac_perfmon_incr (limiet IN NUMBER, zwaarte IN NUMBER)
AS
dummy VARCHAR2 (1);
BEGIN
BEGIN
SELECT ''
INTO dummy
FROM fac_perfmon
WHERE fac_perfmon_datum = TRUNC (SYSDATE);
UPDATE fac_perfmon
SET fac_perfmon_waarde = fac_perfmon_waarde + zwaarte,
fac_perfmon_aantal = fac_perfmon_aantal + 1
WHERE fac_perfmon_datum = TRUNC (SYSDATE);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- a brandnew day. vul het aantal gebruikers van de vorige dag in en start een nieuwe
UPDATE fac_perfmon
SET fac_perfmon_users =
(SELECT COUNT (prs_perslid_key)
FROM prs_perslid
WHERE TRUNC (prs_perslid_login) = fac_perfmon_datum)
WHERE fac_perfmon_users IS NULL;
INSERT INTO fac_perfmon
(fac_perfmon_aantal, fac_perfmon_waarde,
fac_perfmon_datum, fac_perfmon_threshold
)
VALUES (1, zwaarte,
TRUNC (SYSDATE), limiet
);
END;
END;
-- Retourneert string met emailadres van persoon pkey, '' indien niet beschikbaar
FUNCTION getemail (pkey IN NUMBER)
RETURN VARCHAR2
IS
lemail prs_perslid.prs_perslid_email%TYPE;
BEGIN
lemail := '';
BEGIN
-- emailadres van ontvanger
SELECT prs_perslid_email
INTO lemail
FROM prs_perslid
WHERE prs_perslid_key = pkey;
EXCEPTION
WHEN OTHERS
THEN
NULL;
END;
RETURN lemail;
END;
-- Retourneert string met mobielnummer van persoon pkey, '' indien niet beschikbaar
FUNCTION getmobile (pkey IN NUMBER)
RETURN VARCHAR2
IS
lphone prs_perslid.prs_perslid_mobiel%TYPE;
BEGIN
lphone := '';
BEGIN
-- mobiele telefoon van ontvanger
SELECT prs_perslid_mobiel
INTO lphone
FROM prs_perslid
WHERE prs_perslid_key = pkey;
EXCEPTION
WHEN OTHERS
THEN
NULL;
END;
RETURN lphone;
END;
-- Retourneert de taal van een user
FUNCTION getlang (pkey IN NUMBER)
RETURN VARCHAR2
IS
llang prs_perslid.prs_perslid_lang%TYPE;
BEGIN
llang := '';
BEGIN
-- taal van persoon; te overwegen (gelijk gedrag) is om alleen
-- afwijking terug te geven, dus NULL als default ipv default
SELECT COALESCE(prs_perslid_lang, lcl.getuserlanguage())
INTO llang
FROM prs_perslid
WHERE prs_perslid_key = pkey;
EXCEPTION
WHEN OTHERS
THEN
NULL;
END;
RETURN llang;
END;
-- Zet een vrij bericht in de queue ter verspreiding volgens pmode. Dit is geen bestaande srtnotificatie
-- In plaats van pto (een intern prs_perslid) kan optioneel ook expliciete adressering worden meegegeven.
-- Bij een interne ontvanger wordt diens taal bijgezocht.
PROCEDURE putnotificationprio (pfrom NUMBER, pto NUMBER, pmessage VARCHAR2, pmode NUMBER,
poptemail VARCHAR2, poptmobile VARCHAR2, pprio NUMBER, pattach VARCHAR2 DEFAULT NULL)
AS
lemail prs_perslid.prs_perslid_email%TYPE;
lphone prs_perslid.prs_perslid_mobiel%TYPE;
llang prs_perslid.prs_perslid_lang%TYPE;
lsysteem prs_perslid.prs_perslid_systeemadres%TYPE;
lmode NUMBER;
BEGIN
lmode := pmode;
IF poptemail IS NULL
THEN
lemail := fac.getemail (pto);
ELSE
lemail := poptemail;
END IF;
IF poptmobile IS NULL
THEN
lphone := fac.getmobile (pto);
ELSE
lphone := poptmobile;
END IF;
IF pto IS NOT NULL
THEN
llang := fac.getlang(pto);
ELSE
llang := lcl.getuserlanguage();
END IF;
IF pto IS NOT NULL
THEN
BEGIN
SELECT prs_perslid_systeemadres
INTO lsysteem
FROM prs_perslid
WHERE prs_perslid_key = pto;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
END IF;
-- Stuur notificatie
IF BITAND(pmode, 2) = 2 AND lemail IS NULL
THEN
lmode := BITAND(lmode, 255-2);
END IF;
IF BITAND(pmode, 4) = 4 AND lphone IS NULL
THEN
lmode := BITAND(lmode, 255-4);
END IF;
IF lmode > 0 OR lsysteem IS NOT NULL THEN
INSERT INTO fac_notificatie
(fac_srtnotificatie_key, fac_notificatie_status, prs_perslid_key_sender, prs_perslid_key_receiver,
fac_notificatie_receiver_email, fac_notificatie_receiver_phone, fac_notificatie_oms,
fac_notificatie_refkey, fac_notificatie_prioriteit, fac_notificatie_lang, fac_notificatie_systeemadres,
fac_notificatie_attachments
)
VALUES (NULL, lmode, pfrom, pto,
lemail, lphone, SUBSTR(pmessage, 1, 2048),
NULL, pprio, llang, lsysteem,
pattach
);
END IF;
END;
/* for code compatibility only */
PROCEDURE putnotification (pfrom NUMBER, pto NUMBER, pmessage VARCHAR2, pmode NUMBER,
poptemail VARCHAR2, poptmobile VARCHAR2)
AS
BEGIN
putnotificationprio (pfrom, pto, pmessage, pmode, poptemail, poptmobile, 2);
END;
-- Zet een bericht in de queue ter verspreiding aan de applicatiebeheerders
PROCEDURE putsystemnotification (pmessage VARCHAR2, pmode NUMBER)
AS
CURSOR c1
IS
SELECT fgg.prs_perslid_key
FROM fac_functie f, fac_groeprechten fgr, fac_gebruikersgroep fgg
WHERE fgg.fac_groep_key = fgr.fac_groep_key
AND f.fac_functie_key = fgr.fac_functie_key
AND f.fac_functie_code = 'WEB_PRSSYS';
BEGIN
FOR rec1 IN c1
LOOP
putnotification (NULL, rec1.prs_perslid_key, pmessage, pmode, NULL, NULL);
END LOOP;
END;
-- Zet een bericht in de queue ter verspreiding volgens definitie van een bestaande srtnotificatie
-- Eventueel gebeurt er dus niets, als de srtnotificatie uitgeschakeld (mode=0) is.
-- Als het bericht wordt meegegeven in poptmessage dan wordt die tekst gebruikt ipv de standaardtekst van pcode
-- Evenzo wordt de standaardmode overruled door poptstatus als die meegegeven is, en
-- kan de email en mobile van pto optioneel worden overruled door poptemail en poptmobile
-- Als email of sms gevraagt wordt (smode) en email of mobile kan niet bepaald worden, wordt niet gequeued
-- pprio is de prioriteit (1, 2 of 3) die geen effect heeft op de quebehandeling, maar wel wordt meegegeven
-- psender is een optioneel emailadres dat als afzender kan worden gehanteerd.
-- pattach is a list of filenames (tbd)
PROCEDURE putnotificationsrtprio (pfrom NUMBER,
pto NUMBER,
pcode VARCHAR2,
pref NUMBER,
poptmessage VARCHAR2,
poptstatus NUMBER,
poptemail VARCHAR2,
poptmobile VARCHAR2,
pxref NUMBER,
pprio NUMBER,
psender VARCHAR2,
pattach VARCHAR2 DEFAULT NULL)
AS
soms fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
smode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
oldercode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
oldersoms fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
oldersmode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
susermode fac_srtnotificatie.fac_srtnotificatie_usermode%TYPE;
lmode fac_srtnotificatie.fac_srtnotificatie_mode%TYPE;
skey fac_srtnotificatie.fac_srtnotificatie_key%TYPE;
lemail fac_notificatie.fac_notificatie_receiver_email%TYPE;
lphone fac_notificatie.fac_notificatie_receiver_phone%TYPE;
llang prs_perslid.prs_perslid_lang%TYPE;
lsysteem prs_perslid.prs_perslid_systeemadres%TYPE;
BEGIN
IF pcode IS NOT NULL
THEN
BEGIN
IF poptstatus IS NULL
THEN
-- Geen status/mode meegegeven, bepaal em zelf
SELECT lcl.x('fac_srtnotificatie_oms', sn.fac_srtnotificatie_key, sn.fac_srtnotificatie_oms),
sn.fac_srtnotificatie_mode,
sn.fac_srtnotificatie_key,
fac_srtnotificatie_usermode
INTO soms,
smode,
skey,
susermode
FROM fac_srtnotificatie sn
WHERE sn.fac_srtnotificatie_code = pcode
AND sn.fac_srtnotificatie_mode > 0;
-- Als deze notificatiesoort userafhankelijk kan zijn, kijken we
-- naar de status/mode die bij de user is aangegeven
IF susermode = 1 AND pto IS NOT NULL
THEN
BEGIN
SELECT prs_perslid_srtnoti_mode
INTO smode
FROM prs_perslid
WHERE prs_perslid_key = pto
AND prs_perslid_srtnoti_mode IS NOT NULL;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- geen gebruikersoverrule, gebruik gewoon de centrale mode
NULL;
END;
END IF;
ELSE
-- Wel status meegegeven; die is dan vast
smode := poptstatus;
SELECT lcl.x('fac_srtnotificatie_oms', sn.fac_srtnotificatie_key, sn.fac_srtnotificatie_oms),
sn.fac_srtnotificatie_key
INTO soms, skey
FROM fac_srtnotificatie sn
WHERE sn.fac_srtnotificatie_code = pcode;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Nothing to do
RETURN;
END;
IF poptmessage IS NOT NULL
THEN
soms := poptmessage;
END IF;
soms := REPLACE (soms, '##KEY##', TO_CHAR (pref));
IF poptemail IS NULL
THEN
lemail := fac.getemail (pto);
ELSE
lemail := poptemail;
END IF;
IF poptmobile IS NULL
THEN
lphone := fac.getmobile (pto);
ELSE
lphone := poptmobile;
END IF;
IF pto IS NOT NULL
THEN
llang := fac.getlang(pto);
ELSE
llang := lcl.getuserlanguage();
END IF;
IF pto IS NOT NULL
THEN
BEGIN
SELECT prs_perslid_systeemadres
INTO lsysteem
FROM prs_perslid
WHERE prs_perslid_key = pto;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
END IF;
lmode := smode;
IF BITAND (smode, 2) = 2 AND lemail IS NULL
THEN
lmode := BITAND (lmode, 255 - 2);
END IF;
IF BITAND (smode, 4) = 4 AND lphone IS NULL
THEN
lmode := BITAND (lmode, 255 - 4);
END IF;
-- Als de omschrijving uit meerdere regels bestaat dan alleen de eerste regel notificeren.
-- Empirisch gebleken dat chr(10) wel wat doet, en chr(13) niet echt
-- hangt dat van iets af? Moeten we dan misschien allebei doen?
IF INSTR(soms, CHR(10)) > 0
THEN
soms := SUBSTR(soms, 1, INSTR (soms, CHR(10)) - 1);
END IF;
-- voorkom e-mail/sms van deze *UPD als de *NEW nog niet eens de deur uit is door Putorders
-- of meer algemeen: elke e-mail/sms die nog niet de deur is.
IF BITAND (smode, 2 + 4) <> 0
THEN
-- Zoek de lmode van een al/nog aanwezige fac_notificatie die over hetzelfde gaat
BEGIN
SELECT fac_srtnotificatie_code, fac_notificatie_status, fac_notificatie_oms
INTO oldercode, oldersmode, oldersoms
FROM fac_v_notifyqueue ander
WHERE (pcode = ander.fac_srtnotificatie_code
OR pcode = 'BESUPD'
AND ander.fac_srtnotificatie_code IN ('BESNEW')
OR pcode IN ('RESUPD','RESBEV','RESOPT','RESCLN')
AND ander.fac_srtnotificatie_code IN ('RESNEW')
OR pcode IN ('RESUPD') -- geen RESUPD als pending RESBEV of RESOPT
AND ander.fac_srtnotificatie_code IN ('RESBEV','RESOPT')
OR pcode = 'MLDUPD'
AND ander.fac_srtnotificatie_code IN ('MLDNEW')
)
AND ander.fac_notificatie_refkey = pref
AND COALESCE (ander.fac_notificatie_extrakey, -1) =
COALESCE (pxref, -1)
AND COALESCE (ander.fac_notificatie_receiver_email, '@') =
COALESCE (lemail, '@')
AND COALESCE (ander.fac_notificatie_receiver_phone, '@') =
COALESCE (lphone, '@')
AND BITAND (fac_notificatie_status, 2 + 4) <> 0
AND ROWNUM=1; -- anders te ingewikkeld
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
-- Identieke noti als reeds in de queue staat, dan zijn wij klaar; hoeft niet nog eens
-- en direct RETURN zodat bestaande noti niet ook nog eens wordt teruggetrokken (is in
-- dit geval, hoewel ouder, dus niet waardeloos)!
IF (pcode = oldercode AND smode = oldersmode AND soms = oldersoms)
THEN
-- Nothing to do
RETURN;
END IF;
IF BITAND (smode, 2) = 2 AND BITAND (oldersmode, 2) = 2
THEN
lmode := BITAND (lmode, 255 - 2);
END IF;
IF BITAND (smode, 4) = 4 AND BITAND (oldersmode, 4) = 4
THEN
lmode := BITAND (lmode, 255 - 4);
END IF;
-- Dan nog omgekeerd: trek eerdere zwakkere notificaties terug als deze pcode sterker is
-- als die oudere nog niet de deur uit is. NB: de tracking blijft natuurlijk gewoon
-- Ook portalberichten worden zo verminderd, en niet alleen die van de laatste 5 minuten
-- U zult bezwaar maken, maar mijn motivatie is dat notificatie een attentiewaarde heeft
-- en een oude attentie waardeloos is. Herhaalde update werden ook al onderdrukt.
-- De tracking tells it all! Gooi je zelf niks weg, dan resteert in de portal de NEW en de AFM, tof.
-- Wellicht dat deze lijst nog wat groeit.
CASE pcode
WHEN 'MLDAFM'
THEN
fac.clrnotifications('MLDUPD', pref);
fac.clrnotifications('MLD2BO', pref); -- De Backoffice hoeft al niet meer
WHEN 'RESAFM'
THEN
fac.clrnotifications('RESUPD', pref);
fac.clrnotifications('RESOPT', pref);
fac.clrnotifications('RESBEV', pref);
WHEN 'RESOPT'
THEN
fac.clrnotifications('RESUPD', pref);
WHEN 'RESBEV'
THEN
fac.clrnotifications('RESUPD', pref);
WHEN 'RESCLN'
THEN
fac.clrnotifications('RESUPD', pref);
WHEN 'BESAFM'
THEN
fac.clrnotifications('BESUPD', pref);
WHEN 'ORDAFM'
THEN
fac.clrnotifications('ORDUPD', pref);
ELSE
NULL;
END CASE;
-- Alle dubbele notificaties met dezelfde omschrijving voor dezelfde ontvanger verwijderen.
fac.clrnotifications(pcode, pref, soms, pto); -- Dubbele notificaties verwijderen indien dezelfde omschrijving en voor dezelfde ontvanger.
END IF;
END IF;
IF lmode > 0 OR lsysteem IS NOT NULL
THEN
-- Stuur notificatie.
INSERT INTO fac_notificatie (fac_srtnotificatie_key,
fac_notificatie_status,
prs_perslid_key_sender,
prs_perslid_key_receiver,
fac_notificatie_receiver_email,
fac_notificatie_receiver_phone,
fac_notificatie_oms,
fac_notificatie_refkey,
fac_notificatie_extrakey,
fac_notificatie_prioriteit,
fac_notificatie_sender_email,
fac_notificatie_lang,
fac_notificatie_systeemadres,
fac_notificatie_attachments)
VALUES (skey,
lmode,
pfrom,
pto,
lemail,
lphone,
soms,
pref,
pxref,
pprio,
psender,
llang,
lsysteem,
pattach);
END IF;
END;
-- Ruim zoveel mogelijk notificatiespul op voor dit item. Pcode mag een wildcard zijn!
PROCEDURE clrnotifications (pcode VARCHAR2, pref NUMBER)
AS
skey fac_srtnotificatie.fac_srtnotificatie_key%TYPE;
BEGIN
-- gequeuede berichten
DELETE FROM fac_notificatie
WHERE fac_srtnotificatie_key IN (SELECT sn.fac_srtnotificatie_key
FROM fac_srtnotificatie sn
WHERE sn.fac_srtnotificatie_code LIKE pcode)
AND fac_notificatie_refkey = pref;
-- portalberichten. Hier moet je wel de dubbele webuser_messages verwijderen. Hier gaat het om ander notificaties als dan die net aangemaakt zijn.
DELETE FROM web_user_messages
WHERE fac_srtnotificatie_key IN (SELECT sn.fac_srtnotificatie_key
FROM fac_srtnotificatie sn
WHERE sn.fac_srtnotificatie_code LIKE pcode)
AND web_user_mess_action_params = pref;
END;
-- Nu de functie met twee extra parameters, de omschrijving en de ontvanger van de notificatie.
PROCEDURE clrnotifications (pcode VARCHAR2, pref NUMBER, psubject VARCHAR2, preceiver NUMBER)
AS
skey fac_srtnotificatie.fac_srtnotificatie_key%TYPE;
BEGIN
-- gequeuede berichten
DELETE FROM fac_notificatie
WHERE fac_srtnotificatie_key IN (SELECT sn.fac_srtnotificatie_key
FROM fac_srtnotificatie sn
WHERE sn.fac_srtnotificatie_code LIKE pcode)
AND fac_notificatie_refkey = pref
AND fac_notificatie_oms = psubject
AND prs_perslid_key_receiver = preceiver;
-- portalberichten: fac_notificatie verwijderd de dubbelen wel in zijn insert trigger (nieuwste notificatie wordt hierna geinsert).
END;
-- Kijk welke jobs gescheduled zijn en nu uitgevoerd moeten worden.
PROCEDURE putnotificationjobs (pcust VARCHAR2)
AS
CURSOR c1
IS
SELECT fac_notificatie_job_key, fac_notificatie_job_view, fac_notificatie_job_oms,
fac_notificatie_job_interval, fac_notificatie_job_mode, fac_notificatie_job_nextrun,
fac_notificatie_job_flags
FROM fac_notificatie_job
WHERE fac_notificatie_job_nextrun <= SYSDATE OR fac_notificatie_job_nextrun IS NULL; -- eerste keer
tnextrun fac_notificatie_job.fac_notificatie_job_nextrun%TYPE;
BEGIN
FOR rec1 IN c1
LOOP
-- Voer de job uit
putjobnotifications (rec1.fac_notificatie_job_view, rec1.fac_notificatie_job_mode, rec1.fac_notificatie_job_flags);
-- Notificeer de uitvoering van de job aan de beheerder(s)? Regel dat zelf maar!
-- putsystemnotification ('Notificatiejob ' || rec1.fac_notificatie_job_oms || ' uitgevoerd.', 1);
-- Bepaal de volgende keer voor deze job, en garandeer dat dat altijd NA NU gaat gebeuren
-- dus zonder dat eventueel overgeslagen keren nog zullen worden ingehaald.
tnextrun := COALESCE (rec1.fac_notificatie_job_nextrun, SYSDATE);
WHILE tnextrun <= SYSDATE
LOOP
-- Interval in hrs, DATE arithmetics are in days, so we will have to divide by 24 hrs a day
UPDATE fac_notificatie_job
SET fac_notificatie_job_nextrun =
COALESCE (fac_notificatie_job_nextrun, SYSDATE)
+ rec1.fac_notificatie_job_interval / 24
WHERE fac_notificatie_job_key = rec1.fac_notificatie_job_key;
SELECT fac_notificatie_job_nextrun
INTO tnextrun
FROM fac_notificatie_job
WHERE fac_notificatie_job_key = rec1.fac_notificatie_job_key;
END LOOP;
END LOOP;
END;
-- Voer nu job pcode uit.
PROCEDURE putjobnotifications (pviewname VARCHAR2, pmode NUMBER, pflags NUMBER)
AS
TYPE noticursortype IS REF CURSOR;
messages noticursortype;
lsender fac_notificatie.prs_perslid_key_sender%TYPE;
lreceiver fac_notificatie.prs_perslid_key_receiver%TYPE;
ltext fac_notificatie.fac_notificatie_oms%TYPE;
lcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
lsrt_key fac_srtnotificatie.fac_srtnotificatie_key%TYPE;
lrefkey fac_notificatie.fac_notificatie_refkey%TYPE;
lxkey fac_notificatie.fac_notificatie_extrakey%TYPE;
lxemail fac_notificatie.fac_notificatie_receiver_email%TYPE;
lxmobile fac_notificatie.fac_notificatie_receiver_phone%TYPE;
attachments fac_notificatie.fac_notificatie_attachments%TYPE;
BEGIN
-- The flags are for compatibility mostly. Flags 2 and 4 cannot be combined (useless)
-- flags: 0=default, 1=view has xemail and xmobile, 2=use fac.notifytracking instead of fac.putnotification(srtprio)
-- 4=view has attachments
-- Kijk of de extra kolommen xemail en xmobile in de view zitten, dan gebruiken we die ook
IF BITAND(pflags, 2) = 2 -- Alleen sender, text, code en xkey verplicht (met xkey zoals in fac_tracking zou komen)
THEN
OPEN messages FOR
'SELECT sender, NULL receiver, text, code, fac_srtnotificatie_key, NULL key, xkey, NULL xemail, NULL xmobile'
|| ' FROM fac_srtnotificatie, ' || pviewname
|| ' WHERE code = fac_srtnotificatie_code';
ELSIF BITAND(pflags, 5) = 5 /* 4+1 */
THEN
OPEN messages FOR
'SELECT sender, receiver, text, code, NULL fac_srtnotificatie_key, key, xkey, xemail, xmobile, attachments FROM '
|| pviewname;
ELSIF BITAND(pflags, 4) = 4
THEN
OPEN messages FOR
'SELECT sender, receiver, text, code, NULL fac_srtnotificatie_key, key, xkey, NULL xemail, NULL xmobile, attachments FROM '
|| pviewname;
ELSIF BITAND(pflags, 1) = 1
THEN
OPEN messages FOR
'SELECT sender, receiver, text, code, NULL fac_srtnotificatie_key, key, xkey, xemail, xmobile, NULL attachments FROM '
|| pviewname;
ELSE -- BITAND(pflags, 1) = 0
OPEN messages FOR
'SELECT sender, receiver, text, code, NULL fac_srtnotificatie_key, key, xkey, NULL xemail, NULL xmobile, NULL attachments FROM '
|| pviewname;
END IF;
LOOP
FETCH messages
INTO lsender, lreceiver, ltext, lcode, lsrt_key, lrefkey, lxkey, lxemail, lxmobile, attachments;
EXIT WHEN messages%NOTFOUND;
IF BITAND(pflags, 2) = 2
THEN
notifytracking(lsrt_key,
lsender,
ltext,
lxkey);
ELSIF lcode IS NULL
THEN
putnotificationprio (lsender,
lreceiver,
ltext,
pmode,
lxemail,
lxmobile,
2,
attachments);
ELSE
putnotificationsrtprio (lsender,
lreceiver,
lcode,
lrefkey,
ltext,
pmode,
lxemail,
lxmobile,
lxkey,
2,
NULL,
attachments);
END IF;
END LOOP;
CLOSE messages;
EXCEPTION
WHEN OTHERS
THEN
raise_application_error (-20000,
'FACILITOR: invalid notification job/view ' || pviewname);
END;
PROCEDURE executeactiviteit (pxmlnode VARCHAR2, pactkey NUMBER)
AS
lkey NUMBER (10);
lkey_m NUMBER (10);
lkey_new NUMBER (10);
luserkey NUMBER (10);
lvolgnr mld_opdr.mld_opdr_bedrijfopdr_volgnr%TYPE;
leinddatum mld_melding.mld_melding_einddatum_std%TYPE;
BEGIN
BEGIN
CASE pxmlnode
WHEN 'melding'
THEN
SELECT MAX (mld_melding_key)
INTO lkey
FROM mld_melding
WHERE fac_activiteit_key = pactkey;
SELECT mld_s_mld_melding_key.nextval
INTO lkey_new
FROM DUAL;
-- TODO: ooit uitvoertijd en accepttijd vers bepalen uit de stdmelding
-- TODO: ooit i18n voor de vaste string
INSERT INTO mld_melding
(mld_melding_key, mld_melding_module, mld_meldbron_key, mld_alg_locatie_key,
mld_alg_onroerendgoed_keys, mld_melding_datum, mld_melding_omschrijving,
mld_melding_opmerking, mld_stdmelding_key, mld_melding_t_uitvoertijd, mld_melding_t_accepttijd,
mld_kosten_klant, mld_melding_document, prs_kostenplaats_key,
prs_perslid_key, mld_adres_key,
mld_workflowstep_key, mld_melding_start_key, mld_melding_ordernr, mld_melding_spoed)
SELECT lkey_new, mld_melding_module, mld_meldbron_key, mld_alg_locatie_key,
mld_alg_onroerendgoed_keys, SYSDATE, mld_melding_omschrijving,
lcl.l('lcl_mld_activity_generated_by')|| pactkey || '. ' || mld_melding_opmerking,
mld_stdmelding_key, mld_melding_t_uitvoertijd, mld_melding_t_accepttijd,
mld_kosten_klant, mld_melding_document, prs_kostenplaats_key, prs_perslid_key,
mld_adres_key, NULL, NULL,
mld_melding_ordernr, mld_melding_spoed
FROM mld_melding
WHERE mld_melding_key = lkey;
INSERT INTO mld_kenmerkmelding
(mld_melding_key, mld_kenmerk_key, mld_kenmerkmelding_waarde)
SELECT lkey_new, mld_kenmerk_key, mld_kenmerkmelding_waarde
FROM mld_kenmerkmelding
WHERE mld_kenmerkmelding_verwijder IS NULL AND mld_melding_key = lkey;
INSERT INTO mld_melding_object
(mld_melding_key, ins_deel_key)
SELECT lkey_new, ins_deel_key
FROM mld_melding_object
WHERE mld_melding_object_verwijder IS NULL AND mld_melding_key = lkey;
mld.setmeldingstatus(lkey_new, 2,NULL);
-- Eventuele (gewijzigde) objecten zijn nu ook opgeslagen.
-- Nu kunnen pas de definitieve mld_melding.mld_melding_einddatum en mld_melding.mld_melding_einddatum_std bepaald en gezet worden.
leinddatum := mld.geteinddatum (lkey_new);
UPDATE mld_melding
SET mld_melding_einddatum = leinddatum,
mld_melding_einddatum_std = leinddatum
WHERE mld_melding_key = lkey_new;
WHEN 'opdracht'
THEN
SELECT MAX (mld_opdr_key),
MAX (mld_melding_key)
INTO lkey,
lkey_m
FROM mld_opdr
WHERE fac_activiteit_key = pactkey;
SELECT mld.bepaalopdrmeldingvolgnr (lkey_m)
INTO lvolgnr
FROM DUAL;
SELECT mld_s_mld_opdr_key.nextval
INTO lkey_new
FROM DUAL;
INSERT INTO mld_opdr
(mld_opdr_key, mld_opdr_module, mld_melding_key, mld_uitvoerende_keys, mld_typeopdr_key,
mld_statusopdr_key, mld_standaardopdr_key, mld_opdr_omschrijving, mld_opdr_datumbegin,
mld_opdr_einddatum, mld_opdr_werkzaamheden, mld_opdr_uren, mld_opdr_materiaal, mld_opdr_kosten,
mld_opdr_contactpersoon, mld_opdr_bedrijfopdr_volgnr, mld_opdr_uurloon, prs_perslid_key,
prs_contactpersoon_key, cnt_contract_key, cnt_contract_dienst_key, prs_kostenplaats_key,
mld_opdr_ordernr, mld_opdr_teverzenden)
SELECT lkey_new, mld_opdr_module, mld_melding_key, mld_uitvoerende_keys, mld_typeopdr_key, mld_statusopdr_key,
mld_standaardopdr_key, mld_opdr_omschrijving, SYSDATE, mld_opdr_einddatum,
'Automatisch gegenereerd door activiteit ' || pactkey || '. ' || mld_opdr_werkzaamheden,
mld_opdr_uren, mld_opdr_materiaal, mld_opdr_kosten, mld_opdr_contactpersoon, lvolgnr,
mld_opdr_uurloon, prs_perslid_key, prs_contactpersoon_key, cnt_contract_key,
cnt_contract_dienst_key, prs_kostenplaats_key, mld_opdr_ordernr, mld_opdr_teverzenden
FROM mld_opdr
WHERE mld_opdr_key = lkey;
INSERT INTO mld_kenmerkopdr
(mld_opdr_key, mld_kenmerk_key, mld_kenmerkopdr_waarde)
SELECT lkey_new, mld_kenmerk_key, mld_kenmerkopdr_waarde
FROM mld_kenmerkopdr
WHERE mld_kenmerkopdr_verwijder IS NULL AND mld_opdr_key = lkey;
mld.setopdrachtstatus(lkey_new, 2,NULL);
WHEN 'bestelling'
THEN
SELECT MAX (bes_bestelling_key),
MAX (prs_perslid_key)
INTO lkey,
luserkey
FROM bes_bestelling
WHERE fac_activiteit_key = pactkey;
SELECT bes_s_bes_bestelling_key.nextval
INTO lkey_new
FROM DUAL;
-- Bestelling kopi<70>ren.
INSERT INTO bes_bestelling (
bes_bestelling_key,
bes_bestelling_module,
bes_bestelling_status,
bes_bestelling_datum,
prs_perslid_key,
prs_perslid_key_voor,
bes_bestelling_opmerking,
bes_bestelling_ordernr,
bes_bestelling_plaats,
mld_adres_key_lev,
prs_kostenplaats_key,
bes_bestelling_leverdatum,
bes_bestelling_kosten_klant
)
SELECT lkey_new,
bes_bestelling_module,
bes_bestelling_status,
SYSDATE,
prs_perslid_key,
prs_perslid_key_voor,
'Automatisch gegenereerd door activiteit ' || pactkey || '. ' || bes_bestelling_opmerking,
bes_bestelling_ordernr,
bes_bestelling_plaats,
mld_adres_key_lev,
prs_kostenplaats_key,
TRUNC (SYSDATE + (bes_bestelling_leverdatum - bes_bestelling_datum)),
bes_bestelling_kosten_klant
FROM bes_bestelling
WHERE bes_bestelling_key = lkey;
-- Kenmerken van bestelling kopi<70>ren.
INSERT INTO bes_kenmerkbestell
(bes_bestelling_key, bes_kenmerk_key, bes_kenmerkbestell_waarde)
SELECT lkey_new, bes_kenmerk_key, bes_kenmerkbestell_waarde
FROM bes_kenmerkbestell
WHERE bes_kenmerkbestell_verwijder IS NULL AND bes_bestelling_key = lkey;
-- Bestelregels kopi<70>ren.
INSERT INTO bes_bestelling_item (bes_bestelling_key,
bes_bestelling_item_aantal,
bes_bestelling_item_aantalontv,
bes_bestelling_item_brutoprijs,
bes_bestelling_item_prijs,
bes_srtdeel_key)
SELECT lkey_new,
bes_bestelling_item_aantal,
bes_bestelling_item_aantalontv,
bes.getsrtdeelprijsinfo(bi.bes_srtdeel_key, SYSDATE, 1),
bes.getsrtdeelprijsinfo(bi.bes_srtdeel_key, SYSDATE, 1),
bi.bes_srtdeel_key
FROM bes_bestelling_item bi, bes_srtdeel isd
WHERE bes_bestelling_key = lkey
AND isd.bes_srtdeel_key = bi.bes_srtdeel_key;
-- Kenmerken van bestelregels kopi<70>ren.
INSERT INTO bes_kenmerkbesteli (bes_bestelling_item_key,
bes_kenmerk_key,
bes_kenmerkbesteli_waarde,
bes_kenmerkbesteli_aanmaak)
SELECT tab1.bes_bestelling_item_key_new,
kbi.bes_kenmerk_key,
kbi.bes_kenmerkbesteli_waarde,
SYSDATE
FROM bes_kenmerkbesteli kbi,
(SELECT bi1.bes_bestelling_item_key bes_bestelling_item_key_new,
bi.bes_bestelling_item_key,
bi.bes_srtdeel_key
FROM bes_bestelling_item bi, bes_bestelling_item bi1
WHERE bi.bes_bestelling_key = lkey
AND bi1.bes_srtdeel_key = bi.bes_srtdeel_key
AND bi1.bes_bestelling_key = lkey_new) tab1
WHERE kbi.bes_bestelling_item_key = tab1.bes_bestelling_item_key
AND kbi.bes_bestelling_item_key IN (SELECT bes_bestelling_item_key
FROM bes_bestelling_item bi
WHERE bi.bes_bestelling_key = lkey);
-- Het gaat hier om een geplande actie. Je mag er van uit gaan dat deze goed gekeurd is voordat deze is aangemaakt.
-- Daarom bestellingstatus op 4 zetten (Geaccepteerd) en bestelopdracht automatisch aanmaken.
bes.setbestellingstatus(lkey_new, 4, luserkey); -- Geaccepteerd
bes.makeorders(luserkey, lkey_new); -- bes_makeorders notificeert zelf de leveranciers.
END CASE;
EXCEPTION
WHEN OTHERS
THEN
putsystemnotification ( 'Facilitor scheduler: opdracht voor activiteit '
|| pactkey
|| ' kan niet worden aangemaakt: '
|| SQLERRM,
3
);
END;
END;
PROCEDURE executeschedules
AS
newaantal NUMBER;
-- Interval in hrs, DATE arithmetics are in days, so we will have to divide interval by 24 hrs a day
CURSOR c1
IS
SELECT fac_activiteit_key, fac_activiteit_xmlnode, fac_activiteit_status_key, fac_activiteit_interval,
fac_activiteit_aantal
FROM fac_activiteit
WHERE ((fac_activiteit_volgende <= SYSDATE AND fac_activiteit_einddatum IS NULL)
OR (fac_activiteit_volgende <= SYSDATE AND SYSDATE < fac_activiteit_einddatum)
OR (fac_activiteit_volgende IS NULL AND SYSDATE BETWEEN fac_activiteit_eerste AND fac_activiteit_einddatum)
OR (fac_activiteit_volgende IS NULL AND fac_activiteit_einddatum IS NULL AND SYSDATE > fac_activiteit_eerste)
)
AND fac_activiteit_status_key IN (2, 3)
AND fac_activiteit_xmlnode IS NOT NULL
AND NVL (fac_activiteit_aantal, 1) > 0
AND fac_activiteit_verwijder IS NULL;
BEGIN
FOR rec1 IN c1
LOOP
-- Voer de job uit
newaantal := NULL;
IF rec1.fac_activiteit_aantal IS NOT NULL
THEN
newaantal := rec1.fac_activiteit_aantal - 1;
END IF;
IF rec1.fac_activiteit_status_key = 2
THEN
executeactiviteit (rec1.fac_activiteit_xmlnode, rec1.fac_activiteit_key);
-- Remove time-part from volgende (ie. set to 0:00)!
UPDATE fac_activiteit
SET fac_activiteit_volgende = TRUNC(COALESCE (fac_activiteit_volgende, fac_activiteit_eerste) + fac_activiteit_interval / 24),
fac_activiteit_laatste = SYSDATE,
fac_activiteit_aantal = newaantal
WHERE fac_activiteit_key = rec1.fac_activiteit_key;
ELSE
-- 1 keer overslaan, de volgende keer weer wel dus. Ook hier: remove time-part from volgende (ie. set to 0:00)!
UPDATE fac_activiteit
SET fac_activiteit_volgende = TRUNC(COALESCE (fac_activiteit_volgende, fac_activiteit_eerste) + fac_activiteit_interval / 24),
fac_activiteit_status_key = 2,
fac_activiteit_aantal = newaantal
WHERE fac_activiteit_key = rec1.fac_activiteit_key;
END IF;
END LOOP;
END;
-- MarkOrderAsSent
-- Markeert dat een opdracht verzonden is, zoals door PutOrders.exe
-- Hoe dat moet is afhankelijk van het soort opdracht: bestelopdracht, meldingsopdracht e.d.
-- pxmlnode is (lowercase!) de xml-naam van de entiteit (opdracht, bestelopdr)
-- pkey is de key daarvan
-- presult geeft het succes van de verzending aan: 0=succesvol, 1=geweigerd, 2=geeninhoudelijkrespons
-- wat gebruikt *kan* worden bij het bepalen van de status die gezet moet worden.
-- Schijnbaar is ook presult<0 nog mogelijk als er technisch wat mis ging. Die tracken we ook maar eens gewoon?
-- presulttext bevat (optioneel) de feedback van de leverancier (bijv. reden van afwijzing bestelopdracht)
-- Voor customer-orderqueues dient overeenkomstige CUST.markorderassent() te worden gedefinieerd.
-- Bij presult=2 weet je niet zeker wat de leverancier heeft gedaan, bij mail veronderstel je ontvangst, maar weet je
-- het niet zeker. Met 5.1.2 (UWVA#21074) is daarvoor de status 4 tussengevoegd
PROCEDURE markorderassent (pxmlnode VARCHAR2, pkey NUMBER, presult NUMBER, presulttext VARCHAR2)
AS
order_confirm prs_bedrijf.prs_bedrijf_order_confirm%TYPE;
melding_key mld_opdr.mld_melding_key%TYPE;
refiatstatus mld_opdr.mld_statusopdr_key_refiat%TYPE;
BEGIN
CASE pxmlnode
WHEN 'opdracht'
THEN
SELECT mld_statusopdr_key_refiat
INTO refiatstatus
FROM mld_opdr
WHERE mld_opdr_key = pkey;
IF presult = 0
THEN
UPDATE mld_opdr
SET mld_opdr_verzonden = SYSDATE
WHERE mld_opdr_key = pkey;
fac.trackaction ('ORDSNT', pkey, NULL, NULL, presulttext);
IF refiatstatus > 0
THEN
mld.setopdrachtstatus (pkey, refiatstatus, NULL);
-- Refiat opdracht kosten en refiat status weer op NULL zetten.
UPDATE mld_opdr
SET mld_opdr_uren_refiat = NULL,
mld_opdr_uurloon_refiat = NULL,
mld_opdr_materiaal_refiat = NULL,
mld_opdr_kosten_refiat = NULL,
mld_statusopdr_key_refiat = NULL,
mld_opdr_approved_refiat = NULL
WHERE mld_opdr_key = pkey;
ELSE
mld.setopdrachtstatus (pkey, 5, NULL);
END IF;
ELSIF presult = 1 -- (Logische) fout
THEN
UPDATE mld_opdr
SET mld_opdr_verzonden = SYSDATE
WHERE mld_opdr_key = pkey;
fac.trackaction ('ORDSNT', pkey, NULL, NULL, presulttext);
-- status van de opdracht wordt afgewezen.
IF refiatstatus > 0
THEN
-- Afwijzing tracken. Dit gebeurt niet automatisch omdat niet naar de afgewezen status wordt gegaan.
fac.trackaction('ORDCAN', pkey, NULL, NULL, presulttext);
mld.setopdrachtstatus (pkey, refiatstatus, NULL);
-- De oude kosten terugzetten.
-- Refiat opdracht kosten en refiat status weer op NULL zetten.
UPDATE mld_opdr
SET mld_opdr_uren = mld_opdr_uren_refiat,
mld_opdr_uurloon = mld_opdr_uurloon_refiat,
mld_opdr_materiaal = mld_opdr_materiaal_refiat,
mld_opdr_kosten = mld_opdr_kosten_refiat,
mld_opdr_approved = mld_opdr_approved_refiat,
mld_opdr_uren_refiat = NULL,
mld_opdr_uurloon_refiat = NULL,
mld_opdr_materiaal_refiat = NULL,
mld_opdr_kosten_refiat = NULL,
mld_statusopdr_key_refiat = NULL,
mld_opdr_approved_refiat = NULL
WHERE mld_opdr_key = pkey;
ELSE
mld.setopdrachtstatus (pkey, 1, NULL);
END IF;
ELSIF presult = 2
THEN
fac.trackaction ('ORDSNT', pkey, NULL, NULL, presulttext);
-- De leverancier heeft geen feedback gegeven, wat is het gedrag dan voor deze leverancier?
SELECT b.prs_bedrijf_order_confirm
INTO order_confirm
FROM prs_bedrijf b, mld_opdr o
WHERE b.prs_bedrijf_key = o.mld_uitvoerende_keys
AND o.mld_opdr_key = pkey;
-- NOTA BENE
-- Zo is deze nog prima compatible. Status 8 is in het huidige gebruik nog niet identiek, dus
-- daar wachten we nog even mee op een diepgaander design, vandaar if true.
IF TRUE OR order_confirm = 1
THEN
-- Er volgt later nog een expliciete bevestiging (5=Ter Bevestiging)
UPDATE mld_opdr
SET mld_opdr_verzonden = SYSDATE
WHERE mld_opdr_key = pkey;
IF refiatstatus > 0
THEN
mld.setopdrachtstatus (pkey, refiatstatus, NULL);
ELSE
mld.setopdrachtstatus (pkey, 5, NULL);
END IF;
ELSE
UPDATE mld_opdr
SET mld_opdr_verzonden = SYSDATE
WHERE mld_opdr_key = pkey;
IF refiatstatus > 0
THEN
mld.setopdrachtstatus (pkey, refiatstatus, NULL);
ELSE
mld.setopdrachtstatus (pkey, 8, NULL);
END IF;
END IF;
-- Refiat opdracht kosten en refiat status weer op NULL zetten.
IF refiatstatus > 0 AND (presult >= 0)
THEN
UPDATE mld_opdr
SET mld_opdr_uren_refiat = NULL,
mld_opdr_uurloon_refiat = NULL,
mld_opdr_materiaal_refiat = NULL,
mld_opdr_kosten_refiat = NULL,
mld_statusopdr_key_refiat = NULL,
mld_opdr_approved_refiat = NULL
WHERE mld_opdr_key = pkey;
END IF;
ELSIF presult < 0
THEN
-- just track, nothing changes really
fac.trackaction ('ORDSNX', pkey, NULL, NULL, presulttext);
END IF;
SELECT mld_melding_key
INTO melding_key
FROM mld_opdr o
WHERE o.mld_opdr_key = pkey;
-- als laatste de status van de melding aanpassen.
mld.updatemeldingstatus (melding_key, 0, NULL);
WHEN 'bestelopdr'
THEN
IF presult = 0
THEN
-- Succesvol
fac.trackaction ('BES2SN', pkey, NULL, NULL, presulttext);
bes.acceptopdracht(pkey, NULL, presulttext);
ELSIF presult = 1 -- (Logische) fout
THEN
fac.trackaction ('BES2SX', pkey, NULL, NULL, presulttext);
bes.rejectopdracht(pkey, NULL, presulttext);
ELSIF presult = 2
THEN
-- De leverancier heeft geen feedback gegeven, wat is het gedrag dan voor deze leverancier?
SELECT b.prs_bedrijf_order_confirm
INTO order_confirm
FROM prs_bedrijf b, bes_bestelopdr o
WHERE b.prs_bedrijf_key = o.prs_bedrijf_key
AND o.bes_bestelopdr_key = pkey;
fac.trackaction ('BES2SN', pkey, NULL, NULL, presulttext);
IF order_confirm = 1
THEN
-- Er volgt later nog een expliciete bevestiging (5=Ter Bevestiging)
UPDATE bes_bestelopdr
SET bes_bestelopdr_status = 5
WHERE bes_bestelopdr_key = pkey;
fac.trackaction ('BES2BE', pkey, NULL, NULL, presulttext);
ELSE
bes.acceptopdracht(pkey, NULL, presulttext);
END IF;
ELSIF presult < 0
THEN
-- just track, nothing changes really
fac.trackaction ('BES2SX', pkey, NULL, NULL, presulttext);
END IF;
WHEN 'contract'
THEN
IF presult = 1
THEN -- (Logische) fout; kan nog niet voorkomen voorlopig, maar toch
fac.trackaction ('CNTSNX', pkey, NULL, NULL, presulttext);
ELSE
-- Succesvol
fac.trackaction ('CNTSNT', pkey, NULL, NULL, presulttext);
END IF;
-- reset
UPDATE cnt_contract
SET cnt_contract_teverzenden = NULL
WHERE cnt_contract_key = pkey;
END CASE;
END;
-- Returnt de geldende waarde voor setting pname, bepaald uit de settingstabel
FUNCTION getSetting (pname IN VARCHAR2 ) RETURN VARCHAR2
AS
lres fac_setting.fac_setting_default%TYPE;
BEGIN
SELECT COALESCE(fac_setting_pvalue, fac_setting_default)
INTO lres
FROM fac_setting
WHERE fac_setting_name = pname;
RETURN lres;
END;
-- add a trackrecord for action pcode, entity prefkey. pdatum may be NULL
-- Doet niets als er een onbekende pcode wordt meegegeven
-- We willen (blijkt) toch ook kunnen regelen dat een tracking per se NIET wordt genotificeerd
-- Dat doen we door pcode te prefixen met #. Deze wordt dan stiekem voor aan poms geplakt
-- (want anders kunnen we niet inserten) en de trigger op fac_tracking doet dan de rest.
PROCEDURE trackaction (pcode VARCHAR2, prefkey NUMBER, puserkey NUMBER, pdatum DATE, poms VARCHAR2)
AS
tkey fac_srtnotificatie.fac_srtnotificatie_key%TYPE;
loms fac_tracking.fac_tracking_oms%TYPE;
lcode VARCHAR2(10); -- tabelsize is 6
BEGIN
IF pcode IS NULL
THEN
RETURN;
END IF;
IF prefkey IS NULL
THEN
RETURN;
END IF;
lcode := pcode;
loms := poms;
IF SUBSTR(lcode,1,1) = '#'
THEN
lcode := SUBSTR(lcode, 2);
IF poms IS NULL
THEN
loms := '#';
ELSE
loms := '#' || loms;
END IF;
END IF;
SELECT fac_srtnotificatie_key
INTO tkey
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = lcode;
IF pdatum IS NULL
THEN
INSERT INTO fac_tracking (fac_tracking_refkey, prs_perslid_key, fac_srtnotificatie_key, fac_tracking_oms
)
VALUES (prefkey, puserkey, tkey, loms
);
ELSE
INSERT INTO fac_tracking (fac_tracking_refkey, prs_perslid_key, fac_srtnotificatie_key, fac_tracking_datum, fac_tracking_oms
)
VALUES (prefkey, puserkey, tkey, pdatum, loms
);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
-- Pas de datum van een tracking record aan
-- Userkey wordt nog genegeerd
PROCEDURE backtrackaction (pcode VARCHAR2,
prefkey NUMBER,
puserkey NUMBER,
pdatum DATE)
AS
tkey fac_srtnotificatie.fac_srtnotificatie_key%TYPE;
BEGIN
SELECT fac_srtnotificatie_key
INTO tkey
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = pcode;
UPDATE fac_tracking
SET fac_tracking_datum = pdatum
WHERE fac_tracking_refkey = prefkey AND fac_srtnotificatie_key = tkey
AND fac_tracking_key =
(SELECT MAX (fac_tracking_key)
FROM fac_tracking T
WHERE t.fac_srtnotificatie_key = tkey
AND fac_tracking_refkey = prefkey);
END;
-- create a notification using only trackrecord parameters
-- Indeed, we could do this using only the fac_tracking_key, but we do not
-- if no ptracking_oms is given, we construct one!
-- Binnen deze procedure weten we nog net wat we doen
-- (nl. notificeren van een trackrecord van een bekende entiteit)
-- Een stap verder niet meer, dan is het gewoon een bericht met
-- een zender en ontvanger.
PROCEDURE notifytracking (psrtnotificatiekey NUMBER,
pperslid_key NUMBER,
ptracking_oms VARCHAR2,
prefkey NUMBER)
AS
lxmlnode fac_srtnotificatie.fac_srtnotificatie_xmlnode%TYPE;
lcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
lcode2 fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
loms fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
loms2 fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
bericht fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
bericht2 fac_srtnotificatie.fac_srtnotificatie_oms%TYPE;
lreceiver fac_notificatie.prs_perslid_key_receiver%TYPE;
lreceiver2 fac_notificatie.prs_perslid_key_receiver%TYPE;
lsender VARCHAR2 (255 CHAR);
lmld_stdmelding_key mld_stdmelding.mld_stdmelding_key%TYPE;
lnotify mld_disc_params.mld_disc_params_notify%TYPE;
lmnotify mld_stdmelding.mld_stdmelding_notify%TYPE;
lbonotify mld_disc_params.mld_disc_params_bonotify%TYPE;
lworkflowstep_key mld_melding.mld_workflowstep_key%TYPE;
lstart_key mld_melding.mld_melding_start_key%TYPE;
luitvtype mld_v_uitvoerende.TYPE%TYPE;
lemail prs_bedrijf.prs_bedrijf_email%TYPE;
lphone prs_bedrijf.prs_bedrijf_telefoon2%TYPE;
lreskey res_rsv_ruimte.res_reservering_key%TYPE;
lres_ruimte_opstel_key res_rsv_ruimte.res_ruimte_opstel_key%TYPE;
lrefkey NUMBER (10);
lxrefkey res_rsv_ruimte.res_rsv_ruimte_key%TYPE;
lalg_ruimte_key res_rsv_ruimte.alg_ruimte_key%TYPE;
lalglocatiekey alg_locatie.alg_locatie_key%TYPE;
lmld_adres_key mld_adres.mld_adres_key%TYPE;
lprs_bedrijf_key prs_bedrijf.prs_bedrijf_key%TYPE;
lmldbehandelaar mld_melding.mld_melding_behandelaar_key%TYPE;
lafs_key bez_afspraak.bez_afspraak_key%TYPE;
BEGIN
-- Het gaat om een notificatie bij een entiteit prefkey,
-- waarvan het type alleen nog moet worden bepaald via
-- de srtnotificatie. Dan kan van het record van die
-- entiteit de ontvanger van de notificatie worden bepaald
-- (normaal de aanvrager) en wordt het bericht gequeueud.
-- De afzender is nu ook bekend (vroeger niet)
-- DIT VERVANGT (5I) ALLE NOTIFICATIETRIGGERS bij de verschillende
-- entiteiten (met uitzondering van opdrachtnotificatie naar buiten!?
IF psrtnotificatiekey IS NULL
THEN
RETURN;
END IF;
IF prefkey IS NULL
THEN
RETURN;
END IF;
lrefkey := prefkey; -- dan kunnen we bij reservering nog wijzigen
bericht := ptracking_oms; -- als die leeg is zoeken we zelf
-- welk type?
SELECT fac_srtnotificatie_xmlnode, fac_srtnotificatie_code,
lcl.x('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms)
INTO lxmlnode, lcode, loms
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_key = psrtnotificatiekey;
-- Bepaal de ontvanger enzo van dit bericht
CASE
WHEN lxmlnode = 'melding'
THEN
IF ptracking_oms IS NULL
THEN
bericht := mld.mldsprintf (loms, prefkey);
END IF;
-- basisgegevens, de ontvanger enzo
SELECT CASE WHEN fac.getsetting ('progress_notification_for') = 'true'
THEN m.prs_perslid_key_voor
ELSE m.prs_perslid_key
END receiver,
m.mld_stdmelding_key,
m.mld_adres_key,
m.mld_alg_locatie_key,
mld_disc_params_notify,
stdm.mld_stdmelding_notify,
d.ins_discipline_email,
mp.mld_disc_params_bonotify,
m.mld_melding_behandelaar_key,
m.mld_workflowstep_key,
m.mld_melding_start_key
INTO lreceiver,
lmld_stdmelding_key,
lmld_adres_key,
lalglocatiekey,
lnotify,
lmnotify,
lsender,
lbonotify,
lmldbehandelaar,
lworkflowstep_key,
lstart_key
FROM mld_melding m,
mld_stdmelding stdm,
ins_tab_discipline d,
mld_disc_params mp
WHERE stdm.mld_stdmelding_key = m.mld_stdmelding_key
AND d.ins_discipline_key = stdm.mld_ins_discipline_key
AND mp.mld_ins_discipline_key = d.ins_discipline_key
AND m.mld_melding_key = prefkey;
IF lbonotify = 1 AND lcode = 'MLDNEW' -- Alleen bij aanmaak van de melding.
THEN
mld.notifybackoffice (prefkey);
END IF;
-- We sturen soms TWEE notificaties, naar melder en nieuwe behandelaar
-- De normale notificatie gaat naar de melder
-- Moeten dus kijken of psrtnotificatiekey naar MLDBEH wijst
-- Dan moeten we ook MLDBE2 versturen naar de behandelaar, al was ik het zelf.
IF lcode = 'MLDBEH' AND lmldbehandelaar IS NOT NULL
THEN
lcode2 := 'MLDBE2';
lreceiver2 := lmldbehandelaar;
SELECT lcl.x('fac_srtnotificatie_oms', fac_srtnotificatie_key, fac_srtnotificatie_oms)
INTO loms2
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = lcode2;
bericht2 := mld.mldsprintf (loms2, prefkey);
END IF;
-- Meldingen worden eventueel niet genotificeerd naar de melder als
-- settings daartoe aanleiding geven. We weten genoeg om te checken of dat zo is
-- Maar een MLDNOT-notificatie moet altijd, ongeacht deze settings
IF lcode <> 'MLDNOT'
AND (lnotify = 0
OR (lnotify = 2 AND lmnotify = 0)
OR ( lworkflowstep_key IS NOT NULL
AND lstart_key <> prefkey
AND fac.getsetting ('mld_notify_workflowsteps') = 0)
)
THEN
-- No first notification: disc says no OR disc says: see stdmelding and stdmelding says no
-- OR this is part of a workflow and settings says not to notify workflowsteps
IF lcode2 IS NULL
THEN
-- Also no second notification
RETURN;
ELSE
-- Only a second notification, so that will be the first
lcode := lcode2;
lreceiver := lreceiver2;
bericht := bericht2;
lcode2 := NULL;
lreceiver2 := NULL;
bericht2 := NULL;
END IF;
END IF;
IF lsender IS NULL
THEN
-- (kennelijk) is de verantwoordelijke voor van het afleveradres iets sterker of zo
IF lmld_adres_key IS NOT NULL
THEN
SELECT l1.alg_locatie_email
INTO lsender
FROM mld_adres ma, alg_locatie l1
WHERE ma.mld_adres_key = lmld_adres_key
AND ma.alg_locatie_key = l1.alg_locatie_key(+);
END IF;
IF lsender IS NULL AND lalglocatiekey IS NOT NULL -- nog steeds onbekend
THEN
SELECT l2.alg_locatie_email
INTO lsender
FROM alg_locatie l2
WHERE l2.alg_locatie_key = lalglocatiekey;
END IF;
END IF;
WHEN lxmlnode = 'opdracht'
THEN
IF ptracking_oms IS NULL
THEN
bericht := mld.opdrsprintf (loms, prefkey);
END IF;
-- In 4i notificeerden we alleen toekenning aan de uitvoerder
-- In 5i tracken we veel meer, en is er dus ook de mogelijkheid
-- tot notificeren van tracking
-- Echter: wie houden we hiervan nou actief op de hoogte?
-- Dat wordt de interne contacpersoon van de opdracht
-- behalve ORDMLE/ORDMLI en ORDONO/ORDOOK, die naar de uitvoerder
IF lcode IN ('ORDMLI', 'ORDMLE', 'ORDONO', 'ORDOOK')
THEN
SELECT mld_uitvoerende_keys
INTO lreceiver
FROM mld_opdr
WHERE mld_opdr_key = prefkey;
SELECT u.TYPE
INTO luitvtype
FROM mld_v_uitvoerende u
WHERE u.mld_uitvoerende_key = lreceiver;
IF luitvtype = 'B'
THEN
-- Het gaat om een externe receiver
BEGIN
SELECT prs_bedrijf_email, prs_bedrijf_telefoon2
INTO lemail, lphone
FROM prs_bedrijf
WHERE prs_bedrijf_key = lreceiver;
-- Nooit op een portal voor externen
-- want dan zou iedereen die notificatie zien ivm lege receiver
-- dit overrulet dus iedere setting!
-- TODO smode := BITAND (smode, 255 - 1);
-- voorkom dat er een bericht wordt gestuurd
-- aan een perslid_key als deze bedrijf_key
lreceiver := NULL;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN;
END;
END IF;
ELSE
-- ons intern contactpersoon krijgt in alle andere gevallen het bericht
SELECT prs_perslid_key
INTO lreceiver
FROM mld_opdr
WHERE mld_opdr_key = prefkey;
END IF;
-- NOTE TO SELF:
-- Bij ORDMLI/ORDMLE en eigenlijk ook ORDGOE worden derden ingelicht,
-- bij ORDGOE tevens de opdrachtcontactpersoon, bij die andere twee niet
-- De mode (mail e.d.) van de notificatie bij dat event kan maar 1 waarde bevatten
-- Momenteel is dat
-- ORDMLI/ORDMLE: hoe ontvangt de uitvoerder dit bericht, contactpersoon krijgt niks
-- ORDGOE: hoe ontvangt de contactpersoon
-- ORD2GO: hoe ontvangt de uitvoerder dit bericht
-- Bij ORDGOE willen we *ook* de goedkeurder inlichten
IF lcode = 'ORDGOE'
THEN
mld.notifyopdrgoedkeurders (prefkey);
END IF;
-- de afzender
BEGIN
SELECT ins_discipline_email
INTO lsender
FROM ins_tab_discipline d,
mld_stdmelding sm,
mld_melding m,
mld_opdr o
WHERE d.ins_discipline_key = sm.mld_ins_discipline_key
AND sm.mld_stdmelding_key = m.mld_stdmelding_key
AND o.mld_melding_key = m.mld_melding_key
AND o.mld_opdr_key = prefkey;
IF lsender IS NULL
THEN
SELECT COALESCE (l1.alg_locatie_email, l2.alg_locatie_email)
INTO lsender
FROM mld_melding m,
mld_adres ma,
alg_locatie l1,
alg_locatie l2,
mld_opdr o
WHERE m.mld_adres_key = ma.mld_adres_key(+)
AND ma.alg_locatie_key = l1.alg_locatie_key(+)
AND m.mld_alg_locatie_key = l2.alg_locatie_key(+)
AND o.mld_melding_key = m.mld_melding_key
AND o.mld_opdr_key = prefkey;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
WHEN lxmlnode = 'reservering' OR lxmlnode = 'xreservering'
THEN
IF ptracking_oms IS NULL
THEN
bericht := res.sprintf (loms, prefkey);
END IF;
BEGIN
SELECT res_rsv_ruimte_contact_key,
res_ruimte_opstel_key,
alg_ruimte_key,
res_reservering_key
INTO lreceiver,
lres_ruimte_opstel_key,
lalg_ruimte_key,
lreskey
FROM res_rsv_ruimte
WHERE res_rsv_ruimte_key = prefkey AND (res_rsv_ruimte_dirtlevel = 0 OR lcode = 'RESDIR');
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN; -- Normaliter geen niet bestaande of dirty reserveringen notificeren
END;
-- de afzender, en moeten we wel?
lnotify := NULL;
BEGIN
-- Bepaal afzender, afhankelijk van catalogus (als res_ruimte) of anders de locatie
-- en check of er voor deze ruimtecatalogus uberhaupt moet worden genotificeerd
IF lres_ruimte_opstel_key IS NOT NULL
THEN
SELECT COALESCE (MAX (d.ins_discipline_email), MAX (l.alg_locatie_email)),
MAX (res_disc_params_notify)
INTO lsender, lnotify
FROM res_ruimte_opstelling ro,
res_ruimte rr,
res_alg_ruimte rag,
alg_ruimte r,
alg_verdieping v,
alg_gebouw g,
alg_locatie l,
ins_tab_discipline d,
res_disc_params rdp
WHERE l.alg_locatie_key = g.alg_locatie_key
AND g.alg_gebouw_key = v.alg_gebouw_key
AND r.alg_verdieping_key = v.alg_verdieping_key
AND r.alg_ruimte_key = rag.alg_ruimte_key
AND rag.res_ruimte_key = rr.res_ruimte_key
AND d.ins_discipline_key = rr.res_discipline_key
AND rr.res_discipline_key = rdp.res_ins_discipline_key
AND rr.res_ruimte_key = ro.res_ruimte_key
AND ro.res_ruimte_opstel_key = lres_ruimte_opstel_key;
ELSIF lalg_ruimte_key IS NOT NULL
THEN
-- Een voorzieningenreservering kan uit meerdere catalogi items hebben,
-- maar bij maar 1 afzender. Zwaarst geldt een cateringcatalogusafzender
SELECT MAX (d.ins_discipline_email)
INTO lsender
FROM ins_tab_discipline d, res_artikel a, res_rsv_artikel ra
WHERE d.ins_discipline_key = a.res_discipline_key
AND a.res_artikel_key = ra.res_artikel_key
AND ra.res_rsv_artikel_verwijder IS NULL
AND ra.res_rsv_ruimte_key = prefkey;
-- Als die er niet is, dan de voorzieningscatalogusafzender
IF lsender IS NULL
THEN
SELECT MAX (d.ins_discipline_email)
INTO lsender
FROM ins_tab_discipline d, res_deel r, res_rsv_deel rd
WHERE d.ins_discipline_key = r.res_discipline_key
AND r.res_deel_key = rd.res_deel_key
AND rd.res_rsv_deel_verwijder IS NULL
AND rd.res_rsv_ruimte_key = prefkey;
END IF;
-- Als die er niet is, dan de locatieafzender
IF lsender IS NULL
THEN
SELECT MAX (l.alg_locatie_email)
INTO lsender
FROM alg_ruimte r,
alg_verdieping v,
alg_gebouw g,
alg_locatie l
WHERE l.alg_locatie_key = g.alg_locatie_key
AND g.alg_gebouw_key = v.alg_gebouw_key
AND r.alg_verdieping_key = v.alg_verdieping_key
AND r.alg_ruimte_key = lalg_ruimte_key;
END IF;
ELSE
lsender := NULL;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
lsender := NULL;
END;
-- Reserveringen worden eventueel niet genotificeerd als settings daartoe aanleiding geven.
-- We weten genoeg om te checken of dat zo is
IF (lnotify = 0)
THEN
-- Nothing to do: disc says no
RETURN;
END IF;
lxrefkey := lrefkey; -- de deelreservering
lrefkey := lreskey; -- de hoofdreservering
WHEN lxmlnode = 'bestelling'
THEN
IF ptracking_oms IS NULL
THEN
bericht := bes.bessprintf (loms, prefkey, '');
END IF;
--
SELECT CASE WHEN fac.getsetting ('progress_notification_for') = 'true'
THEN prs_perslid_key_voor
ELSE prs_perslid_key
END receiver
, mld_adres_key_lev
INTO lreceiver
, lmld_adres_key
FROM bes_bestelling bb
WHERE bb.bes_bestelling_key = prefkey;
--
-- Bij BESACP willen we *ook* de goedkeurders inlichten
IF lcode = 'BESACP'
THEN
bes.notifybesgoedkeurders (prefkey);
END IF;
--
-- Bepaal de afzender
-- die komt van de (strikt: een) catalogus van de artikelen uit deze bestelling
-- of anders bepaald door de locatie van het afleveradres
BEGIN
-- Merk op dat tijdens insert nog niet bekend is welke items nog gaan worden toegevoegd
-- en dan is het dus niet mogelijk hier de catalogus te bepalen en te gebruiken
-- Tijdens update zou dat wel kunnen, maar de update wordt soms veroorzaakt door
-- een andere update, in het bijzonder makeorders(). Dat levert dan weer een
-- table is mutating error op. Dat betekent dus dat de notificatie eigenlijk dieper
-- moet worden gegenereerd, op bestelling-item. Dit valt nu buiten de scope van RWSN#14861
-- Met 5i kunnen we dit hier nu wel doen toch? Nee, ook niet!
-- SELECT MAX (ins_discipline_email)
-- INTO lsender
-- FROM ins_tab_discipline d, bes_bestelling_item bi, ins_srtdeel sd, ins_srtgroep sg
-- WHERE bi.ins_srtdeel_key = sd.ins_srtdeel_key
-- AND sd.ins_srtgroep_key = sg.ins_srtgroep_key
-- AND sg.ins_discipline_key = d.ins_discipline_key
-- AND bi.bes_bestelling_key = prefkey;
IF lsender IS NULL
THEN
SELECT l.alg_locatie_email
INTO lsender
FROM mld_adres ma, alg_locatie l
WHERE lmld_adres_key = ma.mld_adres_key(+)
AND ma.alg_locatie_key = l.alg_locatie_key(+);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
lsender := NULL;
END;
WHEN lxmlnode = 'bestelopdr'
THEN
IF ptracking_oms IS NULL
THEN
bericht := bes.opdrsprintf (loms, prefkey);
END IF;
-- Wie ontvangt deze? (besteller/leverancier)
lreceiver := NULL;
lnotify := NULL; -- de leverancier
IF lcode IN ('BES2SN', 'BES2SX')
THEN
-- Ontvanger = misschien de besteller (afh. van catalogus)
-- Mochten er (technisch) meerdere zijn, pak er maar eentje
BEGIN
SELECT b.prs_perslid_key,
b.prs_perslid_key_voor,
b.mld_adres_key_lev,
p.prs_perslid_email,
p.prs_perslid_telefoonnr,
bdp.bes_disc_params_noti_opdr
INTO lreceiver,
lreceiver2,
lmld_adres_key,
lemail,
lphone,
lnotify
FROM prs_perslid p,
bes_bestelling b,
bes_bestelling_item bi,
bes_bestelopdr_item boi,
bes_srtdeel sd,
bes_srtgroep sg,
bes_disc_params bdp
WHERE p.prs_perslid_key = b.prs_perslid_key
AND bi.bes_bestelling_key = b.bes_bestelling_key
AND sd.bes_srtdeel_key = bi.bes_srtdeel_key
AND sg.bes_srtgroep_key = sd.bes_srtgroep_key
AND bdp.bes_ins_discipline_key = sg.ins_discipline_key
AND boi.bes_bestelopdr_item_key = bi.bes_bestelopdr_item_key
AND boi.bes_bestelopdr_key = prefkey
AND ROWNUM = 1;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN;
END;
-- Geen dubbele sturen; ik zeg zelfs: de bestel_voor moet m.i. helemaal niet ingelicht worden?!
--IF (lreceiver2 = lreceiver)
--THEN
lreceiver2 := NULL;
--END IF;
END IF;
IF (lnotify != 1 OR lnotify IS NULL)
THEN
-- Ontvanger = leverancier, toch niet de besteller
lreceiver := NULL;
lreceiver2 := NULL;
SELECT prs_bedrijf_key
INTO lprs_bedrijf_key
FROM bes_bestelopdr
WHERE bes_bestelopdr_key = prefkey;
BEGIN
SELECT prs_bedrijf_email, prs_bedrijf_telefoon2
INTO lemail, lphone
FROM prs_bedrijf
WHERE prs_bedrijf_key = lprs_bedrijf_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN;
END;
END IF;
-- Afzender
BEGIN
SELECT MAX (ins_discipline_email)
INTO lsender
FROM ins_tab_discipline d,
bes_bestelling_item bi,
bes_srtdeel sd,
bes_srtgroep sg,
bes_bestelopdr_item boi
WHERE bi.bes_srtdeel_key = sd.bes_srtdeel_key
AND sd.bes_srtgroep_key = sg.bes_srtgroep_key
AND sg.ins_discipline_key = d.ins_discipline_key
AND boi.bes_bestelopdr_item_key = bi.bes_bestelopdr_item_key
AND boi.bes_bestelopdr_key = prefkey;
IF lsender IS NULL
THEN
SELECT l.alg_locatie_email
INTO lsender
FROM mld_adres ma, alg_locatie l
WHERE lmld_adres_key = ma.mld_adres_key(+)
AND ma.alg_locatie_key = l.alg_locatie_key(+);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
WHEN lxmlnode = 'afspraak' OR lxmlnode = 'bezoeker'
THEN
IF lxmlnode = 'afspraak'
THEN
IF ptracking_oms IS NULL
THEN
bericht := bez.afssprintf (loms, prefkey);
END IF;
lafs_key := prefkey;
ELSE -- lxmlnode = 'bezoeker'
IF ptracking_oms IS NULL
THEN
bericht := bez.bzksprintf (loms, prefkey);
END IF;
SELECT bez_afspraak_key
INTO lafs_key
FROM bez_bezoekers
WHERE bez_bezoekers_key = prefkey;
END IF;
-- We sturen bij bezoekers soms TWEE notificaties, naar contact en host
-- De normale notificatie gaat naar de contact (UWVA#19008)
-- Moeten dus kijken of psrtnotificatiekey naar BEZDON of BEZOUT wijst
-- Dan moeten we ook BEZDO2 of BEZOU2 versturen naar de host.
IF lcode = 'BEZDON'
THEN
lcode2 := 'BEZDO2';
ELSIF lcode = 'BEZOUT'
THEN
lcode2 := 'BEZOU2';
END IF;
IF lcode2 IS NOT NULL
THEN
SELECT lcl.x ('fac_srtnotificatie_oms',
fac_srtnotificatie_key,
fac_srtnotificatie_oms)
INTO loms2
FROM fac_srtnotificatie
WHERE fac_srtnotificatie_code = lcode2;
bericht2 := bez.bzksprintf (loms2, prefkey);
END IF;
SELECT bez_afspraak_contact_key, bez_afspraak_host_key, alg_locatie_key
INTO lreceiver, lreceiver2, lalglocatiekey
FROM bez_afspraak
WHERE bez_afspraak_key = lafs_key;
-- afzender
BEGIN
SELECT l.alg_locatie_email
INTO lsender
FROM alg_locatie l
WHERE l.alg_locatie_key = lalglocatiekey;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
lsender := NULL;
END;
WHEN lxmlnode = 'deel'
THEN
IF ptracking_oms IS NULL
THEN
bericht := ins.sprintf (loms, prefkey);
END IF;
-- Beheeracties notificeren we niet, zou niet weten naar wie.
IF lcode IN ('INSOUT', 'INSINN')
THEN
-- Bij uitlenen sturen we een notificatie naar de tijdelijke nieuwe eigenaar (UWVA#21528)
-- Bij innemen sturen we een notificatie naar de oorspronkelijke eigenaar (indien persoon; zeldzaam)
SELECT ins_alg_ruimte_key, ins_alg_locatie_key
INTO lreceiver, lalglocatiekey
FROM ins_deel
WHERE ins_alg_ruimte_type = 'P' AND ins_deel_key = prefkey;
-- Afzender
BEGIN
SELECT MAX (ins_discipline_email)
INTO lsender
FROM ins_tab_discipline d,
ins_deel dl,
ins_srtdeel sd,
ins_srtgroep sg
WHERE dl.ins_srtdeel_key = sd.ins_srtdeel_key
AND sd.ins_srtgroep_key = sg.ins_srtgroep_key
AND sg.ins_discipline_key = d.ins_discipline_key
AND dl.ins_deel_key = prefkey;
IF lsender IS NULL
THEN
SELECT l.alg_locatie_email
INTO lsender
FROM alg_locatie l
WHERE l.alg_locatie_key = lalglocatiekey;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
END IF;
WHEN lxmlnode = 'contract'
THEN
IF ptracking_oms IS NULL
THEN
bericht := cnt.sprintf (loms, prefkey);
END IF;
-- Ontvanger = contractbeheerder
SELECT prs_perslid_key_beh
INTO lreceiver
FROM cnt_contract
WHERE cnt_contract_key = prefkey;
-- Bepaal de afzender
-- Afzender is het email adres van de contractsoort (discipline)
-- Of wordt anders bepaald door de locatiescope van het contract
BEGIN
SELECT MAX (cd.ins_discipline_email)
INTO lsender
FROM cnt_contract c, cnt_discipline cd
WHERE c.ins_discipline_key = cd.ins_discipline_key
AND c.cnt_contract_key = prefkey;
IF lsender IS NULL
THEN
SELECT MAX(email)
INTO lsender
FROM (SELECT l.alg_locatie_email email
FROM cnt_contract_plaats,
alg_locatie l
WHERE cnt_alg_plaats_key = l.alg_locatie_key
AND cnt_alg_plaats_code = 'L'
AND cnt_contract_plaats_verwijder IS NULL
AND cnt_contract_key = prefkey
UNION
SELECT l.alg_locatie_email email
FROM cnt_contract_plaats,
alg_locatie l,
alg_gebouw g
WHERE cnt_alg_plaats_code = 'G'
AND cnt_alg_plaats_key = g.alg_gebouw_key
AND g.alg_locatie_key = l.alg_locatie_key
AND cnt_contract_plaats_verwijder IS NULL
AND cnt_contract_key = prefkey
UNION
SELECT l.alg_locatie_email email
FROM cnt_contract_plaats,
alg_locatie l,
alg_terreinsector t
WHERE cnt_alg_plaats_code = 'T'
AND cnt_alg_plaats_key = t.alg_terreinsector_key
AND t.alg_locatie_key = l.alg_locatie_key
AND cnt_contract_plaats_verwijder IS NULL
AND cnt_contract_key = prefkey);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
lsender := NULL;
END;
WHEN lxmlnode = 'message'
THEN
NULL; -- kan nog niet via tracking worden veroorzaakt (later: ontvangstbericht?)
ELSE
NULL; -- force error?
END CASE;
fac.putnotificationsrtprio (pperslid_key,
lreceiver,
lcode,
lrefkey,
bericht,
NULL,
lemail,
lphone,
lxrefkey,
2,
lsender);
IF lcode2 IS NOT NULL AND lreceiver2 IS NOT NULL
THEN
fac.putnotificationsrtprio (pperslid_key,
lreceiver2,
lcode2,
lrefkey,
bericht2,
NULL,
lemail,
lphone,
lxrefkey,
2,
lsender);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
-- Levert de (nieuwste) datum op van een getrackt event op key
-- bv de laatste wijzigingsdatum van melding 123 is gettrackingdate('MLDUPD', 123)
FUNCTION gettrackingdate (peventcode IN VARCHAR2, pkey IN number) RETURN date
AS
retdatum date := NULL;
BEGIN
IF peventcode IS NOT NULL AND pkey IS NOT NULL THEN
BEGIN
SELECT MAX(fac_tracking_datum)
INTO retdatum
FROM fac_tracking t, fac_srtnotificatie st
WHERE t.fac_srtnotificatie_key = st.fac_srtnotificatie_key
AND st.fac_srtnotificatie_code = peventcode
AND fac_tracking_refkey=pkey;
EXCEPTION
WHEN NO_DATA_FOUND
THEN NULL;
END;
END IF;
RETURN retdatum;
END;
-- Levert de (nieuwste) muteerder op van een getrackt event op key
-- bv de laatste wijziger van melding 123 is gettrackinguserkey('MLDUPD', 123)
FUNCTION gettrackinguserkey (peventcode IN VARCHAR2, pkey IN NUMBER)
RETURN NUMBER
AS
retkey fac_tracking.prs_perslid_key%TYPE := NULL;
BEGIN
BEGIN
SELECT prs_perslid_key
INTO retkey
FROM fac_tracking t, fac_srtnotificatie st
WHERE t.fac_srtnotificatie_key = st.fac_srtnotificatie_key
AND st.fac_srtnotificatie_code = peventcode
AND fac_tracking_refkey = pkey;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN TOO_MANY_ROWS
THEN
-- Veronderstel dat de tracking meestal uniek is, daarom slechts in
-- uitzonderingsgevallen de nieuwste bepalen
SELECT prs_perslid_key
INTO retkey
FROM fac_tracking t, fac_srtnotificatie st
WHERE t.fac_srtnotificatie_key = st.fac_srtnotificatie_key
AND st.fac_srtnotificatie_code = peventcode
AND fac_tracking_refkey = pkey
AND fac_tracking_key =
(SELECT MAX (fac_tracking_key)
FROM fac_tracking t, fac_srtnotificatie st
WHERE t.fac_srtnotificatie_key = st.fac_srtnotificatie_key
AND st.fac_srtnotificatie_code = peventcode
AND fac_tracking_refkey = pkey);
END;
RETURN retkey;
END;
PROCEDURE initsession (flcode IN VARCHAR2)
AS
setsql VARCHAR2(200);
BEGIN
-- Initialiseert deze Oracle session met de vereiste parameters
-- De flcode (FACILITOR Language code) mag null zijn, dan wordt de databasedefault gebruikt
lcl.setuserlanguage(flcode);
setsql := 'ALTER SESSION SET '
|| ' NLS_NUMERIC_CHARACTERS = ''.,'''
|| ' NLS_SORT = ''BINARY'''
|| ' NLS_TERRITORY=''AMERICA''';
EXECUTE IMMEDIATE setsql;
END;
PROCEDURE registerversion (pmaj IN NUMBER, pmin IN NUMBER, ppatch IN VARCHAR2, pschema IN VARCHAR2, plang IN VARCHAR2)
AS
verstring fac_module.fac_module_version%TYPE;
revisionnr fac_version.fac_version_schema%TYPE;
BEGIN
IF pmaj IS NOT NULL AND pmin IS NOT NULL AND ppatch IS NOT NULL
THEN
verstring := TO_CHAR (pmaj) || '.' || TO_CHAR (pmin) || '.' || TO_CHAR (ppatch);
UPDATE fac_module
SET fac_module_version = verstring;
UPDATE fac_version
SET fac_version_major = pmaj,
fac_version_minor = pmin,
fac_version_patch = ppatch,
fac_version_schema = pschema,
fac_version_date = SYSDATE;
UPDATE fac_message
SET fac_message_text = 'FACILITOR ' || verstring || 'DB' || TO_CHAR(pschema)
WHERE fac_message_code = 'FAC_M002';
END IF;
IF plang IS NOT NULL
THEN
UPDATE fac_version
SET fac_version_lang = plang;
END IF;
END;
PROCEDURE registercustversion (pcustid IN VARCHAR2, pcustnr IN NUMBER)
AS
BEGIN
IF pcustid IS NOT NULL AND pcustnr IS NOT NULL
THEN
UPDATE fac_version
SET fac_version_cust = pcustid,
fac_version_custnr = pcustnr,
fac_version_date = SYSDATE;
END IF;
END;
FUNCTION getdbversion RETURN VARCHAR2
AS
verstring VARCHAR2(100);
BEGIN
SELECT 'DB'||fac_version_schema||'/'||fac_version_cust||fac_version_custnr||'-'||COALESCE(fac_version_otap,'P*')
INTO verstring
FROM fac_version;
RETURN verstring;
END;
-- Status: proven concept
PROCEDURE processemail (pfrom IN VARCHAR2,
pto IN VARCHAR2,
psubject IN VARCHAR2,
pbody IN VARCHAR2,
pextra IN VARCHAR2
)
AS
sender prs_perslid.prs_perslid_key%TYPE;
kostenplaats prs_afdeling.prs_kostenplaats_key%TYPE;
newkey mld_melding.mld_melding_key%TYPE;
defaultstdmelding fac_setting.fac_setting_default%TYPE;
kkey mld_kenmerk.mld_kenmerk_key%TYPE;
errormsg fac_result.fac_result_waarde%TYPE;
BEGIN
-- Valideer de sender in pfrom: kennen we deze?
SELECT prs_perslid_key, d.prs_kostenplaats_key
INTO sender, kostenplaats
FROM prs_perslid p, prs_afdeling d
WHERE p.prs_afdeling_key = d.prs_afdeling_key
AND UPPER (prs_perslid_email) = UPPER (pfrom);
CASE
WHEN UPPER (pto) LIKE 'SERVICEDESK@%'
THEN
defaultstdmelding := fac.getsetting ('defaultstdmelding');
-- suggested extensions:
-- check for MLDUSE-write autorisations
-- parse the subject to find an appropriate stdmelding, if uniquely possible
-- append (as a note?) to an existing melding if #key is found in the subject
BEGIN
INSERT INTO mld_melding (mld_melding_module,
mld_meldbron_key,
mld_melding_datum,
mld_melding_omschrijving,
mld_melding_status,
mld_stdmelding_key,
prs_perslid_key,
prs_perslid_key_voor,
prs_kostenplaats_key,
mld_melding_spoed)
VALUES ('MLD',
4, -- email
SYSDATE,
SUBSTR (
psubject || CHR (13)
|| REPLACE (
pbody,
CHR (13) || CHR (10) || CHR (13) || CHR (10),
CHR (13) || CHR (10)),
1,
4000), -- verwijder onnodige witregels
NULL,
defaultstdmelding,
sender,
sender,
kostenplaats,
3)
RETURNING mld_melding_key
INTO newkey;
-- find the lowest volgnummer of the flexfield of type folder.
SELECT MIN (mld_kenmerk_key)
INTO kkey
FROM mld_kenmerk k,
mld_srtkenmerk sk,
mld_stdmelding std,
ins_tab_discipline d
WHERE mld_srtkenmerk_kenmerktype = 'M'
AND sk.mld_srtkenmerk_key = k.mld_srtkenmerk_key
AND std.mld_stdmelding_key = defaultstdmelding
AND std.mld_ins_discipline_key = d.ins_discipline_key
AND ( (k.mld_stdmelding_key = std.mld_stdmelding_key
AND k.mld_kenmerk_niveau = 'S')
OR (k.mld_stdmelding_key = d.ins_discipline_key
AND k.mld_kenmerk_niveau = 'D')
OR (k.mld_stdmelding_key = d.ins_srtdiscipline_key
AND k.mld_kenmerk_niveau = 'T'))
AND k.mld_kenmerk_verwijder IS NULL
AND NOT EXISTS
(SELECT mld_kenmerk_volgnummer
FROM mld_kenmerk k1,
mld_srtkenmerk sk1,
mld_stdmelding std1,
ins_tab_discipline d1
WHERE sk1.mld_srtkenmerk_kenmerktype = 'M'
AND sk1.mld_srtkenmerk_key =
k1.mld_srtkenmerk_key
AND std1.mld_stdmelding_key =
defaultstdmelding
AND std1.mld_ins_discipline_key =
d1.ins_discipline_key
AND ( (k1.mld_stdmelding_key =
std1.mld_stdmelding_key
AND k1.mld_kenmerk_niveau = 'S')
OR (k1.mld_stdmelding_key =
d1.ins_discipline_key
AND k1.mld_kenmerk_niveau = 'D')
OR (k1.mld_stdmelding_key =
d1.ins_srtdiscipline_key
AND k1.mld_kenmerk_niveau = 'T'))
AND k1.mld_kenmerk_verwijder IS NULL
AND k1.mld_kenmerk_volgnummer >
k.mld_kenmerk_volgnummer);
IF kkey IS NOT NULL
THEN
INSERT INTO fac_result (fac_result_sessionid,
fac_result_naam,
fac_result_waarde)
VALUES ('hMailServer',
'kenmerkpath',
'MLD\M' || to_char( TRUNC(newkey/1000), 'FM0000') || '___\M' || newkey || '\' || kkey || '\');
END IF;
mld.setmeldingstatus (newkey, 2, sender);
END;
ELSE
NULL;
END CASE;
IF errormsg IS NOT NULL
THEN
INSERT INTO fac_result (fac_result_sessionid,
fac_result_naam,
fac_result_waarde)
VALUES ('hMailServer', 'errormsg', errormsg);
END IF;
EXCEPTION
WHEN OTHERS
THEN
INSERT INTO fac_result (fac_result_sessionid,
fac_result_naam,
fac_result_waarde)
VALUES ('hMailServer',
'errormsg',
'Database fout - Neem contact op met uw systeembeheerder');
END;
-- Is de meegegeven datum een feestdag
FUNCTION isdatefeestdag(p_date IN DATE)
RETURN BOOLEAN
IS
inspdate DATE;
BEGIN
SELECT mvd.mld_vrije_dagen_datum
INTO inspdate
FROM mld_vrije_dagen mvd
WHERE mvd.mld_vrije_dagen_datum = TRUNC(p_date, 'DD');
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Datum is geen feestdag.
RETURN FALSE;
END;
-- Calculation of next cyclus date
-- Deze functie moet snel en efficient zijn.
FUNCTION calcnextcyclusdate(p_date IN DATE,
p_mode IN NUMBER,
p_eenheid IN NUMBER,
p_periode IN NUMBER,
p_bits IN NUMBER)
RETURN DATE
IS
fromdate DATE;
fromdow NUMBER;
fromdom NUMBER;
todaydow NUMBER;
inspdate DATE;
nextday NUMBER;
lastday DATE;
w_bits NUMBER;
m_bits NUMBER;
w_day_n NUMBER;
w_day_v VARCHAR2(10);
BEGIN
IF p_periode = 0
THEN
RETURN p_date;
END IF;
-- moment-modus of interval-modus?
IF p_mode = 0
THEN
-- momentmodus UIT TE WERKEN!
--fromdate := GREATEST (SYSDATE, p_date);
fromdate := p_date;
CASE p_eenheid
WHEN 0
THEN
BEGIN
-- uurlijks
inspdate := fromdate + p_periode / 24;
IF (BITAND(p_bits, 128) = 128) AND isdatefeestdag(inspdate)
THEN
-- Checkbox "Niet op feestdagen" is aangevinkt en de datum is een feestdag. De datum overslaan en bepaal de volgende inspectiedatum.
inspdate := calcnextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits);
END IF;
-- werking van cyclus_bits tbd
END;
WHEN 1
THEN
BEGIN
-- dagelijks, elke cperiode dagen
inspdate := fromdate + p_periode;
IF (BITAND(p_bits, 128) = 128) AND isdatefeestdag(inspdate)
THEN
-- Checkbox "Niet op feestdagen" is aangevinkt en de datum is een feestdag. De datum overslaan en bepaal de volgende inspectiedatum.
inspdate := calcnextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits);
END IF;
-- cyclus_bits heeft geen effect
END;
WHEN 2
THEN
BEGIN
-- wekelijks
-- werking van cyclus_bits
-- bits voor elke dag (als in: tweewekelijks elke dinsdag en donderdag = 4+16=20)
-- 0 = geen dag (gewoon 7 dagen verder)
-- 1 = zondags (2^0): 1 dow
-- 2 = maandags (2^1): 2 dow
-- 4 = dinsdags (2^2): 3 dow
-- 8 == woensdag (2^3): 4 dow
-- 16 = donderdags (2^4): 5 dow
-- 32 = vrijdags (2^5): 6 dow
-- 64 = zaterdags (2^6): 7 dow
-- Is er deze week nog een inspectiedag?
-- Ja: De volgende bits dag.
-- Nee: Als bits is 0: exact x (eenheid) weken verder.
-- Als bits > 0: x (eenheid) weken verder de eerste bits dag.
fromdow := fac.getweekdaynum (fromdate);
IF p_bits IS NULL OR p_bits = 0
THEN
-- Dan maar een waarde kiezen. We kiezen vandaag.
todaydow := fac.getweekdaynum (SYSDATE);
w_bits := POWER(2, fromdow - 1) ;
ELSIF p_bits >= 128
THEN
w_bits := BITAND(p_bits, 127);
ELSE
w_bits := p_bits;
END IF;
IF w_bits IS NOT NULL AND w_bits >= POWER(2, fromdow) -- Bijvoorbeeld donderdag(5): p_bits >= 2^5(32). (32 is vrijdags)
THEN
-- Er is deze week nog een inspectiedag.
-- Bepaal de volgende bits dag deze week.
FOR i IN fromdow..6 LOOP
nextday := i;
EXIT WHEN BITAND(w_bits, POWER(2, i)) = POWER(2, i);
END LOOP;
inspdate := fromdate - fromdow + 1 + nextday;
ELSE
-- Er is deze week geen inspectiedag meer.
-- Eerste bits dag x (eenheid) weken verder.
IF w_bits IS NULL OR w_bits = 0
THEN
-- Exact eenheid weken verder.
inspdate := fromdate + p_periode * 7;
ELSE
-- Bepaal de eerste bits dag x (eenheid) weken verder.
inspdate := fromdate + p_periode * 7 + 1 - fromdow; -- zondag
FOR i IN 0..6 LOOP
nextday := i;
EXIT WHEN BITAND(w_bits, POWER(2, i)) = POWER(2, i);
END LOOP;
inspdate := inspdate + nextday;
END IF;
END IF;
IF (BITAND(p_bits, 128) = 128) AND isdatefeestdag(inspdate)
THEN
-- Checkbox "Niet op feestdagen" is aangevinkt en de datum is een feestdag. De datum overslaan en bepaal de volgende inspectiedatum.
inspdate := calcnextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits);
END IF;
END;
WHEN 3
THEN
BEGIN
-- Maandelijks
-- werking van cyclus_bits
-- bits 1 t/m 8 gebruiken we op dezelfde wijze als bij eenheid week
-- bits voor elke dag (als in: tweemaandelijks elke dinsdag en donderdag = 4+16=20)
-- 0 = geen dag (gewoon 7 dagen verder)
-- 1 = zondags (2^0): 1 dow (day of week/dag van de week)
-- 2 = maandags (2^1): 2 dow
-- 4 = dinsdags (2^2): 3 dow
-- 8 == woensdag (2^3): 4 dow
-- 16 = donderdags (2^4): 5 dow
-- 32 = vrijdags (2^5): 6 dow
-- 64 = zaterdags (2^6): 7 dow
-- 128 = niet op een feestdag
-- bits 9 t/m 11 geven de dag van de maand aan
-- 1 = eerste xxxdag van de maand (2^9 = 256)
-- 2 = tweede xxxdag van de maand (2^10 = 512)
-- 3 = derde xxxdag van de maand (2^9 + 2^10 = 256 + 512 = 768)
-- 4 = vierde xxxdag van de maand (2^11 = 1024)
-- 5 = NOT IN USE
-- 6 = <20><>n na laatste xxxdag van de maand (2^10 + 2^11 = 512 + 1024 = 1536)
-- 7 = laatste dag van de maand (2^9 + 2^10 + 2^11 = 256 + 512 + 1024 = 1792)
fromdow := fac.getweekdaynum (fromdate);
-- Alleen de gezette bits van de dagen van de week.
w_bits := BITAND(p_bits, 127);
-- Alleen de gezette bits van de y-ste xxxdag van de maand.
m_bits := BITAND(p_bits, 256 + 512 + 1024) / 256;
-- NEXT_DAY verwacht als tweede parameter de dagnaam als string. De dag van de week (nummer) werkt niet in een package.
-- Bepaal de taalonafhankelijke weekdag die je zoekt, zodat je NEXT_DAY kunt gaan gebruiken.
CASE
WHEN BITAND(w_bits, 1) = 1
THEN w_day_n := 1; -- 'ZONDAG' / 'SUNDAY';
WHEN BITAND(w_bits, 2) = 2
THEN w_day_n := 2; -- 'MAANDAG' / 'MONDAY';
WHEN BITAND(w_bits, 4) = 4
THEN w_day_n := 3; -- 'DINSDAG' / 'TUESDAY';
WHEN BITAND(w_bits, 8) = 8
THEN w_day_n := 4; -- 'WOENSDAG' / 'WEDNESDAY';
WHEN BITAND(w_bits, 16) = 16
THEN w_day_n := 5; -- 'DONDERDAG' / 'THURSDAY';
WHEN BITAND(w_bits, 32) = 32
THEN w_day_n := 6; -- 'VRIJDAG' / 'FRIDAY';
WHEN BITAND(w_bits, 64) = 64
THEN w_day_n := 7; -- 'ZATERDAG' / 'SATURDAY';
END CASE;
-- Tweede parameter van NEXT_DAY is de dag naam in de ingestelde taal
-- En we willen niet taal afhankelijk zijn. Dus de naam onafhankelijk bepalen
-- 01-06-2014 is een ZONDAG
w_day_v := TO_CHAR(TO_DATE('01-06-2014', 'DD-MM-YYYY') + w_day_n - 1, 'DAY'); -- Levert de naam van de weekdag op, taalonafhankelijk (ZONDAG.....ZATERDAG).
-- Is er deze maand nog een inspectiedag?
-- Eerst de eerste inspectiedag bepalen
IF w_bits IS NULL OR w_bits = 0
THEN
-- Exact eenheid maanden verder.
inspdate := ADD_MONTHS (fromdate, p_periode);
ELSIF m_bits > 4
THEN
CASE
WHEN m_bits = 6 OR m_bits = 7
THEN
-- <20><>n na laatste (6) of laatste (7) xxxdag van de maand bepalen
-- Bepaal de eerste bits dag van de volgende maand de y-ste xxxdag van de maand.
-- en neem dan de datum van twee weken of <20><>n week daarvoor.
inspdate := NEXT_DAY (TRUNC(ADD_MONTHS (fromdate, 1), 'MONTH') - 1, w_day_v) - ((8 - m_bits) * 7); -- m_bits 6 resp. 7 dan 2 resp. 1 week/weken terug.
-- Als inspectie datum niet in de toekomst ligt dan de eerste inspectie datum bepalen in de volgende periode maanden verder.
IF (inspdate <= fromdate)
THEN
inspdate := NEXT_DAY (TRUNC(ADD_MONTHS (inspdate, p_periode + 1), 'MONTH') - 1, w_day_v) - ((8 - m_bits) * 7); -- m_bits 6 resp. 7 dan 2 resp. 1 week/weken terug.
ELSIF p_periode > 1 -- (inspdate > fromdate) geldt automatisch.
THEN
inspdate := NEXT_DAY (TRUNC(ADD_MONTHS (inspdate, p_periode), 'MONTH') - 1, w_day_v) - ((8 - m_bits) * 7); -- m_bits 6 resp. 7 dan 2 resp. 1 week/weken terug.
END IF;
ELSE
-- Niet ondersteunende instelling.
-- Exact eenheid maanden verder.
inspdate := ADD_MONTHS (fromdate, p_periode);
END CASE;
ELSE -- 0 < m_bits <= 4
-- Eerste bits dag.
-- Bepaal de eerste bits dag deze maand de y-ste xxxdag van de maand.
inspdate := NEXT_DAY (TRUNC(fromdate, 'MONTH') - 1 + ((m_bits - 1) * 7), w_day_v);
-- Als de inspdate later is dan de meegegeven datum dan zijn we klaar.
-- Als de inspdate vandaag of in het verleden ligt dan
-- kijken we niet of er nog andere inspectiedatums in dezelfde week zijn die wel in de toekomst liggen (BEPERKING / VERSIMPELING in eerste instantie)
-- Daarom zorgen dat er in de invoer maar 1 dag in de week gekozen kan worden.
-- Als inspectie datum niet in de toekomst ligt dan de eerste inspectie datum bepalen in de volgende periode maanden verder.
IF (inspdate <= fromdate)
THEN
inspdate := NEXT_DAY (TRUNC(ADD_MONTHS (inspdate, p_periode), 'MONTH') - 1 + ((m_bits - 1) * 7), w_day_v);
ELSIF p_periode > 1 -- (inspdate > fromdate) geldt automatisch.
THEN
inspdate := NEXT_DAY (TRUNC(ADD_MONTHS (inspdate, p_periode - 1), 'MONTH') - 1 + ((m_bits - 1) * 7), w_day_v);
END IF;
END IF;
IF (BITAND(p_bits, 128) = 128) AND isdatefeestdag(inspdate)
THEN
-- Checkbox "Niet op feestdagen" is aangevinkt en de datum is een feestdag. De datum overslaan en bepaal de volgende inspectiedatum.
inspdate := calcnextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits);
END IF;
END;
WHEN 4
THEN
BEGIN
-- jaarlijks
inspdate := ADD_MONTHS (fromdate, p_periode * 12);
IF p_bits > 0
THEN
lastday := LAST_DAY(ADD_MONTHS (TRUNC(inspdate, 'YEAR'), 11));
inspdate := ADD_MONTHS (TRUNC(inspdate, 'YEAR'), p_bits - 1);
IF inspdate > lastday -- was p_bits groter dan het aantal maanden in het jaar? Dan de laatste dag van de laatste maand van het jaar nemen.
THEN
inspdate := lastday;
ELSE
fromdom := fromdate - TRUNC(fromdate, 'MONTH');
inspdate := inspdate + fromdom;
END IF;
END IF;
-- werking van cyclus_bits tbd
END;
END CASE;
ELSE
-- intervalmodus, p_bits doet er niet toe
fromdate := p_date;
CASE p_eenheid
WHEN 0
THEN
BEGIN
-- uurlijks
inspdate := fromdate + p_periode / 24;
END;
WHEN 1
THEN
BEGIN
-- dagelijks, elke cperiode dagen
inspdate := fromdate + p_periode;
END;
WHEN 2
THEN
BEGIN
-- wekelijks
inspdate := fromdate + p_periode * 7;
END;
WHEN 3
THEN
BEGIN
-- maandelijks
inspdate := ADD_MONTHS (fromdate, p_periode);
END;
WHEN 4
THEN
BEGIN
-- jaarlijks
inspdate := fromdate + p_periode * 365;
END;
END CASE;
END IF;
-- Stukje veiligheid inbouwen die een oneindige loop (of recursie) van de datumberekening voorkomt zodat de Oracle Server niet gaat hangen.
-- Berekende datum moet later zijn als de meegegeven datum.
IF p_date >= inspdate AND p_periode <> 0
THEN
raise_application_error (-20001, 'FACILITOR: Invalid inspection date calculated! Check interval parameters');
END IF;
RETURN inspdate;
END;
-- Berekent de n-de (p_steps) controledatum na p_date.
-- Indien p_steps niet is meegegeven dan wordt de eerstvolgende controledatum na nu teruggegeven.
-- steps = 0, (NULL): 1-ste vandaag of in de toekomst (als meegegeven datum (p_date) de huidite datum is, dan deze weer teruggeven).
-- steps = n: n-volgende vanaf meegegeven datum (p_date). Als deze berekende datum in de toekomst ligt en steps is nog niet null, dan wordt NULL teruggegeven).
FUNCTION nextcyclusdate (p_date IN DATE,
p_mode IN NUMBER,
p_eenheid IN NUMBER,
p_periode IN NUMBER,
p_bits IN NUMBER,
p_steps IN NUMBER DEFAULT 0)
RETURN DATE
IS
inspdate DATE;
inspdate_trunc DATE;
vandaagdate DATE;
toekomst BOOLEAN;
nuoftoekomst BOOLEAN;
BEGIN
inspdate := p_date;
IF p_eenheid IS NULL
THEN
RETURN NULL;
ELSIF p_eenheid = 0
THEN
inspdate_trunc := TRUNC(p_date, 'HH24');
vandaagdate := TRUNC(SYSDATE, 'HH24');
ELSE
inspdate_trunc := TRUNC(p_date, 'DDD');
vandaagdate := TRUNC(SYSDATE, 'DDD');
END IF;
toekomst := inspdate_trunc > vandaagdate;
-- De volgende inspectiedatum berekenen.
-- Maar let op, er kan een datum in de toekomst meegegeven zijn. Dan deze ook weer opleveren en niet de volgende berekenen.
-- Bij het meegegeven van de huidige datum en steps is 0 de huidige controledatum weer teruggeven.
IF NOT (p_steps = 0 AND toekomst) -- p_steps != 0 || !toekomst
THEN
-- Calulate next cyclus date m.b.v. voledige datum met tijd.
inspdate := calcnextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits);
END IF;
-- Nu insdate_trunc van de next cyclus date weer bepalen
IF p_eenheid = 0
THEN
inspdate_trunc := TRUNC(inspdate, 'HH24');
ELSE
inspdate_trunc := TRUNC(inspdate, 'DDD');
END IF;
nuoftoekomst := inspdate_trunc >= vandaagdate;
IF p_steps = 0
THEN
IF nuoftoekomst
THEN
RETURN inspdate;
ELSE
RETURN nextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits, 0); -- voledige datum met tijd gebruiken
END IF;
ELSIF p_steps > 1 AND nuoftoekomst
THEN
RETURN NULL;
ELSIF p_steps = 1 OR nuoftoekomst
THEN
RETURN inspdate;
ELSE
RETURN nextcyclusdate (inspdate, p_mode, p_eenheid, p_periode, p_bits, p_steps - 1); -- voledige datum met tijd gebruiken
END IF;
END;
-- Berekent de n-de (p_steps) controledatum na p_date.
-- Indien p_steps niet is meegegeven dan wordt de eerstvolgende controledatum na nu teruggegeven.
-- steps = 0, (NULL): 1-ste vandaag of in de toekomst (als meegegeven datum (p_date) de huidite datum is, dan deze weer teruggeven).
-- steps = n: n-volgende vanaf meegegeven datum (p_date). Als deze berekende datum in de toekomst ligt en steps is nog niet null, dan wordt NULL teruggegeven).
FUNCTION nextcyclusdate (p_insdeel IN NUMBER,
p_srtcontrole IN NUMBER,
p_steps IN NUMBER DEFAULT 0)
RETURN DATE
IS
inspdate DATE;
BEGIN
SELECT inspectie_next
INTO inspdate
FROM (WITH defined_inspect AS (SELECT isc.ins_srtcontrole_key,
isc.ins_srtcontrole_mode,
isc.ins_srtcontrole_eenheid,
isc.ins_srtcontrole_bits,
isc.ins_srtcontrole_periode,
id.ins_deel_key,
id.ins_deel_aanmaak
FROM ins_deel id,
ins_srtdeel s,
ins_srtcontrole isc
WHERE s.ins_srtdeel_key = id.ins_srtdeel_key
AND (isc.ins_srtcontrole_niveau = 'S'
AND isc.ins_srtinstallatie_key = id.ins_srtdeel_key
OR isc.ins_srtcontrole_niveau = 'G'
AND isc.ins_srtinstallatie_key = s.ins_srtgroep_key
OR isc.ins_srtcontrole_niveau = 'D'
AND isc.ins_srtinstallatie_key = id.ins_discipline_key)
AND id.ins_deel_key = p_insdeel)
SELECT fac.nextcyclusdate (COALESCE ( (SELECT MAX ( GREATEST (COALESCE (idsc.ins_deelsrtcontrole_datum_xcp,
CASE di.ins_srtcontrole_mode
WHEN 0
THEN idsc.ins_deelsrtcontrole_datum_org
ELSE idsc.ins_deelsrtcontrole_datum END),
CASE di.ins_srtcontrole_mode
WHEN 0
THEN idsc.ins_deelsrtcontrole_datum_org
ELSE idsc.ins_deelsrtcontrole_datum
END)
) ins_deelsrtcontrole_datum
FROM ins_deelsrtcontrole idsc
WHERE idsc.ins_srtcontrole_key = di.ins_srtcontrole_key
AND idsc.ins_deel_key = di.ins_deel_key),
di.ins_deel_aanmaak),
di.ins_srtcontrole_mode,
COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, di.ins_srtcontrole_eenheid),
COALESCE(xcp.ins_srtcontroledl_xcp_periode, di.ins_srtcontrole_periode),
COALESCE(xcp.ins_srtcontroledl_xcp_bits, di.ins_srtcontrole_bits),
p_steps
) inspectie_next
FROM defined_inspect di,
ins_srtcontroledl_xcp xcp
WHERE di.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)
AND di.ins_deel_key = xcp.ins_deel_key(+)
AND di.ins_deel_key = p_insdeel
AND di.ins_srtcontrole_key = p_srtcontrole);
RETURN inspdate;
END;
-- Bereken hoeveel controlestappen het is naar de eerste controle datum in de toekomst (standaard) of na de meegegeven datum.
FUNCTION nextcyclusdatesteps (p_date IN DATE,
p_mode IN NUMBER,
p_eenheid IN NUMBER,
p_periode IN NUMBER,
p_bits IN NUMBER,
p_steps IN NUMBER DEFAULT 1, -- Standaard beginnen te tellen bij 1.
p_enddate IN DATE DEFAULT SYSDATE)
RETURN NUMBER
IS
fromdate DATE;
fromdow NUMBER;
fromdom NUMBER;
inspdate DATE;
enddate DATE;
BEGIN
-- Calulate next cyclus date
inspdate := calcnextcyclusdate (p_date, p_mode, p_eenheid, p_periode, p_bits);
IF ((p_eenheid = 0 AND TRUNC(inspdate, 'HH24') >= TRUNC(p_enddate, 'HH24')) OR
(p_eenheid > 0 AND TRUNC(inspdate, 'DDD') >= TRUNC(p_enddate, 'DDD')))
THEN
RETURN p_steps;
ELSE
RETURN nextcyclusdatesteps (inspdate, p_mode, p_eenheid, p_periode, p_bits, p_steps + 1, p_enddate);
END IF;
END;
FUNCTION nextcyclusdatesteps (p_insdeel IN NUMBER,
p_srtcontrole IN NUMBER,
p_steps IN NUMBER DEFAULT 1) -- Standaard beginnen te tellen bij 1.
RETURN NUMBER
IS
lsteps NUMBER;
BEGIN
SELECT inspectie_steps
INTO lsteps
FROM (WITH defined_inspect AS (SELECT isc.ins_srtcontrole_key,
isc.ins_srtcontrole_mode,
isc.ins_srtcontrole_eenheid,
isc.ins_srtcontrole_bits,
isc.ins_srtcontrole_periode,
id.ins_deel_key,
id.ins_deel_aanmaak
FROM ins_deel id,
ins_srtdeel s,
ins_srtcontrole isc
WHERE s.ins_srtdeel_key = id.ins_srtdeel_key
AND (isc.ins_srtcontrole_niveau = 'S'
AND isc.ins_srtinstallatie_key = id.ins_srtdeel_key
OR isc.ins_srtcontrole_niveau = 'G'
AND isc.ins_srtinstallatie_key = s.ins_srtgroep_key
OR isc.ins_srtcontrole_niveau = 'D'
AND isc.ins_srtinstallatie_key = id.ins_discipline_key)
AND id.ins_deel_key = p_insdeel)
SELECT fac.nextcyclusdatesteps (COALESCE ( (SELECT MAX (COALESCE(idsc.ins_deelsrtcontrole_datum_xcp, idsc.ins_deelsrtcontrole_datum_org)) ins_deelsrtcontrole_datum
FROM ins_deelsrtcontrole idsc
WHERE di.ins_srtcontrole_key = idsc.ins_srtcontrole_key
AND idsc.ins_deel_key = di.ins_deel_key),
ins_deel_aanmaak),
di.ins_srtcontrole_mode,
COALESCE(xcp.ins_srtcontroledl_xcp_eenheid, di.ins_srtcontrole_eenheid),
COALESCE(xcp.ins_srtcontroledl_xcp_periode, di.ins_srtcontrole_periode),
COALESCE(xcp.ins_srtcontroledl_xcp_bits, di.ins_srtcontrole_bits),
p_steps
) inspectie_steps
FROM defined_inspect di,
ins_srtcontroledl_xcp xcp
WHERE di.ins_srtcontrole_key = xcp.ins_srtcontrole_key(+)
AND di.ins_deel_key = xcp.ins_deel_key(+)
AND di.ins_deel_key = p_insdeel
AND di.ins_srtcontrole_key = p_srtcontrole);
RETURN lsteps;
END;
-- We garanderen maximaal 64 characters
-- We ondersteunen alleen nog maar 'MD5'
FUNCTION makehash (p_in VARCHAR2, method IN VARCHAR2 DEFAULT 'MD5')
RETURN VARCHAR2
IS
l_hash VARCHAR2 (2000);
BEGIN
l_hash := RAWTOHEX(UTL_RAW.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5 (input_string=> p_in)));
RETURN l_hash;
END;
FUNCTION testhash (p_hash VARCHAR2, p_in VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF p_hash = makehash(p_in, 'MD5')
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
END fac;
/
REGISTERRUN('$Id$')